mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 08:43:55 -06:00
pcie_sriov: Make a PCI device with user-created VF ARI-capable
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> Message-Id: <20250314-sriov-v9-9-57dae8ae3ab5@daynix.com> Tested-by: Yui Washizu <yui.washidu@gmail.com> Tested-by: Pasha Tatashin <pasha.tatashin@soleen.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
6f9bebf1dc
commit
d0c280d3fa
4 changed files with 24 additions and 10 deletions
|
@ -28,7 +28,8 @@ virtio-net-pci functions to a bus. Below is a command line example:
|
||||||
The VFs specify the paired PF with ``sriov-pf`` property. The PF must be
|
The VFs specify the paired PF with ``sriov-pf`` property. The PF must be
|
||||||
added after all VFs. It is the user's responsibility to ensure that VFs have
|
added after all VFs. It is the user's responsibility to ensure that VFs have
|
||||||
function numbers larger than one of the PF, and that the function numbers
|
function numbers larger than one of the PF, and that the function numbers
|
||||||
have a consistent stride.
|
have a consistent stride. Both the PF and VFs are ARI-capable so you can have
|
||||||
|
255 VFs at maximum.
|
||||||
|
|
||||||
You may also need to perform additional steps to activate the SR-IOV feature on
|
You may also need to perform additional steps to activate the SR-IOV feature on
|
||||||
your guest. For Linux, refer to [1]_.
|
your guest. For Linux, refer to [1]_.
|
||||||
|
|
|
@ -245,6 +245,7 @@ int16_t pcie_sriov_pf_init_from_user_created_vfs(PCIDevice *dev,
|
||||||
PCIDevice **vfs;
|
PCIDevice **vfs;
|
||||||
BusState *bus = qdev_get_parent_bus(DEVICE(dev));
|
BusState *bus = qdev_get_parent_bus(DEVICE(dev));
|
||||||
uint16_t ven_id = pci_get_word(dev->config + PCI_VENDOR_ID);
|
uint16_t ven_id = pci_get_word(dev->config + PCI_VENDOR_ID);
|
||||||
|
uint16_t size = PCI_EXT_CAP_SRIOV_SIZEOF;
|
||||||
uint16_t vf_dev_id;
|
uint16_t vf_dev_id;
|
||||||
uint16_t vf_offset;
|
uint16_t vf_offset;
|
||||||
uint16_t vf_stride;
|
uint16_t vf_stride;
|
||||||
|
@ -311,6 +312,11 @@ int16_t pcie_sriov_pf_init_from_user_created_vfs(PCIDevice *dev,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pcie_find_capability(dev, PCI_EXT_CAP_ID_ARI)) {
|
||||||
|
pcie_ari_init(dev, offset + size);
|
||||||
|
size += PCI_ARI_SIZEOF;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < pf->len; i++) {
|
for (i = 0; i < pf->len; i++) {
|
||||||
vfs[i]->exp.sriov_vf.pf = dev;
|
vfs[i]->exp.sriov_vf.pf = dev;
|
||||||
vfs[i]->exp.sriov_vf.vf_number = i;
|
vfs[i]->exp.sriov_vf.vf_number = i;
|
||||||
|
@ -331,7 +337,7 @@ int16_t pcie_sriov_pf_init_from_user_created_vfs(PCIDevice *dev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PCI_EXT_CAP_SRIOV_SIZEOF;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pcie_sriov_register_device(PCIDevice *dev, Error **errp)
|
bool pcie_sriov_register_device(PCIDevice *dev, Error **errp)
|
||||||
|
|
|
@ -2111,12 +2111,16 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
|
||||||
PCI_BASE_ADDRESS_SPACE_IO, &proxy->bar);
|
PCI_BASE_ADDRESS_SPACE_IO, &proxy->bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = pcie_sriov_pf_init_from_user_created_vfs(&proxy->pci_dev,
|
if (pci_is_vf(&proxy->pci_dev)) {
|
||||||
proxy->last_pcie_cap_offset,
|
pcie_ari_init(&proxy->pci_dev, proxy->last_pcie_cap_offset);
|
||||||
errp);
|
proxy->last_pcie_cap_offset += PCI_ARI_SIZEOF;
|
||||||
if (res > 0) {
|
} else {
|
||||||
proxy->last_pcie_cap_offset += res;
|
res = pcie_sriov_pf_init_from_user_created_vfs(
|
||||||
virtio_add_feature(&vdev->host_features, VIRTIO_F_SR_IOV);
|
&proxy->pci_dev, proxy->last_pcie_cap_offset, errp);
|
||||||
|
if (res > 0) {
|
||||||
|
proxy->last_pcie_cap_offset += res;
|
||||||
|
virtio_add_feature(&vdev->host_features, VIRTIO_F_SR_IOV);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,12 +43,15 @@ void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pcie_sriov_pf_init_from_user_created_vfs() - Initialize PF with user-created
|
* pcie_sriov_pf_init_from_user_created_vfs() - Initialize PF with user-created
|
||||||
* VFs.
|
* VFs, adding ARI to PF
|
||||||
* @dev: A PCIe device being realized.
|
* @dev: A PCIe device being realized.
|
||||||
* @offset: The offset of the SR-IOV capability.
|
* @offset: The offset of the SR-IOV capability.
|
||||||
* @errp: pointer to Error*, to store an error if it happens.
|
* @errp: pointer to Error*, to store an error if it happens.
|
||||||
*
|
*
|
||||||
* Return: The size of added capability. 0 if the user did not create VFs.
|
* Initializes a PF with user-created VFs, adding the ARI extended capability to
|
||||||
|
* the PF. The VFs should call pcie_ari_init() to form an ARI device.
|
||||||
|
*
|
||||||
|
* Return: The size of added capabilities. 0 if the user did not create VFs.
|
||||||
* -1 if failed.
|
* -1 if failed.
|
||||||
*/
|
*/
|
||||||
int16_t pcie_sriov_pf_init_from_user_created_vfs(PCIDevice *dev,
|
int16_t pcie_sriov_pf_init_from_user_created_vfs(PCIDevice *dev,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue