Message ID | 1689731808-3009-2-git-send-email-yui.washidu@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | virtio-net: add support for SR-IOV emulation | expand |
On 2023/07/19 10:56, Yui Washizu wrote: > This enables SR-IOV emulation on virtio-pci devices by adding SR-IOV capability > It also introduces a newly added property 'sriov_max_vfs' > to enable or disable the SR-IOV feature on the virtio-pci device in guest, > as well as to specify the maximum number of VFs that can be created in the guest. > Currently only virtio-net is supported. > Also, the vendor ID and device ID remain the same for both the PF and VF, > enabling existing guest PF drivers to be used in the VF without any modifications. > > Signed-off-by: Yui Washizu <yui.washidu@gmail.com> > --- > hw/pci/msix.c | 8 +++-- > hw/pci/pci.c | 4 +++ > hw/virtio/virtio-pci.c | 62 ++++++++++++++++++++++++++++++---- > include/hw/virtio/virtio-pci.h | 1 + > 4 files changed, 66 insertions(+), 9 deletions(-) > > diff --git a/hw/pci/msix.c b/hw/pci/msix.c > index ab8869d9d0..3b94ce389f 100644 > --- a/hw/pci/msix.c > +++ b/hw/pci/msix.c > @@ -421,8 +421,12 @@ int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, > return ret; > } > > - pci_register_bar(dev, bar_nr, PCI_BASE_ADDRESS_SPACE_MEMORY, > - &dev->msix_exclusive_bar); > + if (pci_is_vf(dev)) { > + pcie_sriov_vf_register_bar(dev, bar_nr, &dev->msix_exclusive_bar); > + } else { > + pci_register_bar(dev, bar_nr, PCI_BASE_ADDRESS_SPACE_MEMORY, > + &dev->msix_exclusive_bar); > + } > > return 0; > } > diff --git a/hw/pci/pci.c b/hw/pci/pci.c > index e2eb4c3b4a..cbd50b38ea 100644 > --- a/hw/pci/pci.c > +++ b/hw/pci/pci.c > @@ -2325,6 +2325,10 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, > return; > } > > + if (pci_is_vf(pdev)) { > + return; > + } > + > if (!pdev->rom_bar) { > /* > * Load rom via fw_cfg instead of creating a rom bar, > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c > index edbc0daa18..2315c2647a 100644 > --- a/hw/virtio/virtio-pci.c > +++ b/hw/virtio/virtio-pci.c > @@ -49,6 +49,8 @@ > * configuration space */ > #define VIRTIO_PCI_CONFIG_SIZE(dev) VIRTIO_PCI_CONFIG_OFF(msix_enabled(dev)) > > +#define VIRTIO_MAX_VFS 127 > + > static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size, > VirtIOPCIProxy *dev); > static void virtio_pci_reset(DeviceState *qdev); > @@ -1907,6 +1909,11 @@ static void virtio_pci_pre_plugged(DeviceState *d, Error **errp) > > if (virtio_pci_modern(proxy)) { > virtio_add_feature(&vdev->host_features, VIRTIO_F_VERSION_1); > + if (proxy->sriov_max_vfs) { > + virtio_add_feature(&vdev->host_features, VIRTIO_F_SR_IOV); > + } > + } else if (proxy->sriov_max_vfs) { > + error_setg(errp, "VirtIO PCI modern is required for the use of SR-IOV"); Missing: return; > } > > virtio_add_feature(&vdev->host_features, VIRTIO_F_BAD_FEATURE); > @@ -2015,22 +2022,62 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp) > virtio_pci_modern_mem_region_map(proxy, &proxy->device, &cap); > virtio_pci_modern_mem_region_map(proxy, &proxy->notify, ¬ify.cap); > > + if (!pci_is_vf(&proxy->pci_dev) && proxy->sriov_max_vfs) { > + if (virtio_bus_get_vdev_id(bus) != VIRTIO_ID_NET) { > + error_setg(errp, "sriov_max_vfs prop is not supported by %s", > + proxy->pci_dev.name); > + return; > + } > + if (proxy->sriov_max_vfs > VIRTIO_MAX_VFS) { > + error_setg(errp, "sriov_max_vfs must be between 0 and %d", > + VIRTIO_MAX_VFS); > + return; > + } > + > + pcie_sriov_pf_init(&proxy->pci_dev, PCI_CONFIG_SPACE_SIZE, > + proxy->pci_dev.name, > + PCI_DEVICE_ID_VIRTIO_10_BASE > + + virtio_bus_get_vdev_id(bus), > + proxy->sriov_max_vfs, proxy->sriov_max_vfs, 1, 1); > + if (proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY) { > + pcie_sriov_pf_init_vf_bar(&proxy->pci_dev, proxy->modern_io_bar_idx, > + PCI_BASE_ADDRESS_SPACE_IO, 4); > + } > + if (proxy->nvectors) { > + pcie_sriov_pf_init_vf_bar(&proxy->pci_dev, proxy->msix_bar_idx, > + PCI_BASE_ADDRESS_SPACE_MEMORY, 4 * 1024); > + } > + pcie_sriov_pf_init_vf_bar(&proxy->pci_dev, proxy->modern_mem_bar_idx, > + PCI_BASE_ADDRESS_SPACE_MEMORY | > + PCI_BASE_ADDRESS_MEM_PREFETCH | > + PCI_BASE_ADDRESS_MEM_TYPE_64, > + 16 * 1024); > + } > + > if (modern_pio) { > memory_region_init(&proxy->io_bar, OBJECT(proxy), > "virtio-pci-io", 0x4); > > - pci_register_bar(&proxy->pci_dev, proxy->modern_io_bar_idx, > - PCI_BASE_ADDRESS_SPACE_IO, &proxy->io_bar); > + if (pci_is_vf(&proxy->pci_dev)) > + pcie_sriov_vf_register_bar(&proxy->pci_dev, proxy->modern_io_bar_idx, > + &proxy->io_bar); > + else > + pci_register_bar(&proxy->pci_dev, proxy->modern_io_bar_idx, > + PCI_BASE_ADDRESS_SPACE_IO, &proxy->io_bar); > > virtio_pci_modern_io_region_map(proxy, &proxy->notify_pio, > ¬ify_pio.cap); > } > > - pci_register_bar(&proxy->pci_dev, proxy->modern_mem_bar_idx, > - PCI_BASE_ADDRESS_SPACE_MEMORY | > - PCI_BASE_ADDRESS_MEM_PREFETCH | > - PCI_BASE_ADDRESS_MEM_TYPE_64, > - &proxy->modern_bar); > + if (pci_is_vf(&proxy->pci_dev)) > + pcie_sriov_vf_register_bar(&proxy->pci_dev, proxy->modern_mem_bar_idx, > + &proxy->modern_bar); > + else > + pci_register_bar(&proxy->pci_dev, proxy->modern_mem_bar_idx, > + PCI_BASE_ADDRESS_SPACE_MEMORY | > + PCI_BASE_ADDRESS_MEM_PREFETCH | > + PCI_BASE_ADDRESS_MEM_TYPE_64, > + &proxy->modern_bar); > > proxy->config_cap = virtio_pci_add_mem_cap(proxy, &cfg.cap); > cfg_mask = (void *)(proxy->pci_dev.wmask + proxy->config_cap); > @@ -2298,6 +2345,7 @@ static Property virtio_pci_properties[] = { > VIRTIO_PCI_FLAG_INIT_FLR_BIT, true), > DEFINE_PROP_BIT("aer", VirtIOPCIProxy, flags, > VIRTIO_PCI_FLAG_AER_BIT, false), > + DEFINE_PROP_UINT16("sriov_max_vfs", VirtIOPCIProxy, sriov_max_vfs, 0), > DEFINE_PROP_END_OF_LIST(), > }; > > diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h > index ab2051b64b..05ab6ddc3f 100644 > --- a/include/hw/virtio/virtio-pci.h > +++ b/include/hw/virtio/virtio-pci.h > @@ -150,6 +150,7 @@ struct VirtIOPCIProxy { > uint32_t flags; > bool disable_modern; > bool ignore_backend_features; > + uint16_t sriov_max_vfs; > OnOffAuto disable_legacy; > /* Transitional device id */ > uint16_t trans_devid;
On Wed, Jul 19, 2023 at 9:59 AM Yui Washizu <yui.washidu@gmail.com> wrote: > > This enables SR-IOV emulation on virtio-pci devices by adding SR-IOV capability > It also introduces a newly added property 'sriov_max_vfs' > to enable or disable the SR-IOV feature on the virtio-pci device in guest, > as well as to specify the maximum number of VFs that can be created in the guest. > Currently only virtio-net is supported. > Also, the vendor ID and device ID remain the same for both the PF and VF, > enabling existing guest PF drivers to be used in the VF without any modifications. > > Signed-off-by: Yui Washizu <yui.washidu@gmail.com> > --- > hw/pci/msix.c | 8 +++-- > hw/pci/pci.c | 4 +++ > hw/virtio/virtio-pci.c | 62 ++++++++++++++++++++++++++++++---- > include/hw/virtio/virtio-pci.h | 1 + > 4 files changed, 66 insertions(+), 9 deletions(-) > > diff --git a/hw/pci/msix.c b/hw/pci/msix.c > index ab8869d9d0..3b94ce389f 100644 > --- a/hw/pci/msix.c > +++ b/hw/pci/msix.c > @@ -421,8 +421,12 @@ int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, > return ret; > } > > - pci_register_bar(dev, bar_nr, PCI_BASE_ADDRESS_SPACE_MEMORY, > - &dev->msix_exclusive_bar); > + if (pci_is_vf(dev)) { > + pcie_sriov_vf_register_bar(dev, bar_nr, &dev->msix_exclusive_bar); > + } else { > + pci_register_bar(dev, bar_nr, PCI_BASE_ADDRESS_SPACE_MEMORY, > + &dev->msix_exclusive_bar); > + } > > return 0; > } > diff --git a/hw/pci/pci.c b/hw/pci/pci.c > index e2eb4c3b4a..cbd50b38ea 100644 > --- a/hw/pci/pci.c > +++ b/hw/pci/pci.c > @@ -2325,6 +2325,10 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, > return; > } > > + if (pci_is_vf(pdev)) { > + return; > + } > + > if (!pdev->rom_bar) { > /* > * Load rom via fw_cfg instead of creating a rom bar, > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c > index edbc0daa18..2315c2647a 100644 > --- a/hw/virtio/virtio-pci.c > +++ b/hw/virtio/virtio-pci.c > @@ -49,6 +49,8 @@ > * configuration space */ > #define VIRTIO_PCI_CONFIG_SIZE(dev) VIRTIO_PCI_CONFIG_OFF(msix_enabled(dev)) > > +#define VIRTIO_MAX_VFS 127 > + > static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size, > VirtIOPCIProxy *dev); > static void virtio_pci_reset(DeviceState *qdev); > @@ -1907,6 +1909,11 @@ static void virtio_pci_pre_plugged(DeviceState *d, Error **errp) > > if (virtio_pci_modern(proxy)) { > virtio_add_feature(&vdev->host_features, VIRTIO_F_VERSION_1); > + if (proxy->sriov_max_vfs) { > + virtio_add_feature(&vdev->host_features, VIRTIO_F_SR_IOV); > + } > + } else if (proxy->sriov_max_vfs) { > + error_setg(errp, "VirtIO PCI modern is required for the use of SR-IOV"); > } > > virtio_add_feature(&vdev->host_features, VIRTIO_F_BAD_FEATURE); > @@ -2015,22 +2022,62 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp) > virtio_pci_modern_mem_region_map(proxy, &proxy->device, &cap); > virtio_pci_modern_mem_region_map(proxy, &proxy->notify, ¬ify.cap); > > + if (!pci_is_vf(&proxy->pci_dev) && proxy->sriov_max_vfs) { > + if (virtio_bus_get_vdev_id(bus) != VIRTIO_ID_NET) { > + error_setg(errp, "sriov_max_vfs prop is not supported by %s", > + proxy->pci_dev.name); > + return; > + } > + if (proxy->sriov_max_vfs > VIRTIO_MAX_VFS) { > + error_setg(errp, "sriov_max_vfs must be between 0 and %d", > + VIRTIO_MAX_VFS); > + return; > + } > + > + pcie_sriov_pf_init(&proxy->pci_dev, PCI_CONFIG_SPACE_SIZE, > + proxy->pci_dev.name, > + PCI_DEVICE_ID_VIRTIO_10_BASE > + + virtio_bus_get_vdev_id(bus), > + proxy->sriov_max_vfs, proxy->sriov_max_vfs, 1, 1); > + if (proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY) { > + pcie_sriov_pf_init_vf_bar(&proxy->pci_dev, proxy->modern_io_bar_idx, > + PCI_BASE_ADDRESS_SPACE_IO, 4); > + } > + if (proxy->nvectors) { > + pcie_sriov_pf_init_vf_bar(&proxy->pci_dev, proxy->msix_bar_idx, > + PCI_BASE_ADDRESS_SPACE_MEMORY, 4 * 1024); > + } > + pcie_sriov_pf_init_vf_bar(&proxy->pci_dev, proxy->modern_mem_bar_idx, > + PCI_BASE_ADDRESS_SPACE_MEMORY | > + PCI_BASE_ADDRESS_MEM_PREFETCH | > + PCI_BASE_ADDRESS_MEM_TYPE_64, > + 16 * 1024); > + } > + > if (modern_pio) { > memory_region_init(&proxy->io_bar, OBJECT(proxy), > "virtio-pci-io", 0x4); > > - pci_register_bar(&proxy->pci_dev, proxy->modern_io_bar_idx, > - PCI_BASE_ADDRESS_SPACE_IO, &proxy->io_bar); > + if (pci_is_vf(&proxy->pci_dev)) > + pcie_sriov_vf_register_bar(&proxy->pci_dev, proxy->modern_io_bar_idx, > + &proxy->io_bar); We probably don't need another memory bar for notification. Thanks > + else > + pci_register_bar(&proxy->pci_dev, proxy->modern_io_bar_idx, > + PCI_BASE_ADDRESS_SPACE_IO, &proxy->io_bar); > > virtio_pci_modern_io_region_map(proxy, &proxy->notify_pio, > ¬ify_pio.cap); > } > > - pci_register_bar(&proxy->pci_dev, proxy->modern_mem_bar_idx, > - PCI_BASE_ADDRESS_SPACE_MEMORY | > - PCI_BASE_ADDRESS_MEM_PREFETCH | > - PCI_BASE_ADDRESS_MEM_TYPE_64, > - &proxy->modern_bar); > + if (pci_is_vf(&proxy->pci_dev)) > + pcie_sriov_vf_register_bar(&proxy->pci_dev, proxy->modern_mem_bar_idx, > + &proxy->modern_bar); > + else > + pci_register_bar(&proxy->pci_dev, proxy->modern_mem_bar_idx, > + PCI_BASE_ADDRESS_SPACE_MEMORY | > + PCI_BASE_ADDRESS_MEM_PREFETCH | > + PCI_BASE_ADDRESS_MEM_TYPE_64, > + &proxy->modern_bar); > > proxy->config_cap = virtio_pci_add_mem_cap(proxy, &cfg.cap); > cfg_mask = (void *)(proxy->pci_dev.wmask + proxy->config_cap); > @@ -2298,6 +2345,7 @@ static Property virtio_pci_properties[] = { > VIRTIO_PCI_FLAG_INIT_FLR_BIT, true), > DEFINE_PROP_BIT("aer", VirtIOPCIProxy, flags, > VIRTIO_PCI_FLAG_AER_BIT, false), > + DEFINE_PROP_UINT16("sriov_max_vfs", VirtIOPCIProxy, sriov_max_vfs, 0), > DEFINE_PROP_END_OF_LIST(), > }; > > diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h > index ab2051b64b..05ab6ddc3f 100644 > --- a/include/hw/virtio/virtio-pci.h > +++ b/include/hw/virtio/virtio-pci.h > @@ -150,6 +150,7 @@ struct VirtIOPCIProxy { > uint32_t flags; > bool disable_modern; > bool ignore_backend_features; > + uint16_t sriov_max_vfs; > OnOffAuto disable_legacy; > /* Transitional device id */ > uint16_t trans_devid; > -- > 2.39.3 >
diff --git a/hw/pci/msix.c b/hw/pci/msix.c index ab8869d9d0..3b94ce389f 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -421,8 +421,12 @@ int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, return ret; } - pci_register_bar(dev, bar_nr, PCI_BASE_ADDRESS_SPACE_MEMORY, - &dev->msix_exclusive_bar); + if (pci_is_vf(dev)) { + pcie_sriov_vf_register_bar(dev, bar_nr, &dev->msix_exclusive_bar); + } else { + pci_register_bar(dev, bar_nr, PCI_BASE_ADDRESS_SPACE_MEMORY, + &dev->msix_exclusive_bar); + } return 0; } diff --git a/hw/pci/pci.c b/hw/pci/pci.c index e2eb4c3b4a..cbd50b38ea 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -2325,6 +2325,10 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, return; } + if (pci_is_vf(pdev)) { + return; + } + if (!pdev->rom_bar) { /* * Load rom via fw_cfg instead of creating a rom bar, diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index edbc0daa18..2315c2647a 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -49,6 +49,8 @@ * configuration space */ #define VIRTIO_PCI_CONFIG_SIZE(dev) VIRTIO_PCI_CONFIG_OFF(msix_enabled(dev)) +#define VIRTIO_MAX_VFS 127 + static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size, VirtIOPCIProxy *dev); static void virtio_pci_reset(DeviceState *qdev); @@ -1907,6 +1909,11 @@ static void virtio_pci_pre_plugged(DeviceState *d, Error **errp) if (virtio_pci_modern(proxy)) { virtio_add_feature(&vdev->host_features, VIRTIO_F_VERSION_1); + if (proxy->sriov_max_vfs) { + virtio_add_feature(&vdev->host_features, VIRTIO_F_SR_IOV); + } + } else if (proxy->sriov_max_vfs) { + error_setg(errp, "VirtIO PCI modern is required for the use of SR-IOV"); } virtio_add_feature(&vdev->host_features, VIRTIO_F_BAD_FEATURE); @@ -2015,22 +2022,62 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp) virtio_pci_modern_mem_region_map(proxy, &proxy->device, &cap); virtio_pci_modern_mem_region_map(proxy, &proxy->notify, ¬ify.cap); + if (!pci_is_vf(&proxy->pci_dev) && proxy->sriov_max_vfs) { + if (virtio_bus_get_vdev_id(bus) != VIRTIO_ID_NET) { + error_setg(errp, "sriov_max_vfs prop is not supported by %s", + proxy->pci_dev.name); + return; + } + if (proxy->sriov_max_vfs > VIRTIO_MAX_VFS) { + error_setg(errp, "sriov_max_vfs must be between 0 and %d", + VIRTIO_MAX_VFS); + return; + } + + pcie_sriov_pf_init(&proxy->pci_dev, PCI_CONFIG_SPACE_SIZE, + proxy->pci_dev.name, + PCI_DEVICE_ID_VIRTIO_10_BASE + + virtio_bus_get_vdev_id(bus), + proxy->sriov_max_vfs, proxy->sriov_max_vfs, 1, 1); + if (proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY) { + pcie_sriov_pf_init_vf_bar(&proxy->pci_dev, proxy->modern_io_bar_idx, + PCI_BASE_ADDRESS_SPACE_IO, 4); + } + if (proxy->nvectors) { + pcie_sriov_pf_init_vf_bar(&proxy->pci_dev, proxy->msix_bar_idx, + PCI_BASE_ADDRESS_SPACE_MEMORY, 4 * 1024); + } + pcie_sriov_pf_init_vf_bar(&proxy->pci_dev, proxy->modern_mem_bar_idx, + PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_PREFETCH | + PCI_BASE_ADDRESS_MEM_TYPE_64, + 16 * 1024); + } + if (modern_pio) { memory_region_init(&proxy->io_bar, OBJECT(proxy), "virtio-pci-io", 0x4); - pci_register_bar(&proxy->pci_dev, proxy->modern_io_bar_idx, - PCI_BASE_ADDRESS_SPACE_IO, &proxy->io_bar); + if (pci_is_vf(&proxy->pci_dev)) + pcie_sriov_vf_register_bar(&proxy->pci_dev, proxy->modern_io_bar_idx, + &proxy->io_bar); + else + pci_register_bar(&proxy->pci_dev, proxy->modern_io_bar_idx, + PCI_BASE_ADDRESS_SPACE_IO, &proxy->io_bar); virtio_pci_modern_io_region_map(proxy, &proxy->notify_pio, ¬ify_pio.cap); } - pci_register_bar(&proxy->pci_dev, proxy->modern_mem_bar_idx, - PCI_BASE_ADDRESS_SPACE_MEMORY | - PCI_BASE_ADDRESS_MEM_PREFETCH | - PCI_BASE_ADDRESS_MEM_TYPE_64, - &proxy->modern_bar); + if (pci_is_vf(&proxy->pci_dev)) + pcie_sriov_vf_register_bar(&proxy->pci_dev, proxy->modern_mem_bar_idx, + &proxy->modern_bar); + else + pci_register_bar(&proxy->pci_dev, proxy->modern_mem_bar_idx, + PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_PREFETCH | + PCI_BASE_ADDRESS_MEM_TYPE_64, + &proxy->modern_bar); proxy->config_cap = virtio_pci_add_mem_cap(proxy, &cfg.cap); cfg_mask = (void *)(proxy->pci_dev.wmask + proxy->config_cap); @@ -2298,6 +2345,7 @@ static Property virtio_pci_properties[] = { VIRTIO_PCI_FLAG_INIT_FLR_BIT, true), DEFINE_PROP_BIT("aer", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_AER_BIT, false), + DEFINE_PROP_UINT16("sriov_max_vfs", VirtIOPCIProxy, sriov_max_vfs, 0), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h index ab2051b64b..05ab6ddc3f 100644 --- a/include/hw/virtio/virtio-pci.h +++ b/include/hw/virtio/virtio-pci.h @@ -150,6 +150,7 @@ struct VirtIOPCIProxy { uint32_t flags; bool disable_modern; bool ignore_backend_features; + uint16_t sriov_max_vfs; OnOffAuto disable_legacy; /* Transitional device id */ uint16_t trans_devid;
This enables SR-IOV emulation on virtio-pci devices by adding SR-IOV capability It also introduces a newly added property 'sriov_max_vfs' to enable or disable the SR-IOV feature on the virtio-pci device in guest, as well as to specify the maximum number of VFs that can be created in the guest. Currently only virtio-net is supported. Also, the vendor ID and device ID remain the same for both the PF and VF, enabling existing guest PF drivers to be used in the VF without any modifications. Signed-off-by: Yui Washizu <yui.washidu@gmail.com> --- hw/pci/msix.c | 8 +++-- hw/pci/pci.c | 4 +++ hw/virtio/virtio-pci.c | 62 ++++++++++++++++++++++++++++++---- include/hw/virtio/virtio-pci.h | 1 + 4 files changed, 66 insertions(+), 9 deletions(-)