int vfio_config_init()

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);
}