in pci/vfio_pci_config.c [1672:1774]
int vfio_config_init(struct vfio_pci_core_device *vdev)
{
struct pci_dev *pdev = vdev->pdev;
u8 *map, *vconfig;
int ret;
/*
* Config space, caps and ecaps are all dword aligned, so we could
* use one byte per dword to record the type. However, there are
* no requiremenst on the length of a capability, so the gap between
* capabilities needs byte granularity.
*/
map = kmalloc(pdev->cfg_size, GFP_KERNEL);
if (!map)
return -ENOMEM;
vconfig = kmalloc(pdev->cfg_size, GFP_KERNEL);
if (!vconfig) {
kfree(map);
return -ENOMEM;
}
vdev->pci_config_map = map;
vdev->vconfig = vconfig;
memset(map, PCI_CAP_ID_BASIC, PCI_STD_HEADER_SIZEOF);
memset(map + PCI_STD_HEADER_SIZEOF, PCI_CAP_ID_INVALID,
pdev->cfg_size - PCI_STD_HEADER_SIZEOF);
ret = vfio_fill_vconfig_bytes(vdev, 0, PCI_STD_HEADER_SIZEOF);
if (ret)
goto out;
vdev->bardirty = true;
/*
* XXX can we just pci_load_saved_state/pci_restore_state?
* may need to rebuild vconfig after that
*/
/* For restore after reset */
vdev->rbar[0] = le32_to_cpu(*(__le32 *)&vconfig[PCI_BASE_ADDRESS_0]);
vdev->rbar[1] = le32_to_cpu(*(__le32 *)&vconfig[PCI_BASE_ADDRESS_1]);
vdev->rbar[2] = le32_to_cpu(*(__le32 *)&vconfig[PCI_BASE_ADDRESS_2]);
vdev->rbar[3] = le32_to_cpu(*(__le32 *)&vconfig[PCI_BASE_ADDRESS_3]);
vdev->rbar[4] = le32_to_cpu(*(__le32 *)&vconfig[PCI_BASE_ADDRESS_4]);
vdev->rbar[5] = le32_to_cpu(*(__le32 *)&vconfig[PCI_BASE_ADDRESS_5]);
vdev->rbar[6] = le32_to_cpu(*(__le32 *)&vconfig[PCI_ROM_ADDRESS]);
if (pdev->is_virtfn) {
*(__le16 *)&vconfig[PCI_VENDOR_ID] = cpu_to_le16(pdev->vendor);
*(__le16 *)&vconfig[PCI_DEVICE_ID] = cpu_to_le16(pdev->device);
/*
* Per SR-IOV spec rev 1.1, 3.4.1.18 the interrupt pin register
* does not apply to VFs and VFs must implement this register
* as read-only with value zero. Userspace is not readily able
* to identify whether a device is a VF and thus that the pin
* definition on the device is bogus should it violate this
* requirement. We already virtualize the pin register for
* other purposes, so we simply need to replace the bogus value
* and consider VFs when we determine INTx IRQ count.
*/
if (vconfig[PCI_INTERRUPT_PIN] &&
!pci_match_id(known_bogus_vf_intx_pin, pdev))
pci_warn(pdev,
"Hardware bug: VF reports bogus INTx pin %d\n",
vconfig[PCI_INTERRUPT_PIN]);
vconfig[PCI_INTERRUPT_PIN] = 0; /* Gratuitous for good VFs */
}
if (pdev->no_command_memory) {
/*
* VFs and devices that set pdev->no_command_memory do not
* implement the memory enable bit of the COMMAND register
* therefore we'll not have it set in our initial copy of
* config space after pci_enable_device(). For consistency
* with PFs, set the virtual enable bit here.
*/
*(__le16 *)&vconfig[PCI_COMMAND] |=
cpu_to_le16(PCI_COMMAND_MEMORY);
}
if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx)
vconfig[PCI_INTERRUPT_PIN] = 0;
ret = vfio_cap_init(vdev);
if (ret)
goto out;
ret = vfio_ecap_init(vdev);
if (ret)
goto out;
return 0;
out:
kfree(map);
vdev->pci_config_map = NULL;
kfree(vconfig);
vdev->vconfig = NULL;
return pcibios_err_to_errno(ret);
}