qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation
@ 2023-12-10  4:05 Akihiko Odaki
  2023-12-10  4:05 ` [PATCH RFC v2 01/12] hw/pci: Initialize PCI multifunction after realization Akihiko Odaki
                   ` (13 more replies)
  0 siblings, 14 replies; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-10  4:05 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Jason Wang, Sriram Yagnaraman, Keith Busch,
	Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu, Akihiko Odaki

Introduction
------------

This series is based on the RFC series submitted by Yui Washizu[1].
See also [2] for the context.

This series enables SR-IOV emulation for virtio-net. It is useful
to test SR-IOV support on the guest, or to expose several vDPA devices
in a VM. vDPA devices can also provide L2 switching feature for
offloading though it is out of scope to allow the guest to configure
such a feature.

The PF side code resides in virtio-pci. The VF side code resides in
the PCI common infrastructure, but it is restricted to work only for
virtio-net-pci because of lack of validation.

User Interface
--------------

A user can configure a SR-IOV capable virtio-net device by adding
virtio-net-pci functions to a bus. Below is a command line example:
  -netdev user,id=n -netdev user,id=o
  -netdev user,id=p -netdev user,id=q
  -device pcie-root-port,id=b
  -device virtio-net-pci,bus=b,addr=0x0.0x3,netdev=q,sriov-pf=f
  -device virtio-net-pci,bus=b,addr=0x0.0x2,netdev=p,sriov-pf=f
  -device virtio-net-pci,bus=b,addr=0x0.0x1,netdev=o,sriov-pf=f
  -device virtio-net-pci,bus=b,addr=0x0.0x0,netdev=n,id=f

The VFs specify the paired PF with "sriov-pf" property. The PF must be
added after all VFs. It is user's responsibility to ensure that VFs have
function numbers larger than one of the PF, and the function numbers
have a consistent stride.

Keeping VF instances
--------------------

A problem with SR-IOV emulation is that it needs to hotplug the VFs as
the guest requests. Previously, this behavior was implemented by
realizing and unrealizing VFs at runtime. However, this strategy does
not work well for the proposed virtio-net emulation; in this proposal,
device options passed in the command line must be maintained as VFs
are hotplugged, but they are consumed when the machine starts and not
available after that, which makes realizing VFs at runtime impossible.

As an strategy alternative to runtime realization/unrealization, this
series proposes to reuse the code to power down PCI Express devices.
When a PCI Express device is powered down, it will be hidden from the
guest but will be kept realized. This effectively implements the
behavior we need for the SR-IOV emulation.

Summary
-------

Patch [1, 5] refactors the PCI infrastructure code.
Patch [6, 10] adds user-created SR-IOV VF infrastructure.
Patch 11 makes virtio-pci work as SR-IOV PF for user-created VFs.
Patch 12 allows user to create SR-IOV VFs with virtio-net-pci.

[1] https://patchew.org/QEMU/1689731808-3009-1-git-send-email-yui.washidu@gmail.com/
[2] https://lore.kernel.org/all/5d46f455-f530-4e5e-9ae7-13a2297d4bc5@daynix.com/

Co-developed-by: Yui Washizu <yui.washidu@gmail.com>
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
Changes in v2:
- Changed to keep VF instances.
- Link to v1: https://lore.kernel.org/r/20231202-sriov-v1-0-32b3570f7bd6@daynix.com

---
Akihiko Odaki (12):
      hw/pci: Initialize PCI multifunction after realization
      hw/pci: Determine if rombar is explicitly enabled
      hw/pci: Do not add ROM BAR for SR-IOV VF
      vfio: Avoid inspecting option QDict for rombar
      hw/qdev: Remove opts member
      pcie_sriov: Reuse SR-IOV VF device instances
      pcie_sriov: Release VFs failed to realize
      pcie_sriov: Ensure PF and VF are mutually exclusive
      pcie_sriov: Check PCI Express for SR-IOV PF
      pcie_sriov: Allow user to create SR-IOV device
      virtio-pci: Implement SR-IOV PF
      virtio-net: Implement SR-IOV VF

 docs/pcie_sriov.txt         |   8 +-
 include/hw/pci/pci.h        |   2 +-
 include/hw/pci/pci_device.h |  13 +-
 include/hw/pci/pcie_sriov.h |  25 ++-
 include/hw/qdev-core.h      |   4 -
 hw/core/qdev.c              |   1 -
 hw/net/igb.c                |   3 +-
 hw/nvme/ctrl.c              |   3 +-
 hw/pci/pci.c                |  98 +++++++-----
 hw/pci/pci_host.c           |   4 +-
 hw/pci/pcie.c               |   4 +-
 hw/pci/pcie_sriov.c         | 360 +++++++++++++++++++++++++++++++++-----------
 hw/vfio/pci.c               |   3 +-
 hw/virtio/virtio-net-pci.c  |   1 +
 hw/virtio/virtio-pci.c      |   7 +
 system/qdev-monitor.c       |  12 +-
 16 files changed, 395 insertions(+), 153 deletions(-)
---
base-commit: 4705fc0c8511d073bee4751c3c974aab2b10a970
change-id: 20231202-sriov-9402fb262be8

Best regards,
-- 
Akihiko Odaki <akihiko.odaki@daynix.com>



^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH RFC v2 01/12] hw/pci: Initialize PCI multifunction after realization
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
@ 2023-12-10  4:05 ` Akihiko Odaki
  2023-12-12  9:59   ` Philippe Mathieu-Daudé
  2023-12-10  4:05 ` [PATCH RFC v2 02/12] hw/pci: Determine if rombar is explicitly enabled Akihiko Odaki
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-10  4:05 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Jason Wang, Sriram Yagnaraman, Keith Busch,
	Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu, Akihiko Odaki

The device realization code may enable PCI multifunction for SR-IOV.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 hw/pci/pci.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index c49417abb2..4cf31128ba 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -940,8 +940,9 @@ static void pci_init_mask_bridge(PCIDevice *d)
                                PCI_PREF_RANGE_TYPE_MASK);
 }
 
-static void pci_init_multifunction(PCIBus *bus, PCIDevice *dev, Error **errp)
+static void pci_init_multifunction(PCIDevice *dev, Error **errp)
 {
+    PCIBus *bus = pci_get_bus(dev);
     uint8_t slot = PCI_SLOT(dev->devfn);
     uint8_t func;
 
@@ -1140,7 +1141,6 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
     PCIConfigReadFunc *config_read = pc->config_read;
     PCIConfigWriteFunc *config_write = pc->config_write;
-    Error *local_err = NULL;
     DeviceState *dev = DEVICE(pci_dev);
     PCIBus *bus = pci_get_bus(pci_dev);
     bool is_bridge = IS_PCI_BRIDGE(pci_dev);
@@ -1233,12 +1233,6 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
     if (is_bridge) {
         pci_init_mask_bridge(pci_dev);
     }
-    pci_init_multifunction(bus, pci_dev, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        do_pci_unregister_device(pci_dev);
-        return NULL;
-    }
 
     if (!config_read)
         config_read = pci_default_read_config;
@@ -2122,6 +2116,13 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
         }
     }
 
+    pci_init_multifunction(pci_dev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        pci_qdev_unrealize(DEVICE(pci_dev));
+        return;
+    }
+
     /*
      * A PCIe Downstream Port that do not have ARI Forwarding enabled must
      * associate only Device 0 with the device attached to the bus

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC v2 02/12] hw/pci: Determine if rombar is explicitly enabled
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
  2023-12-10  4:05 ` [PATCH RFC v2 01/12] hw/pci: Initialize PCI multifunction after realization Akihiko Odaki
@ 2023-12-10  4:05 ` Akihiko Odaki
  2023-12-10  4:05 ` [PATCH RFC v2 03/12] hw/pci: Do not add ROM BAR for SR-IOV VF Akihiko Odaki
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-10  4:05 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Jason Wang, Sriram Yagnaraman, Keith Busch,
	Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu, Akihiko Odaki

vfio determines if rombar is explicitly enabled by inspecting QDict.
Inspecting QDict is not nice because QDict is untyped and depends on the
details on the external interface. Add an infrastructure to determine if
rombar is explicitly enabled to hw/pci. PCIDevice::rom_bar is changed to
have -1 by the default to tell rombar is explicitly enabled. It is
consistent with other properties like addr and romsize.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 include/hw/pci/pci_device.h | 5 +++++
 hw/pci/pci.c                | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
index d3dd0f64b2..54fa0676ab 100644
--- a/include/hw/pci/pci_device.h
+++ b/include/hw/pci/pci_device.h
@@ -205,6 +205,11 @@ static inline uint16_t pci_get_bdf(PCIDevice *dev)
     return PCI_BUILD_BDF(pci_bus_num(pci_get_bus(dev)), dev->devfn);
 }
 
+static inline bool pci_rom_bar_explicitly_enabled(PCIDevice *dev)
+{
+    return dev->rom_bar && dev->rom_bar != -1;
+}
+
 uint16_t pci_requester_id(PCIDevice *dev);
 
 /* DMA access functions */
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 4cf31128ba..31e8f413a6 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -71,7 +71,7 @@ static Property pci_props[] = {
     DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
     DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
     DEFINE_PROP_UINT32("romsize", PCIDevice, romsize, -1),
-    DEFINE_PROP_UINT32("rombar",  PCIDevice, rom_bar, 1),
+    DEFINE_PROP_UINT32("rombar",  PCIDevice, rom_bar, -1),
     DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present,
                     QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false),
     DEFINE_PROP_BIT("x-pcie-lnksta-dllla", PCIDevice, cap_present,

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC v2 03/12] hw/pci: Do not add ROM BAR for SR-IOV VF
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
  2023-12-10  4:05 ` [PATCH RFC v2 01/12] hw/pci: Initialize PCI multifunction after realization Akihiko Odaki
  2023-12-10  4:05 ` [PATCH RFC v2 02/12] hw/pci: Determine if rombar is explicitly enabled Akihiko Odaki
@ 2023-12-10  4:05 ` Akihiko Odaki
  2023-12-10  4:05 ` [PATCH RFC v2 04/12] vfio: Avoid inspecting option QDict for rombar Akihiko Odaki
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-10  4:05 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Jason Wang, Sriram Yagnaraman, Keith Busch,
	Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu, Akihiko Odaki

A SR-IOV VF cannot have a ROM BAR.

Co-developed-by: Yui Washizu <yui.washidu@gmail.com>
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 hw/pci/pci.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 31e8f413a6..5a93cc1681 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2377,6 +2377,14 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom,
         return;
     }
 
+    if (pci_is_vf(pdev)) {
+        if (pdev->rom_bar && pdev->rom_bar != -1) {
+            error_setg(errp, "ROM BAR cannot be enabled for SR-IOV VF");
+        }
+
+        return;
+    }
+
     if (load_file || pdev->romsize == -1) {
         path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile);
         if (path == NULL) {

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC v2 04/12] vfio: Avoid inspecting option QDict for rombar
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
                   ` (2 preceding siblings ...)
  2023-12-10  4:05 ` [PATCH RFC v2 03/12] hw/pci: Do not add ROM BAR for SR-IOV VF Akihiko Odaki
@ 2023-12-10  4:05 ` Akihiko Odaki
  2023-12-10  4:05 ` [PATCH RFC v2 05/12] hw/qdev: Remove opts member Akihiko Odaki
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-10  4:05 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Jason Wang, Sriram Yagnaraman, Keith Busch,
	Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu, Akihiko Odaki

Use pci_rom_bar_explicitly_enabled() to determine if rombar is explicitly
enabled.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 hw/vfio/pci.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index c62c02f7b6..bc29ce9194 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1008,7 +1008,6 @@ static void vfio_pci_size_rom(VFIOPCIDevice *vdev)
 {
     uint32_t orig, size = cpu_to_le32((uint32_t)PCI_ROM_ADDRESS_MASK);
     off_t offset = vdev->config_offset + PCI_ROM_ADDRESS;
-    DeviceState *dev = DEVICE(vdev);
     char *name;
     int fd = vdev->vbasedev.fd;
 
@@ -1042,7 +1041,7 @@ static void vfio_pci_size_rom(VFIOPCIDevice *vdev)
     }
 
     if (vfio_opt_rom_in_denylist(vdev)) {
-        if (dev->opts && qdict_haskey(dev->opts, "rombar")) {
+        if (pci_rom_bar_explicitly_enabled(&vdev->pdev)) {
             warn_report("Device at %s is known to cause system instability"
                         " issues during option rom execution",
                         vdev->vbasedev.name);

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC v2 05/12] hw/qdev: Remove opts member
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
                   ` (3 preceding siblings ...)
  2023-12-10  4:05 ` [PATCH RFC v2 04/12] vfio: Avoid inspecting option QDict for rombar Akihiko Odaki
@ 2023-12-10  4:05 ` Akihiko Odaki
  2023-12-12 10:04   ` Philippe Mathieu-Daudé
  2023-12-10  4:05 ` [PATCH RFC v2 06/12] pcie_sriov: Reuse SR-IOV VF device instances Akihiko Odaki
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-10  4:05 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Jason Wang, Sriram Yagnaraman, Keith Busch,
	Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu, Akihiko Odaki

It is no longer used.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 include/hw/qdev-core.h |  4 ----
 hw/core/qdev.c         |  1 -
 system/qdev-monitor.c  | 12 +++++++-----
 3 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 151d968238..6befbca311 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -237,10 +237,6 @@ struct DeviceState {
      * @pending_deleted_expires_ms: optional timeout for deletion events
      */
     int64_t pending_deleted_expires_ms;
-    /**
-     * @opts: QDict of options for the device
-     */
-    QDict *opts;
     /**
      * @hotplugged: was device added after PHASE_MACHINE_READY?
      */
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 43d863b0c5..c98691a90d 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -706,7 +706,6 @@ static void device_finalize(Object *obj)
         dev->canonical_path = NULL;
     }
 
-    qobject_unref(dev->opts);
     g_free(dev->id);
 }
 
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index a13db763e5..71c00f62ee 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -625,6 +625,7 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
     char *id;
     DeviceState *dev = NULL;
     BusState *bus = NULL;
+    QDict *properties;
 
     driver = qdict_get_try_str(opts, "driver");
     if (!driver) {
@@ -705,13 +706,14 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
     }
 
     /* set properties */
-    dev->opts = qdict_clone_shallow(opts);
-    qdict_del(dev->opts, "driver");
-    qdict_del(dev->opts, "bus");
-    qdict_del(dev->opts, "id");
+    properties = qdict_clone_shallow(opts);
+    qdict_del(properties, "driver");
+    qdict_del(properties, "bus");
+    qdict_del(properties, "id");
 
-    object_set_properties_from_keyval(&dev->parent_obj, dev->opts, from_json,
+    object_set_properties_from_keyval(&dev->parent_obj, properties, from_json,
                                       errp);
+    qobject_unref(properties);
     if (*errp) {
         goto err_del_dev;
     }

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC v2 06/12] pcie_sriov: Reuse SR-IOV VF device instances
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
                   ` (4 preceding siblings ...)
  2023-12-10  4:05 ` [PATCH RFC v2 05/12] hw/qdev: Remove opts member Akihiko Odaki
@ 2023-12-10  4:05 ` Akihiko Odaki
  2023-12-10  4:05 ` [PATCH RFC v2 07/12] pcie_sriov: Release VFs failed to realize Akihiko Odaki
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-10  4:05 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Jason Wang, Sriram Yagnaraman, Keith Busch,
	Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu, Akihiko Odaki

Disable SR-IOV VF devices by reusing code to power down PCI devices
instead of removing them when the guest requests to disable VFs. This
allows to realize devices and report VF realization errors at PF
realization time.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 docs/pcie_sriov.txt         |   8 ++--
 include/hw/pci/pci.h        |   2 +-
 include/hw/pci/pci_device.h |   2 +-
 include/hw/pci/pcie_sriov.h |   6 +--
 hw/net/igb.c                |   3 +-
 hw/nvme/ctrl.c              |   3 +-
 hw/pci/pci.c                |  18 ++++----
 hw/pci/pci_host.c           |   4 +-
 hw/pci/pcie.c               |   4 +-
 hw/pci/pcie_sriov.c         | 105 +++++++++++++++++++++-----------------------
 10 files changed, 79 insertions(+), 76 deletions(-)

diff --git a/docs/pcie_sriov.txt b/docs/pcie_sriov.txt
index a47aad0bfa..ab2142807f 100644
--- a/docs/pcie_sriov.txt
+++ b/docs/pcie_sriov.txt
@@ -52,9 +52,11 @@ setting up a BAR for a VF.
       ...
 
       /* Add and initialize the SR/IOV capability */
-      pcie_sriov_pf_init(d, 0x200, "your_virtual_dev",
-                       vf_devid, initial_vfs, total_vfs,
-                       fun_offset, stride);
+      if (!pcie_sriov_pf_init(d, 0x200, "your_virtual_dev",
+                              vf_devid, initial_vfs, total_vfs,
+                              fun_offset, stride, errp)) {
+         return;
+      }
 
       /* Set up individual VF BARs (parameters as for normal BARs) */
       pcie_sriov_pf_init_vf_bar( ... )
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index fa6313aabc..fae83b9b72 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -643,6 +643,6 @@ static inline void pci_irq_pulse(PCIDevice *pci_dev)
 }
 
 MSIMessage pci_get_msi_message(PCIDevice *dev, int vector);
-void pci_set_power(PCIDevice *pci_dev, bool state);
+void pci_set_enabled(PCIDevice *pci_dev, bool state);
 
 #endif
diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
index 54fa0676ab..f5aba8ae26 100644
--- a/include/hw/pci/pci_device.h
+++ b/include/hw/pci/pci_device.h
@@ -56,7 +56,7 @@ typedef struct PCIReqIDCache PCIReqIDCache;
 struct PCIDevice {
     DeviceState qdev;
     bool partially_hotplugged;
-    bool has_power;
+    bool is_enabled;
 
     /* PCI config space */
     uint8_t *config;
diff --git a/include/hw/pci/pcie_sriov.h b/include/hw/pci/pcie_sriov.h
index 095fb0c9ed..d9a39dacca 100644
--- a/include/hw/pci/pcie_sriov.h
+++ b/include/hw/pci/pcie_sriov.h
@@ -18,7 +18,6 @@
 struct PCIESriovPF {
     uint16_t num_vfs;   /* Number of virtual functions created */
     uint8_t vf_bar_type[PCI_NUM_REGIONS];   /* Store type for each VF bar */
-    const char *vfname; /* Reference to the device type used for the VFs */
     PCIDevice **vf;     /* Pointer to an array of num_vfs VF devices */
 };
 
@@ -27,10 +26,11 @@ struct PCIESriovVF {
     uint16_t vf_number; /* Logical VF number of this function */
 };
 
-void pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
+bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
                         const char *vfname, uint16_t vf_dev_id,
                         uint16_t init_vfs, uint16_t total_vfs,
-                        uint16_t vf_offset, uint16_t vf_stride);
+                        uint16_t vf_offset, uint16_t vf_stride,
+                        Error **errp);
 void pcie_sriov_pf_exit(PCIDevice *dev);
 
 /* Set up a VF bar in the SR/IOV bar area */
diff --git a/hw/net/igb.c b/hw/net/igb.c
index 8089acfea4..326e334a8d 100644
--- a/hw/net/igb.c
+++ b/hw/net/igb.c
@@ -449,7 +449,8 @@ static void igb_pci_realize(PCIDevice *pci_dev, Error **errp)
 
     pcie_sriov_pf_init(pci_dev, IGB_CAP_SRIOV_OFFSET, TYPE_IGBVF,
         IGB_82576_VF_DEV_ID, IGB_MAX_VF_FUNCTIONS, IGB_MAX_VF_FUNCTIONS,
-        IGB_VF_OFFSET, IGB_VF_STRIDE);
+        IGB_VF_OFFSET, IGB_VF_STRIDE,
+        &error_abort);
 
     pcie_sriov_pf_init_vf_bar(pci_dev, IGBVF_MMIO_BAR_IDX,
         PCI_BASE_ADDRESS_MEM_TYPE_64 | PCI_BASE_ADDRESS_MEM_PREFETCH,
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index f026245d1e..ea006e6175 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -8042,7 +8042,8 @@ static void nvme_init_sriov(NvmeCtrl *n, PCIDevice *pci_dev, uint16_t offset)
 
     pcie_sriov_pf_init(pci_dev, offset, "nvme", vf_dev_id,
                        n->params.sriov_max_vfs, n->params.sriov_max_vfs,
-                       NVME_VF_OFFSET, NVME_VF_STRIDE);
+                       NVME_VF_OFFSET, NVME_VF_STRIDE,
+                       &error_abort);
 
     pcie_sriov_pf_init_vf_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
                               PCI_BASE_ADDRESS_MEM_TYPE_64, bar_size);
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 5a93cc1681..eb351844ee 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1516,7 +1516,7 @@ static void pci_update_mappings(PCIDevice *d)
             continue;
 
         new_addr = pci_bar_address(d, i, r->type, r->size);
-        if (!d->has_power) {
+        if (!d->is_enabled) {
             new_addr = PCI_BAR_UNMAPPED;
         }
 
@@ -1604,7 +1604,7 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val_in, int
         pci_update_irq_disabled(d, was_irq_disabled);
         memory_region_set_enabled(&d->bus_master_enable_region,
                                   (pci_get_word(d->config + PCI_COMMAND)
-                                   & PCI_COMMAND_MASTER) && d->has_power);
+                                   & PCI_COMMAND_MASTER) && d->is_enabled);
     }
 
     msi_write_config(d, addr, val_in, l);
@@ -2180,7 +2180,9 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
         return;
     }
 
-    pci_set_power(pci_dev, true);
+    if (!pci_is_vf(pci_dev)) {
+        pci_set_enabled(pci_dev, true);
+    }
 
     pci_dev->msi_trigger = pci_msi_trigger;
 }
@@ -2844,18 +2846,18 @@ MSIMessage pci_get_msi_message(PCIDevice *dev, int vector)
     return msg;
 }
 
-void pci_set_power(PCIDevice *d, bool state)
+void pci_set_enabled(PCIDevice *d, bool state)
 {
-    if (d->has_power == state) {
+    if (d->is_enabled == state) {
         return;
     }
 
-    d->has_power = state;
+    d->is_enabled = state;
     pci_update_mappings(d);
     memory_region_set_enabled(&d->bus_master_enable_region,
                               (pci_get_word(d->config + PCI_COMMAND)
-                               & PCI_COMMAND_MASTER) && d->has_power);
-    if (!d->has_power) {
+                               & PCI_COMMAND_MASTER) && d->is_enabled);
+    if (!d->is_enabled) {
         pci_device_reset(d);
     }
 }
diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index a18aa0a8d4..1f3030108c 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -86,7 +86,7 @@ void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
      * allowing direct removal of unexposed functions.
      */
     if ((pci_dev->qdev.hotplugged && !pci_get_function_0(pci_dev)) ||
-        !pci_dev->has_power || is_pci_dev_ejected(pci_dev)) {
+        !pci_dev->is_enabled || is_pci_dev_ejected(pci_dev)) {
         return;
     }
 
@@ -111,7 +111,7 @@ uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
      * allowing direct removal of unexposed functions.
      */
     if ((pci_dev->qdev.hotplugged && !pci_get_function_0(pci_dev)) ||
-        !pci_dev->has_power || is_pci_dev_ejected(pci_dev)) {
+        !pci_dev->is_enabled || is_pci_dev_ejected(pci_dev)) {
         return ~0x0;
     }
 
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 6db0cf69cd..f34c157e1f 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -394,7 +394,9 @@ static void pcie_set_power_device(PCIBus *bus, PCIDevice *dev, void *opaque)
 {
     bool *power = opaque;
 
-    pci_set_power(dev, *power);
+    if (!pci_is_vf(dev)) {
+        pci_set_enabled(dev, *power);
+    }
 }
 
 static void pcie_cap_update_power(PCIDevice *hotplug_dev)
diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
index 5ef8950940..5fc146efc4 100644
--- a/hw/pci/pcie_sriov.c
+++ b/hw/pci/pcie_sriov.c
@@ -20,15 +20,29 @@
 #include "qapi/error.h"
 #include "trace.h"
 
-static PCIDevice *register_vf(PCIDevice *pf, int devfn,
-                              const char *name, uint16_t vf_num);
-static void unregister_vfs(PCIDevice *dev);
+static void unrealize_vfs(PCIDevice *dev, uint16_t total_vfs)
+{
+    for (uint16_t i = 0; i < total_vfs; i++) {
+        Error *err = NULL;
+        PCIDevice *vf = dev->exp.sriov_pf.vf[i];
+        if (!object_property_set_bool(OBJECT(vf), "realized", false, &err)) {
+            error_reportf_err(err, "Failed to unplug: ");
+        }
+        object_unparent(OBJECT(vf));
+        object_unref(OBJECT(vf));
+    }
+    g_free(dev->exp.sriov_pf.vf);
+    dev->exp.sriov_pf.vf = NULL;
+}
 
-void pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
+bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
                         const char *vfname, uint16_t vf_dev_id,
                         uint16_t init_vfs, uint16_t total_vfs,
-                        uint16_t vf_offset, uint16_t vf_stride)
+                        uint16_t vf_offset, uint16_t vf_stride,
+                        Error **errp)
 {
+    BusState *bus = qdev_get_parent_bus(&dev->qdev);
+    int32_t devfn = dev->devfn + vf_offset;
     uint8_t *cfg = dev->config + offset;
     uint8_t *wmask;
 
@@ -36,7 +50,6 @@ void pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
                         offset, PCI_EXT_CAP_SRIOV_SIZEOF);
     dev->exp.sriov_cap = offset;
     dev->exp.sriov_pf.num_vfs = 0;
-    dev->exp.sriov_pf.vfname = g_strdup(vfname);
     dev->exp.sriov_pf.vf = NULL;
 
     pci_set_word(cfg + PCI_SRIOV_VF_OFFSET, vf_offset);
@@ -69,13 +82,36 @@ void pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
     pci_set_word(wmask + PCI_SRIOV_SYS_PGSIZE, 0x553);
 
     qdev_prop_set_bit(&dev->qdev, "multifunction", true);
+
+    dev->exp.sriov_pf.vf = g_new(PCIDevice *, total_vfs);
+    assert(dev->exp.sriov_pf.vf);
+
+    for (uint16_t i = 0; i < total_vfs; i++) {
+        PCIDevice *vf = pci_new(devfn, vfname);
+        vf->exp.sriov_vf.pf = dev;
+        vf->exp.sriov_vf.vf_number = i;
+
+        if (!qdev_realize(&vf->qdev, bus, errp)) {
+            unrealize_vfs(dev, i);
+            return false;
+        }
+
+        /* set vid/did according to sr/iov spec - they are not used */
+        pci_config_set_vendor_id(vf->config, 0xffff);
+        pci_config_set_device_id(vf->config, 0xffff);
+
+        dev->exp.sriov_pf.vf[i] = vf;
+        devfn += vf_stride;
+    }
+
+    return true;
 }
 
 void pcie_sriov_pf_exit(PCIDevice *dev)
 {
-    unregister_vfs(dev);
-    g_free((char *)dev->exp.sriov_pf.vfname);
-    dev->exp.sriov_pf.vfname = NULL;
+    uint8_t *cfg = dev->config + dev->exp.sriov_cap;
+
+    unrealize_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF));
 }
 
 void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num,
@@ -141,55 +177,22 @@ void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num,
     }
 }
 
-static PCIDevice *register_vf(PCIDevice *pf, int devfn, const char *name,
-                              uint16_t vf_num)
-{
-    PCIDevice *dev = pci_new(devfn, name);
-    dev->exp.sriov_vf.pf = pf;
-    dev->exp.sriov_vf.vf_number = vf_num;
-    PCIBus *bus = pci_get_bus(pf);
-    Error *local_err = NULL;
-
-    qdev_realize(&dev->qdev, &bus->qbus, &local_err);
-    if (local_err) {
-        error_report_err(local_err);
-        return NULL;
-    }
-
-    /* set vid/did according to sr/iov spec - they are not used */
-    pci_config_set_vendor_id(dev->config, 0xffff);
-    pci_config_set_device_id(dev->config, 0xffff);
-
-    return dev;
-}
-
 static void register_vfs(PCIDevice *dev)
 {
     uint16_t num_vfs;
     uint16_t i;
     uint16_t sriov_cap = dev->exp.sriov_cap;
-    uint16_t vf_offset =
-        pci_get_word(dev->config + sriov_cap + PCI_SRIOV_VF_OFFSET);
-    uint16_t vf_stride =
-        pci_get_word(dev->config + sriov_cap + PCI_SRIOV_VF_STRIDE);
-    int32_t devfn = dev->devfn + vf_offset;
 
     assert(sriov_cap > 0);
     num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF);
-
-    dev->exp.sriov_pf.vf = g_new(PCIDevice *, num_vfs);
-    assert(dev->exp.sriov_pf.vf);
+    if (num_vfs > pci_get_word(dev->config + sriov_cap + PCI_SRIOV_TOTAL_VF)) {
+        return;
+    }
 
     trace_sriov_register_vfs(dev->name, PCI_SLOT(dev->devfn),
                              PCI_FUNC(dev->devfn), num_vfs);
     for (i = 0; i < num_vfs; i++) {
-        dev->exp.sriov_pf.vf[i] = register_vf(dev, devfn,
-                                              dev->exp.sriov_pf.vfname, i);
-        if (!dev->exp.sriov_pf.vf[i]) {
-            num_vfs = i;
-            break;
-        }
-        devfn += vf_stride;
+        pci_set_enabled(dev->exp.sriov_pf.vf[i], true);
     }
     dev->exp.sriov_pf.num_vfs = num_vfs;
 }
@@ -202,16 +205,8 @@ static void unregister_vfs(PCIDevice *dev)
     trace_sriov_unregister_vfs(dev->name, PCI_SLOT(dev->devfn),
                                PCI_FUNC(dev->devfn), num_vfs);
     for (i = 0; i < num_vfs; i++) {
-        Error *err = NULL;
-        PCIDevice *vf = dev->exp.sriov_pf.vf[i];
-        if (!object_property_set_bool(OBJECT(vf), "realized", false, &err)) {
-            error_reportf_err(err, "Failed to unplug: ");
-        }
-        object_unparent(OBJECT(vf));
-        object_unref(OBJECT(vf));
+        pci_set_enabled(dev->exp.sriov_pf.vf[i], false);
     }
-    g_free(dev->exp.sriov_pf.vf);
-    dev->exp.sriov_pf.vf = NULL;
     dev->exp.sriov_pf.num_vfs = 0;
     pci_set_word(dev->config + dev->exp.sriov_cap + PCI_SRIOV_NUM_VF, 0);
 }

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC v2 07/12] pcie_sriov: Release VFs failed to realize
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
                   ` (5 preceding siblings ...)
  2023-12-10  4:05 ` [PATCH RFC v2 06/12] pcie_sriov: Reuse SR-IOV VF device instances Akihiko Odaki
@ 2023-12-10  4:05 ` Akihiko Odaki
  2023-12-10  4:05 ` [PATCH RFC v2 08/12] pcie_sriov: Ensure PF and VF are mutually exclusive Akihiko Odaki
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-10  4:05 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Jason Wang, Sriram Yagnaraman, Keith Busch,
	Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu, Akihiko Odaki

Release VFs failed to realize just as we do in unregister_vfs().

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 hw/pci/pcie_sriov.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
index 5fc146efc4..566aeb9e99 100644
--- a/hw/pci/pcie_sriov.c
+++ b/hw/pci/pcie_sriov.c
@@ -92,6 +92,8 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
         vf->exp.sriov_vf.vf_number = i;
 
         if (!qdev_realize(&vf->qdev, bus, errp)) {
+            object_unparent(OBJECT(vf));
+            object_unref(vf);
             unrealize_vfs(dev, i);
             return false;
         }

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC v2 08/12] pcie_sriov: Ensure PF and VF are mutually exclusive
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
                   ` (6 preceding siblings ...)
  2023-12-10  4:05 ` [PATCH RFC v2 07/12] pcie_sriov: Release VFs failed to realize Akihiko Odaki
@ 2023-12-10  4:05 ` Akihiko Odaki
  2023-12-10  4:05 ` [PATCH RFC v2 09/12] pcie_sriov: Check PCI Express for SR-IOV PF Akihiko Odaki
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-10  4:05 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Jason Wang, Sriram Yagnaraman, Keith Busch,
	Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu, Akihiko Odaki

A device cannot be a SR-IOV PF and a VF at the same time.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 hw/pci/pcie_sriov.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
index 566aeb9e99..160dfc84ec 100644
--- a/hw/pci/pcie_sriov.c
+++ b/hw/pci/pcie_sriov.c
@@ -46,6 +46,11 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
     uint8_t *cfg = dev->config + offset;
     uint8_t *wmask;
 
+    if (pci_is_vf(dev)) {
+        error_setg(errp, "a device cannot be a SR-IOV PF and a VF at the same time");
+        return false;
+    }
+
     pcie_add_capability(dev, PCI_EXT_CAP_ID_SRIOV, 1,
                         offset, PCI_EXT_CAP_SRIOV_SIZEOF);
     dev->exp.sriov_cap = offset;

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC v2 09/12] pcie_sriov: Check PCI Express for SR-IOV PF
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
                   ` (7 preceding siblings ...)
  2023-12-10  4:05 ` [PATCH RFC v2 08/12] pcie_sriov: Ensure PF and VF are mutually exclusive Akihiko Odaki
@ 2023-12-10  4:05 ` Akihiko Odaki
  2023-12-10  4:05 ` [PATCH RFC v2 10/12] pcie_sriov: Allow user to create SR-IOV device Akihiko Odaki
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-10  4:05 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Jason Wang, Sriram Yagnaraman, Keith Busch,
	Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu, Akihiko Odaki

SR-IOV requires PCI Express.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 hw/pci/pcie_sriov.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
index 160dfc84ec..8272916cf3 100644
--- a/hw/pci/pcie_sriov.c
+++ b/hw/pci/pcie_sriov.c
@@ -46,6 +46,11 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
     uint8_t *cfg = dev->config + offset;
     uint8_t *wmask;
 
+    if (!pci_is_express(dev)) {
+        error_setg(errp, "PCI Express is required for SR-IOV PF");
+        return false;
+    }
+
     if (pci_is_vf(dev)) {
         error_setg(errp, "a device cannot be a SR-IOV PF and a VF at the same time");
         return false;

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC v2 10/12] pcie_sriov: Allow user to create SR-IOV device
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
                   ` (8 preceding siblings ...)
  2023-12-10  4:05 ` [PATCH RFC v2 09/12] pcie_sriov: Check PCI Express for SR-IOV PF Akihiko Odaki
@ 2023-12-10  4:05 ` Akihiko Odaki
  2023-12-10  4:05 ` [PATCH RFC v2 11/12] virtio-pci: Implement SR-IOV PF Akihiko Odaki
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-10  4:05 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Jason Wang, Sriram Yagnaraman, Keith Busch,
	Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu, Akihiko Odaki

A user can create a SR-IOV device by specifying the PF with the
sriov-pf property of the VFs. The VFs must be added before the PF.

A user-creatable VF must have PCIDeviceClass::sriov_vf_user_creatable
set. Such a VF cannot refer to the PF because it is created before the
PF.

A PF that user-creatable VFs can be attached calls
pcie_sriov_pf_init_from_user_created_vfs() during realization and
pcie_sriov_pf_exit() when exiting.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 include/hw/pci/pci_device.h |   6 +-
 include/hw/pci/pcie_sriov.h |  19 +++
 hw/pci/pci.c                |  53 ++++++---
 hw/pci/pcie_sriov.c         | 279 +++++++++++++++++++++++++++++++++++---------
 4 files changed, 283 insertions(+), 74 deletions(-)

diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
index f5aba8ae26..15ec97908d 100644
--- a/include/hw/pci/pci_device.h
+++ b/include/hw/pci/pci_device.h
@@ -37,6 +37,8 @@ struct PCIDeviceClass {
     uint16_t subsystem_id;              /* only for header type = 0 */
 
     const char *romfile;                /* rom bar */
+
+    bool sriov_vf_user_creatable;
 };
 
 enum PCIReqIDType {
@@ -160,6 +162,8 @@ struct PCIDevice {
     /* ID of standby device in net_failover pair */
     char *failover_pair_id;
     uint32_t acpi_index;
+
+    char *sriov_pf;
 };
 
 static inline int pci_intx(PCIDevice *pci_dev)
@@ -192,7 +196,7 @@ static inline int pci_is_express_downstream_port(const PCIDevice *d)
 
 static inline int pci_is_vf(const PCIDevice *d)
 {
-    return d->exp.sriov_vf.pf != NULL;
+    return d->sriov_pf || d->exp.sriov_vf.pf != NULL;
 }
 
 static inline uint32_t pci_config_size(const PCIDevice *d)
diff --git a/include/hw/pci/pcie_sriov.h b/include/hw/pci/pcie_sriov.h
index d9a39dacca..7a66b6cd7c 100644
--- a/include/hw/pci/pcie_sriov.h
+++ b/include/hw/pci/pcie_sriov.h
@@ -19,6 +19,7 @@ struct PCIESriovPF {
     uint16_t num_vfs;   /* Number of virtual functions created */
     uint8_t vf_bar_type[PCI_NUM_REGIONS];   /* Store type for each VF bar */
     PCIDevice **vf;     /* Pointer to an array of num_vfs VF devices */
+    bool vf_user_created; /* If VFs are created by user */
 };
 
 struct PCIESriovVF {
@@ -41,6 +42,24 @@ void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num,
 void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num,
                                 MemoryRegion *memory);
 
+/**
+ * pcie_sriov_pf_init_from_user_created_vfs() - Initialize PF with user-created
+ *                                              VFs.
+ * @dev: A PCIe device being realized.
+ * @offset: The offset of the SR-IOV capability.
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Return:
+ * * true - @dev is initialized as a PCIe SR-IOV PF.
+ * * false - @dev is not initialized because there is no SR-IOV VFs or an error
+ *           occurred.
+ */
+bool pcie_sriov_pf_init_from_user_created_vfs(PCIDevice *dev, uint16_t offset,
+                                              Error **errp);
+
+bool pcie_sriov_register_device(PCIDevice *dev, Error **errp);
+void pcie_sriov_unregister_device(PCIDevice *dev);
+
 /*
  * Default (minimal) page size support values
  * as required by the SR/IOV standard:
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index eb351844ee..592af3bcab 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -85,6 +85,7 @@ static Property pci_props[] = {
                     QEMU_PCIE_ERR_UNC_MASK_BITNR, true),
     DEFINE_PROP_BIT("x-pcie-ari-nextfn-1", PCIDevice, cap_present,
                     QEMU_PCIE_ARI_NEXTFN_1_BITNR, false),
+    DEFINE_PROP_STRING("sriov-pf", PCIDevice, sriov_pf),
     DEFINE_PROP_END_OF_LIST()
 };
 
@@ -955,8 +956,7 @@ static void pci_init_multifunction(PCIDevice *dev, Error **errp)
      * device, as it may just be a VF that ended up with function 0 in
      * the legacy PCI interpretation. Avoid failing in such cases:
      */
-    if (pci_is_vf(dev) &&
-        dev->exp.sriov_vf.pf->cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {
+    if (pci_is_vf(dev)) {
         return;
     }
 
@@ -1267,6 +1267,7 @@ static void pci_qdev_unrealize(DeviceState *dev)
 
     pci_unregister_io_regions(pci_dev);
     pci_del_option_rom(pci_dev);
+    pcie_sriov_unregister_device(pci_dev);
 
     if (pc->exit) {
         pc->exit(pci_dev);
@@ -1298,7 +1299,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
     pcibus_t size = memory_region_size(memory);
     uint8_t hdr_type;
 
-    assert(!pci_is_vf(pci_dev)); /* VFs must use pcie_sriov_vf_register_bar */
     assert(region_num >= 0);
     assert(region_num < PCI_NUM_REGIONS);
     assert(is_power_of_2(size));
@@ -1309,7 +1309,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
     assert(hdr_type != PCI_HEADER_TYPE_BRIDGE || region_num < 2);
 
     r = &pci_dev->io_regions[region_num];
-    r->addr = PCI_BAR_UNMAPPED;
     r->size = size;
     r->type = type;
     r->memory = memory;
@@ -1317,22 +1316,35 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
                         ? pci_get_bus(pci_dev)->address_space_io
                         : pci_get_bus(pci_dev)->address_space_mem;
 
-    wmask = ~(size - 1);
-    if (region_num == PCI_ROM_SLOT) {
-        /* ROM enable bit is writable */
-        wmask |= PCI_ROM_ADDRESS_ENABLE;
-    }
-
-    addr = pci_bar(pci_dev, region_num);
-    pci_set_long(pci_dev->config + addr, type);
+    if (pci_is_vf(pci_dev)) {
+        PCIDevice *pf = pci_dev->exp.sriov_vf.pf;
+        assert(!pf || type == pf->exp.sriov_pf.vf_bar_type[region_num]);
 
-    if (!(r->type & PCI_BASE_ADDRESS_SPACE_IO) &&
-        r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-        pci_set_quad(pci_dev->wmask + addr, wmask);
-        pci_set_quad(pci_dev->cmask + addr, ~0ULL);
+        r->addr = pci_bar_address(pci_dev, region_num, r->type, r->size);
+        if (r->addr != PCI_BAR_UNMAPPED) {
+            memory_region_add_subregion_overlap(r->address_space,
+                                                r->addr, r->memory, 1);
+        }
     } else {
-        pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff);
-        pci_set_long(pci_dev->cmask + addr, 0xffffffff);
+        r->addr = PCI_BAR_UNMAPPED;
+
+        wmask = ~(size - 1);
+        if (region_num == PCI_ROM_SLOT) {
+            /* ROM enable bit is writable */
+            wmask |= PCI_ROM_ADDRESS_ENABLE;
+        }
+
+        addr = pci_bar(pci_dev, region_num);
+        pci_set_long(pci_dev->config + addr, type);
+
+        if (!(r->type & PCI_BASE_ADDRESS_SPACE_IO) &&
+            r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+            pci_set_quad(pci_dev->wmask + addr, wmask);
+            pci_set_quad(pci_dev->cmask + addr, ~0ULL);
+        } else {
+            pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff);
+            pci_set_long(pci_dev->cmask + addr, 0xffffffff);
+        }
     }
 }
 
@@ -2116,6 +2128,11 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
         }
     }
 
+    if (!pcie_sriov_register_device(pci_dev, errp)) {
+        pci_qdev_unrealize(DEVICE(pci_dev));
+        return;
+    }
+
     pci_init_multifunction(pci_dev, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
index 8272916cf3..55abf65ee9 100644
--- a/hw/pci/pcie_sriov.c
+++ b/hw/pci/pcie_sriov.c
@@ -20,6 +20,8 @@
 #include "qapi/error.h"
 #include "trace.h"
 
+static GHashTable *pfs;
+
 static void unrealize_vfs(PCIDevice *dev, uint16_t total_vfs)
 {
     for (uint16_t i = 0; i < total_vfs; i++) {
@@ -35,14 +37,45 @@ static void unrealize_vfs(PCIDevice *dev, uint16_t total_vfs)
     dev->exp.sriov_pf.vf = NULL;
 }
 
-bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
-                        const char *vfname, uint16_t vf_dev_id,
-                        uint16_t init_vfs, uint16_t total_vfs,
-                        uint16_t vf_offset, uint16_t vf_stride,
-                        Error **errp)
+static void register_vfs(PCIDevice *dev)
+{
+    uint16_t num_vfs;
+    uint16_t i;
+    uint16_t sriov_cap = dev->exp.sriov_cap;
+
+    assert(sriov_cap > 0);
+    num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF);
+    if (num_vfs > pci_get_word(dev->config + sriov_cap + PCI_SRIOV_TOTAL_VF)) {
+        return;
+    }
+
+    trace_sriov_register_vfs(dev->name, PCI_SLOT(dev->devfn),
+                             PCI_FUNC(dev->devfn), num_vfs);
+    for (i = 0; i < num_vfs; i++) {
+        pci_set_enabled(dev->exp.sriov_pf.vf[i], true);
+    }
+    dev->exp.sriov_pf.num_vfs = num_vfs;
+}
+
+static void unregister_vfs(PCIDevice *dev)
+{
+    uint16_t num_vfs = dev->exp.sriov_pf.num_vfs;
+    uint16_t i;
+
+    trace_sriov_unregister_vfs(dev->name, PCI_SLOT(dev->devfn),
+                               PCI_FUNC(dev->devfn), num_vfs);
+    for (i = 0; i < num_vfs; i++) {
+        pci_set_enabled(dev->exp.sriov_pf.vf[i], false);
+    }
+    dev->exp.sriov_pf.num_vfs = 0;
+    pci_set_word(dev->config + dev->exp.sriov_cap + PCI_SRIOV_NUM_VF, 0);
+}
+
+static bool pcie_sriov_pf_init_common(PCIDevice *dev, uint16_t offset,
+                                      uint16_t vf_dev_id, uint16_t init_vfs,
+                                      uint16_t total_vfs, uint16_t vf_offset,
+                                      uint16_t vf_stride, Error **errp)
 {
-    BusState *bus = qdev_get_parent_bus(&dev->qdev);
-    int32_t devfn = dev->devfn + vf_offset;
     uint8_t *cfg = dev->config + offset;
     uint8_t *wmask;
 
@@ -93,6 +126,28 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
 
     qdev_prop_set_bit(&dev->qdev, "multifunction", true);
 
+    return true;
+}
+
+bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
+                        const char *vfname, uint16_t vf_dev_id,
+                        uint16_t init_vfs, uint16_t total_vfs,
+                        uint16_t vf_offset, uint16_t vf_stride,
+                        Error **errp)
+{
+    BusState *bus = qdev_get_parent_bus(&dev->qdev);
+    int32_t devfn = dev->devfn + vf_offset;
+
+    if (pfs && g_hash_table_contains(pfs, dev->qdev.id)) {
+        error_setg(errp, "attaching user-created SR-IOV VF unsupported");
+        return false;
+    }
+
+    if (!pcie_sriov_pf_init_common(dev, offset, vf_dev_id, init_vfs,
+                                   total_vfs, vf_offset, vf_stride, errp)) {
+        return false;
+    }
+
     dev->exp.sriov_pf.vf = g_new(PCIDevice *, total_vfs);
     assert(dev->exp.sriov_pf.vf);
 
@@ -123,7 +178,20 @@ void pcie_sriov_pf_exit(PCIDevice *dev)
 {
     uint8_t *cfg = dev->config + dev->exp.sriov_cap;
 
-    unrealize_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF));
+    if (dev->exp.sriov_pf.vf_user_created) {
+        uint16_t ven_id = pci_get_word(dev->config + PCI_VENDOR_ID);
+        uint16_t total_vfs = pci_get_word(dev->config + PCI_SRIOV_TOTAL_VF);
+        uint16_t vf_dev_id = pci_get_word(dev->config + PCI_SRIOV_VF_DID);
+
+        unregister_vfs(dev);
+
+        for (uint16_t i = 0; i < total_vfs; i++) {
+            pci_config_set_vendor_id(dev->exp.sriov_pf.vf[i]->config, ven_id);
+            pci_config_set_device_id(dev->exp.sriov_pf.vf[i]->config, vf_dev_id);
+        }
+    } else {
+        unrealize_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF));
+    }
 }
 
 void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num,
@@ -156,71 +224,172 @@ void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num,
 void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num,
                                 MemoryRegion *memory)
 {
-    PCIIORegion *r;
-    PCIBus *bus = pci_get_bus(dev);
     uint8_t type;
-    pcibus_t size = memory_region_size(memory);
 
-    assert(pci_is_vf(dev)); /* PFs must use pci_register_bar */
-    assert(region_num >= 0);
-    assert(region_num < PCI_NUM_REGIONS);
+    assert(dev->exp.sriov_vf.pf);
     type = dev->exp.sriov_vf.pf->exp.sriov_pf.vf_bar_type[region_num];
 
-    if (!is_power_of_2(size)) {
-        error_report("%s: PCI region size must be a power"
-                     " of two - type=0x%x, size=0x%"FMT_PCIBUS,
-                     __func__, type, size);
-        exit(1);
-    }
+    return pci_register_bar(dev, region_num, type, memory);
+}
 
-    r = &dev->io_regions[region_num];
-    r->memory = memory;
-    r->address_space =
-        type & PCI_BASE_ADDRESS_SPACE_IO
-        ? bus->address_space_io
-        : bus->address_space_mem;
-    r->size = size;
-    r->type = type;
-
-    r->addr = pci_bar_address(dev, region_num, r->type, r->size);
-    if (r->addr != PCI_BAR_UNMAPPED) {
-        memory_region_add_subregion_overlap(r->address_space,
-                                            r->addr, r->memory, 1);
-    }
+static gint compare_vf_devfns(gconstpointer a, gconstpointer b)
+{
+    return (*(PCIDevice **)a)->devfn - (*(PCIDevice **)b)->devfn;
 }
 
-static void register_vfs(PCIDevice *dev)
+bool pcie_sriov_pf_init_from_user_created_vfs(PCIDevice *dev, uint16_t offset,
+                                              Error **errp)
 {
-    uint16_t num_vfs;
+    GPtrArray *pf;
+    PCIDevice **vfs;
+    BusState *bus = qdev_get_parent_bus(DEVICE(dev));
+    uint16_t ven_id = pci_get_word(dev->config + PCI_VENDOR_ID);
+    uint16_t vf_dev_id;
+    uint16_t vf_offset;
+    uint16_t vf_stride;
     uint16_t i;
-    uint16_t sriov_cap = dev->exp.sriov_cap;
 
-    assert(sriov_cap > 0);
-    num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF);
-    if (num_vfs > pci_get_word(dev->config + sriov_cap + PCI_SRIOV_TOTAL_VF)) {
-        return;
+    if (!pfs || !dev->qdev.id) {
+        return false;
     }
 
-    trace_sriov_register_vfs(dev->name, PCI_SLOT(dev->devfn),
-                             PCI_FUNC(dev->devfn), num_vfs);
-    for (i = 0; i < num_vfs; i++) {
-        pci_set_enabled(dev->exp.sriov_pf.vf[i], true);
+    pf = g_hash_table_lookup(pfs, dev->qdev.id);
+    if (!pf) {
+        return false;
     }
-    dev->exp.sriov_pf.num_vfs = num_vfs;
+
+    if (pf->len > UINT16_MAX) {
+        error_setg(errp, "too many VFs");
+        return false;
+    }
+
+    g_ptr_array_sort(pf, compare_vf_devfns);
+    vfs = (void *)pf->pdata;
+
+    if (vfs[0]->devfn <= dev->devfn) {
+        error_setg(errp, "a VF function number is less than the PF function number");
+        return false;
+    }
+
+    vf_dev_id = pci_get_word(vfs[0]->config + PCI_DEVICE_ID);
+    vf_offset = vfs[0]->devfn - dev->devfn;
+    vf_stride = pf->len < 2 ? 0 : vfs[1]->devfn - vfs[0]->devfn;
+
+    for (i = 0; i < pf->len; i++) {
+        if (bus != qdev_get_parent_bus(&vfs[i]->qdev)) {
+            error_setg(errp, "SR-IOV VF parent bus mismatches with PF");
+            return false;
+        }
+
+        if (ven_id != pci_get_word(vfs[i]->config + PCI_VENDOR_ID)) {
+            error_setg(errp, "SR-IOV VF vendor ID mismatches with PF");
+            return false;
+        }
+
+        if (vf_dev_id != pci_get_word(vfs[i]->config + PCI_DEVICE_ID)) {
+            error_setg(errp, "inconsistent SR-IOV VF device IDs");
+            return false;
+        }
+
+        for (size_t j = 0; j < PCI_NUM_REGIONS; j++) {
+            if (vfs[i]->io_regions[j].size != vfs[0]->io_regions[j].size ||
+                vfs[i]->io_regions[j].type != vfs[0]->io_regions[j].type) {
+                error_setg(errp, "inconsistent SR-IOV BARs");
+                return false;
+            }
+        }
+
+        if (vfs[i]->devfn - vfs[0]->devfn != vf_stride * i) {
+            error_setg(errp, "inconsistent SR-IOV stride");
+            return false;
+        }
+    }
+
+    if (!pcie_sriov_pf_init_common(dev, offset, vf_dev_id, pf->len,
+                                   pf->len, vf_offset, vf_stride, errp)) {
+        return false;
+    }
+
+    for (i = 0; i < pf->len; i++) {
+        vfs[i]->exp.sriov_vf.pf = dev;
+
+        /* set vid/did according to sr/iov spec - they are not used */
+        pci_config_set_vendor_id(vfs[i]->config, 0xffff);
+        pci_config_set_device_id(vfs[i]->config, 0xffff);
+    }
+
+    dev->exp.sriov_pf.vf = vfs;
+    dev->exp.sriov_pf.vf_user_created = true;
+
+    for (i = 0; i < PCI_NUM_REGIONS; i++) {
+        uint8_t type = vfs[0]->io_regions[i].type;
+        pcibus_t size = vfs[0]->io_regions[i].size;
+
+        if (size) {
+            pcie_sriov_pf_init_vf_bar(dev, i, type, size);
+        }
+    }
+
+    return true;
 }
 
-static void unregister_vfs(PCIDevice *dev)
+bool pcie_sriov_register_device(PCIDevice *dev, Error **errp)
 {
-    uint16_t num_vfs = dev->exp.sriov_pf.num_vfs;
-    uint16_t i;
+    if (!dev->exp.sriov_pf.vf && dev->qdev.id &&
+        pfs && g_hash_table_contains(pfs, dev->qdev.id)) {
+        error_setg(errp, "attaching user-created SR-IOV VF unsupported");
+        return false;
+    }
 
-    trace_sriov_unregister_vfs(dev->name, PCI_SLOT(dev->devfn),
-                               PCI_FUNC(dev->devfn), num_vfs);
-    for (i = 0; i < num_vfs; i++) {
-        pci_set_enabled(dev->exp.sriov_pf.vf[i], false);
+    if (dev->sriov_pf) {
+        PCIDevice *pci_pf;
+        GPtrArray *pf;
+
+        if (!PCI_DEVICE_GET_CLASS(dev)->sriov_vf_user_creatable) {
+            error_setg(errp, "user cannot create SR-IOV VF with this device type");
+            return false;
+        }
+
+        if (!pci_is_express(dev)) {
+            error_setg(errp, "PCI Express is required for SR-IOV VF");
+            return false;
+        }
+
+        if (!pci_qdev_find_device(dev->sriov_pf, &pci_pf)) {
+            error_setg(errp, "PCI device specified as SR-IOV PF already exists");
+            return false;
+        }
+
+        if (!pfs) {
+            pfs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+        }
+
+        pf = g_hash_table_lookup(pfs, dev->sriov_pf);
+        if (!pf) {
+            pf = g_ptr_array_new();
+            g_hash_table_insert(pfs, g_strdup(dev->sriov_pf), pf);
+        }
+
+        g_ptr_array_add(pf, dev);
+    }
+
+    return true;
+}
+
+void pcie_sriov_unregister_device(PCIDevice *dev)
+{
+    if (dev->sriov_pf && pfs) {
+        GPtrArray *pf = g_hash_table_lookup(pfs, dev->qdev.id);
+
+        if (pf) {
+            g_ptr_array_remove_fast(pf, dev);
+
+            if (!pf->len) {
+                g_hash_table_remove(pfs, dev->qdev.id);
+                g_ptr_array_free(pf, FALSE);
+            }
+        }
     }
-    dev->exp.sriov_pf.num_vfs = 0;
-    pci_set_word(dev->config + dev->exp.sriov_cap + PCI_SRIOV_NUM_VF, 0);
 }
 
 void pcie_sriov_config_write(PCIDevice *dev, uint32_t address,

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC v2 11/12] virtio-pci: Implement SR-IOV PF
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
                   ` (9 preceding siblings ...)
  2023-12-10  4:05 ` [PATCH RFC v2 10/12] pcie_sriov: Allow user to create SR-IOV device Akihiko Odaki
@ 2023-12-10  4:05 ` Akihiko Odaki
  2023-12-10  4:05 ` [PATCH RFC v2 12/12] virtio-net: Implement SR-IOV VF Akihiko Odaki
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-10  4:05 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Jason Wang, Sriram Yagnaraman, Keith Busch,
	Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu, Akihiko Odaki

Allow user to attach SR-IOV VF to a virtio-pci PF.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 hw/virtio/virtio-pci.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 205dbf24fb..4f3ec71218 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -2075,6 +2075,12 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
         pci_register_bar(&proxy->pci_dev, proxy->legacy_io_bar_idx,
                          PCI_BASE_ADDRESS_SPACE_IO, &proxy->bar);
     }
+
+    if (pcie_sriov_pf_init_from_user_created_vfs(&proxy->pci_dev,
+                                                 PCI_CONFIG_SPACE_SIZE,
+                                                 errp)) {
+        virtio_add_feature(&vdev->host_features, VIRTIO_F_SR_IOV);
+    }
 }
 
 static void virtio_pci_device_unplugged(DeviceState *d)
@@ -2083,6 +2089,7 @@ static void virtio_pci_device_unplugged(DeviceState *d)
     bool modern = virtio_pci_modern(proxy);
     bool modern_pio = proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY;
 
+    pcie_sriov_pf_exit(&proxy->pci_dev);
     virtio_pci_stop_ioeventfd(proxy);
 
     if (modern) {

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH RFC v2 12/12] virtio-net: Implement SR-IOV VF
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
                   ` (10 preceding siblings ...)
  2023-12-10  4:05 ` [PATCH RFC v2 11/12] virtio-pci: Implement SR-IOV PF Akihiko Odaki
@ 2023-12-10  4:05 ` Akihiko Odaki
  2023-12-11  2:52 ` [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Jason Wang
  2023-12-19  8:37 ` Yui Washizu
  13 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-10  4:05 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Jason Wang, Sriram Yagnaraman, Keith Busch,
	Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu, Akihiko Odaki

A virtio-net device can be added as a SR-IOV VF to another virtio-pci
device that will be the PF.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 hw/virtio/virtio-net-pci.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/virtio/virtio-net-pci.c b/hw/virtio/virtio-net-pci.c
index e03543a70a..dba4987d6e 100644
--- a/hw/virtio/virtio-net-pci.c
+++ b/hw/virtio/virtio-net-pci.c
@@ -75,6 +75,7 @@ static void virtio_net_pci_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+    k->sriov_vf_user_creatable = true;
     set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
     device_class_set_props(dc, virtio_net_properties);
     vpciklass->realize = virtio_net_pci_realize;

-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
                   ` (11 preceding siblings ...)
  2023-12-10  4:05 ` [PATCH RFC v2 12/12] virtio-net: Implement SR-IOV VF Akihiko Odaki
@ 2023-12-11  2:52 ` Jason Wang
  2023-12-11  5:28   ` Akihiko Odaki
  2023-12-19  8:37 ` Yui Washizu
  13 siblings, 1 reply; 23+ messages in thread
From: Jason Wang @ 2023-12-11  2:52 UTC (permalink / raw)
  To: Akihiko Odaki
  Cc: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Sriram Yagnaraman, Keith Busch, Klaus Jensen,
	qemu-devel, qemu-block, Yui Washizu

On Sun, Dec 10, 2023 at 12:06 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>
> Introduction
> ------------
>
> This series is based on the RFC series submitted by Yui Washizu[1].
> See also [2] for the context.
>
> This series enables SR-IOV emulation for virtio-net. It is useful
> to test SR-IOV support on the guest, or to expose several vDPA devices
> in a VM. vDPA devices can also provide L2 switching feature for
> offloading though it is out of scope to allow the guest to configure
> such a feature.
>
> The PF side code resides in virtio-pci. The VF side code resides in
> the PCI common infrastructure, but it is restricted to work only for
> virtio-net-pci because of lack of validation.
>
> User Interface
> --------------
>
> A user can configure a SR-IOV capable virtio-net device by adding
> virtio-net-pci functions to a bus. Below is a command line example:
>   -netdev user,id=n -netdev user,id=o
>   -netdev user,id=p -netdev user,id=q
>   -device pcie-root-port,id=b
>   -device virtio-net-pci,bus=b,addr=0x0.0x3,netdev=q,sriov-pf=f
>   -device virtio-net-pci,bus=b,addr=0x0.0x2,netdev=p,sriov-pf=f
>   -device virtio-net-pci,bus=b,addr=0x0.0x1,netdev=o,sriov-pf=f
>   -device virtio-net-pci,bus=b,addr=0x0.0x0,netdev=n,id=f
>
> The VFs specify the paired PF with "sriov-pf" property. The PF must be
> added after all VFs. It is user's responsibility to ensure that VFs have
> function numbers larger than one of the PF, and the function numbers
> have a consistent stride.

This seems not user friendly. Any reason we can't just allow user to
specify the stride here?

Btw, I vaguely remember qemu allows the params to be accepted as a
list. If this is true, we can accept a list of netdev here?

>
> Keeping VF instances
> --------------------
>
> A problem with SR-IOV emulation is that it needs to hotplug the VFs as
> the guest requests. Previously, this behavior was implemented by
> realizing and unrealizing VFs at runtime. However, this strategy does
> not work well for the proposed virtio-net emulation; in this proposal,
> device options passed in the command line must be maintained as VFs
> are hotplugged, but they are consumed when the machine starts and not
> available after that, which makes realizing VFs at runtime impossible.

Could we store the device options in the PF?

Thanks

>
> As an strategy alternative to runtime realization/unrealization, this
> series proposes to reuse the code to power down PCI Express devices.
> When a PCI Express device is powered down, it will be hidden from the
> guest but will be kept realized. This effectively implements the
> behavior we need for the SR-IOV emulation.
>
> Summary
> -------
>
> Patch [1, 5] refactors the PCI infrastructure code.
> Patch [6, 10] adds user-created SR-IOV VF infrastructure.
> Patch 11 makes virtio-pci work as SR-IOV PF for user-created VFs.
> Patch 12 allows user to create SR-IOV VFs with virtio-net-pci.
>
> [1] https://patchew.org/QEMU/1689731808-3009-1-git-send-email-yui.washidu@gmail.com/
> [2] https://lore.kernel.org/all/5d46f455-f530-4e5e-9ae7-13a2297d4bc5@daynix.com/
>
> Co-developed-by: Yui Washizu <yui.washidu@gmail.com>
> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> ---
> Changes in v2:
> - Changed to keep VF instances.
> - Link to v1: https://lore.kernel.org/r/20231202-sriov-v1-0-32b3570f7bd6@daynix.com
>
> ---
> Akihiko Odaki (12):
>       hw/pci: Initialize PCI multifunction after realization
>       hw/pci: Determine if rombar is explicitly enabled
>       hw/pci: Do not add ROM BAR for SR-IOV VF
>       vfio: Avoid inspecting option QDict for rombar
>       hw/qdev: Remove opts member
>       pcie_sriov: Reuse SR-IOV VF device instances
>       pcie_sriov: Release VFs failed to realize
>       pcie_sriov: Ensure PF and VF are mutually exclusive
>       pcie_sriov: Check PCI Express for SR-IOV PF
>       pcie_sriov: Allow user to create SR-IOV device
>       virtio-pci: Implement SR-IOV PF
>       virtio-net: Implement SR-IOV VF
>
>  docs/pcie_sriov.txt         |   8 +-
>  include/hw/pci/pci.h        |   2 +-
>  include/hw/pci/pci_device.h |  13 +-
>  include/hw/pci/pcie_sriov.h |  25 ++-
>  include/hw/qdev-core.h      |   4 -
>  hw/core/qdev.c              |   1 -
>  hw/net/igb.c                |   3 +-
>  hw/nvme/ctrl.c              |   3 +-
>  hw/pci/pci.c                |  98 +++++++-----
>  hw/pci/pci_host.c           |   4 +-
>  hw/pci/pcie.c               |   4 +-
>  hw/pci/pcie_sriov.c         | 360 +++++++++++++++++++++++++++++++++-----------
>  hw/vfio/pci.c               |   3 +-
>  hw/virtio/virtio-net-pci.c  |   1 +
>  hw/virtio/virtio-pci.c      |   7 +
>  system/qdev-monitor.c       |  12 +-
>  16 files changed, 395 insertions(+), 153 deletions(-)
> ---
> base-commit: 4705fc0c8511d073bee4751c3c974aab2b10a970
> change-id: 20231202-sriov-9402fb262be8
>
> Best regards,
> --
> Akihiko Odaki <akihiko.odaki@daynix.com>
>



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation
  2023-12-11  2:52 ` [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Jason Wang
@ 2023-12-11  5:28   ` Akihiko Odaki
  2023-12-11  7:26     ` Jason Wang
  0 siblings, 1 reply; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-11  5:28 UTC (permalink / raw)
  To: Jason Wang
  Cc: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Sriram Yagnaraman, Keith Busch, Klaus Jensen,
	qemu-devel, qemu-block, Yui Washizu

On 2023/12/11 11:52, Jason Wang wrote:
> On Sun, Dec 10, 2023 at 12:06 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>>
>> Introduction
>> ------------
>>
>> This series is based on the RFC series submitted by Yui Washizu[1].
>> See also [2] for the context.
>>
>> This series enables SR-IOV emulation for virtio-net. It is useful
>> to test SR-IOV support on the guest, or to expose several vDPA devices
>> in a VM. vDPA devices can also provide L2 switching feature for
>> offloading though it is out of scope to allow the guest to configure
>> such a feature.
>>
>> The PF side code resides in virtio-pci. The VF side code resides in
>> the PCI common infrastructure, but it is restricted to work only for
>> virtio-net-pci because of lack of validation.
>>
>> User Interface
>> --------------
>>
>> A user can configure a SR-IOV capable virtio-net device by adding
>> virtio-net-pci functions to a bus. Below is a command line example:
>>    -netdev user,id=n -netdev user,id=o
>>    -netdev user,id=p -netdev user,id=q
>>    -device pcie-root-port,id=b
>>    -device virtio-net-pci,bus=b,addr=0x0.0x3,netdev=q,sriov-pf=f
>>    -device virtio-net-pci,bus=b,addr=0x0.0x2,netdev=p,sriov-pf=f
>>    -device virtio-net-pci,bus=b,addr=0x0.0x1,netdev=o,sriov-pf=f
>>    -device virtio-net-pci,bus=b,addr=0x0.0x0,netdev=n,id=f
>>
>> The VFs specify the paired PF with "sriov-pf" property. The PF must be
>> added after all VFs. It is user's responsibility to ensure that VFs have
>> function numbers larger than one of the PF, and the function numbers
>> have a consistent stride.
> 
> This seems not user friendly. Any reason we can't just allow user to
> specify the stride here?

It should be possible to assign addr automatically without requiring 
user to specify the stride. I'll try that in the next version.

> 
> Btw, I vaguely remember qemu allows the params to be accepted as a
> list. If this is true, we can accept a list of netdev here?

Yes, rocker does that. But the problem is not just about getting 
parameters needed for VFs, which I forgot to mention in the cover letter 
and will explain below.

> 
>>
>> Keeping VF instances
>> --------------------
>>
>> A problem with SR-IOV emulation is that it needs to hotplug the VFs as
>> the guest requests. Previously, this behavior was implemented by
>> realizing and unrealizing VFs at runtime. However, this strategy does
>> not work well for the proposed virtio-net emulation; in this proposal,
>> device options passed in the command line must be maintained as VFs
>> are hotplugged, but they are consumed when the machine starts and not
>> available after that, which makes realizing VFs at runtime impossible.
> 
> Could we store the device options in the PF?

I wrote it's to store the device options, but the problem is actually 
more about realizing VFs at runtime instead of at the initialization time.

Realizing VFs at runtime have two major problems. One is that it delays 
the validations of options; invalid options will be noticed when the 
guest requests to realize VFs. netdevs also warn that they are not used 
at initialization time, not knowing that they will be used by VFs later. 
References to other QEMU objects in the option may also die before VFs 
are realized.

The other problem is that QEMU cannot interact with the unrealized VFs. 
For example, if you type "device_add virtio-net-pci,id=vf,sriov-pf=pf" 
in HMP, you will expect "device_del vf" works, but it's hard to 
implement such behaviors with unrealized VFs.

I was first going to compromise and allow such quirky behaviors, but I 
realized such a compromise is unnecessary if we reuse the PCI power down 
logic so I wrote v2.

Regards,
Akihiko Odaki


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation
  2023-12-11  5:28   ` Akihiko Odaki
@ 2023-12-11  7:26     ` Jason Wang
  2023-12-11  8:29       ` Akihiko Odaki
  0 siblings, 1 reply; 23+ messages in thread
From: Jason Wang @ 2023-12-11  7:26 UTC (permalink / raw)
  To: Akihiko Odaki
  Cc: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Sriram Yagnaraman, Keith Busch, Klaus Jensen,
	qemu-devel, qemu-block, Yui Washizu

On Mon, Dec 11, 2023 at 1:30 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>
> On 2023/12/11 11:52, Jason Wang wrote:
> > On Sun, Dec 10, 2023 at 12:06 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
> >>
> >> Introduction
> >> ------------
> >>
> >> This series is based on the RFC series submitted by Yui Washizu[1].
> >> See also [2] for the context.
> >>
> >> This series enables SR-IOV emulation for virtio-net. It is useful
> >> to test SR-IOV support on the guest, or to expose several vDPA devices
> >> in a VM. vDPA devices can also provide L2 switching feature for
> >> offloading though it is out of scope to allow the guest to configure
> >> such a feature.
> >>
> >> The PF side code resides in virtio-pci. The VF side code resides in
> >> the PCI common infrastructure, but it is restricted to work only for
> >> virtio-net-pci because of lack of validation.
> >>
> >> User Interface
> >> --------------
> >>
> >> A user can configure a SR-IOV capable virtio-net device by adding
> >> virtio-net-pci functions to a bus. Below is a command line example:
> >>    -netdev user,id=n -netdev user,id=o
> >>    -netdev user,id=p -netdev user,id=q
> >>    -device pcie-root-port,id=b
> >>    -device virtio-net-pci,bus=b,addr=0x0.0x3,netdev=q,sriov-pf=f
> >>    -device virtio-net-pci,bus=b,addr=0x0.0x2,netdev=p,sriov-pf=f
> >>    -device virtio-net-pci,bus=b,addr=0x0.0x1,netdev=o,sriov-pf=f
> >>    -device virtio-net-pci,bus=b,addr=0x0.0x0,netdev=n,id=f
> >>
> >> The VFs specify the paired PF with "sriov-pf" property. The PF must be
> >> added after all VFs. It is user's responsibility to ensure that VFs have
> >> function numbers larger than one of the PF, and the function numbers
> >> have a consistent stride.
> >
> > This seems not user friendly. Any reason we can't just allow user to
> > specify the stride here?
>
> It should be possible to assign addr automatically without requiring
> user to specify the stride. I'll try that in the next version.
>
> >
> > Btw, I vaguely remember qemu allows the params to be accepted as a
> > list. If this is true, we can accept a list of netdev here?
>
> Yes, rocker does that. But the problem is not just about getting
> parameters needed for VFs, which I forgot to mention in the cover letter
> and will explain below.
>
> >
> >>
> >> Keeping VF instances
> >> --------------------
> >>
> >> A problem with SR-IOV emulation is that it needs to hotplug the VFs as
> >> the guest requests. Previously, this behavior was implemented by
> >> realizing and unrealizing VFs at runtime. However, this strategy does
> >> not work well for the proposed virtio-net emulation; in this proposal,
> >> device options passed in the command line must be maintained as VFs
> >> are hotplugged, but they are consumed when the machine starts and not
> >> available after that, which makes realizing VFs at runtime impossible.
> >
> > Could we store the device options in the PF?
>
> I wrote it's to store the device options, but the problem is actually
> more about realizing VFs at runtime instead of at the initialization time.
>
> Realizing VFs at runtime have two major problems. One is that it delays
> the validations of options; invalid options will be noticed when the
> guest requests to realize VFs.

If PCI spec allows the failure when creating VF, then it should not be
a problem.

> netdevs also warn that they are not used
> at initialization time, not knowing that they will be used by VFs later.

We could invent things to calm down this false positive.

> References to other QEMU objects in the option may also die before VFs
> are realized.

Is there any other thing than netdev we need to consider?

>
> The other problem is that QEMU cannot interact with the unrealized VFs.
> For example, if you type "device_add virtio-net-pci,id=vf,sriov-pf=pf"
> in HMP, you will expect "device_del vf" works, but it's hard to
> implement such behaviors with unrealized VFs.

I think hotplug can only be done at PF level if we do that.

>
> I was first going to compromise and allow such quirky behaviors, but I
> realized such a compromise is unnecessary if we reuse the PCI power down
> logic so I wrote v2.

Haven't checked the code, but anything related to the PM here?

Thanks

>
> Regards,
> Akihiko Odaki
>



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation
  2023-12-11  7:26     ` Jason Wang
@ 2023-12-11  8:29       ` Akihiko Odaki
  2023-12-12  4:12         ` Jason Wang
  0 siblings, 1 reply; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-11  8:29 UTC (permalink / raw)
  To: Jason Wang
  Cc: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Sriram Yagnaraman, Keith Busch, Klaus Jensen,
	qemu-devel, qemu-block, Yui Washizu

On 2023/12/11 16:26, Jason Wang wrote:
> On Mon, Dec 11, 2023 at 1:30 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>>
>> On 2023/12/11 11:52, Jason Wang wrote:
>>> On Sun, Dec 10, 2023 at 12:06 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>>>>
>>>> Introduction
>>>> ------------
>>>>
>>>> This series is based on the RFC series submitted by Yui Washizu[1].
>>>> See also [2] for the context.
>>>>
>>>> This series enables SR-IOV emulation for virtio-net. It is useful
>>>> to test SR-IOV support on the guest, or to expose several vDPA devices
>>>> in a VM. vDPA devices can also provide L2 switching feature for
>>>> offloading though it is out of scope to allow the guest to configure
>>>> such a feature.
>>>>
>>>> The PF side code resides in virtio-pci. The VF side code resides in
>>>> the PCI common infrastructure, but it is restricted to work only for
>>>> virtio-net-pci because of lack of validation.
>>>>
>>>> User Interface
>>>> --------------
>>>>
>>>> A user can configure a SR-IOV capable virtio-net device by adding
>>>> virtio-net-pci functions to a bus. Below is a command line example:
>>>>     -netdev user,id=n -netdev user,id=o
>>>>     -netdev user,id=p -netdev user,id=q
>>>>     -device pcie-root-port,id=b
>>>>     -device virtio-net-pci,bus=b,addr=0x0.0x3,netdev=q,sriov-pf=f
>>>>     -device virtio-net-pci,bus=b,addr=0x0.0x2,netdev=p,sriov-pf=f
>>>>     -device virtio-net-pci,bus=b,addr=0x0.0x1,netdev=o,sriov-pf=f
>>>>     -device virtio-net-pci,bus=b,addr=0x0.0x0,netdev=n,id=f
>>>>
>>>> The VFs specify the paired PF with "sriov-pf" property. The PF must be
>>>> added after all VFs. It is user's responsibility to ensure that VFs have
>>>> function numbers larger than one of the PF, and the function numbers
>>>> have a consistent stride.
>>>
>>> This seems not user friendly. Any reason we can't just allow user to
>>> specify the stride here?
>>
>> It should be possible to assign addr automatically without requiring
>> user to specify the stride. I'll try that in the next version.
>>
>>>
>>> Btw, I vaguely remember qemu allows the params to be accepted as a
>>> list. If this is true, we can accept a list of netdev here?
>>
>> Yes, rocker does that. But the problem is not just about getting
>> parameters needed for VFs, which I forgot to mention in the cover letter
>> and will explain below.
>>
>>>
>>>>
>>>> Keeping VF instances
>>>> --------------------
>>>>
>>>> A problem with SR-IOV emulation is that it needs to hotplug the VFs as
>>>> the guest requests. Previously, this behavior was implemented by
>>>> realizing and unrealizing VFs at runtime. However, this strategy does
>>>> not work well for the proposed virtio-net emulation; in this proposal,
>>>> device options passed in the command line must be maintained as VFs
>>>> are hotplugged, but they are consumed when the machine starts and not
>>>> available after that, which makes realizing VFs at runtime impossible.
>>>
>>> Could we store the device options in the PF?
>>
>> I wrote it's to store the device options, but the problem is actually
>> more about realizing VFs at runtime instead of at the initialization time.
>>
>> Realizing VFs at runtime have two major problems. One is that it delays
>> the validations of options; invalid options will be noticed when the
>> guest requests to realize VFs.
> 
> If PCI spec allows the failure when creating VF, then it should not be
> a problem.

I doubt the spec cares such a failure at all. VF enablement should 
always work for a real hardware. It's neither user-friendly to tell 
configuration errors at runtime.

> 
>> netdevs also warn that they are not used
>> at initialization time, not knowing that they will be used by VFs later.
> 
> We could invent things to calm down this false positive.
> 
>> References to other QEMU objects in the option may also die before VFs
>> are realized.
> 
> Is there any other thing than netdev we need to consider?

You will also want to set a distinct mac for each VF. Other properties 
does not matter much in my opinion.

> 
>>
>> The other problem is that QEMU cannot interact with the unrealized VFs.
>> For example, if you type "device_add virtio-net-pci,id=vf,sriov-pf=pf"
>> in HMP, you will expect "device_del vf" works, but it's hard to
>> implement such behaviors with unrealized VFs.
> 
> I think hotplug can only be done at PF level if we do that.

Assuming you mean to let netdev and mac accept arrays, yes.

> 
>>
>> I was first going to compromise and allow such quirky behaviors, but I
>> realized such a compromise is unnecessary if we reuse the PCI power down
>> logic so I wrote v2.
> 
> Haven't checked the code, but anything related to the PM here?

You mean power management? We don't have to care about PCI power down 
for VFs because powering down a SR-IOV PCI device will reset it and thus 
disable its VFs.

Regards,
Akihiko Odaki


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation
  2023-12-11  8:29       ` Akihiko Odaki
@ 2023-12-12  4:12         ` Jason Wang
  2023-12-12  9:34           ` Akihiko Odaki
  0 siblings, 1 reply; 23+ messages in thread
From: Jason Wang @ 2023-12-12  4:12 UTC (permalink / raw)
  To: Akihiko Odaki
  Cc: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Sriram Yagnaraman, Keith Busch, Klaus Jensen,
	qemu-devel, qemu-block, Yui Washizu

On Mon, Dec 11, 2023 at 4:29 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>
> On 2023/12/11 16:26, Jason Wang wrote:
> > On Mon, Dec 11, 2023 at 1:30 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
> >>
> >> On 2023/12/11 11:52, Jason Wang wrote:
> >>> On Sun, Dec 10, 2023 at 12:06 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
> >>>>
> >>>> Introduction
> >>>> ------------
> >>>>
> >>>> This series is based on the RFC series submitted by Yui Washizu[1].
> >>>> See also [2] for the context.
> >>>>
> >>>> This series enables SR-IOV emulation for virtio-net. It is useful
> >>>> to test SR-IOV support on the guest, or to expose several vDPA devices
> >>>> in a VM. vDPA devices can also provide L2 switching feature for
> >>>> offloading though it is out of scope to allow the guest to configure
> >>>> such a feature.
> >>>>
> >>>> The PF side code resides in virtio-pci. The VF side code resides in
> >>>> the PCI common infrastructure, but it is restricted to work only for
> >>>> virtio-net-pci because of lack of validation.
> >>>>
> >>>> User Interface
> >>>> --------------
> >>>>
> >>>> A user can configure a SR-IOV capable virtio-net device by adding
> >>>> virtio-net-pci functions to a bus. Below is a command line example:
> >>>>     -netdev user,id=n -netdev user,id=o
> >>>>     -netdev user,id=p -netdev user,id=q
> >>>>     -device pcie-root-port,id=b
> >>>>     -device virtio-net-pci,bus=b,addr=0x0.0x3,netdev=q,sriov-pf=f
> >>>>     -device virtio-net-pci,bus=b,addr=0x0.0x2,netdev=p,sriov-pf=f
> >>>>     -device virtio-net-pci,bus=b,addr=0x0.0x1,netdev=o,sriov-pf=f
> >>>>     -device virtio-net-pci,bus=b,addr=0x0.0x0,netdev=n,id=f
> >>>>
> >>>> The VFs specify the paired PF with "sriov-pf" property. The PF must be
> >>>> added after all VFs. It is user's responsibility to ensure that VFs have
> >>>> function numbers larger than one of the PF, and the function numbers
> >>>> have a consistent stride.
> >>>
> >>> This seems not user friendly. Any reason we can't just allow user to
> >>> specify the stride here?
> >>
> >> It should be possible to assign addr automatically without requiring
> >> user to specify the stride. I'll try that in the next version.
> >>
> >>>
> >>> Btw, I vaguely remember qemu allows the params to be accepted as a
> >>> list. If this is true, we can accept a list of netdev here?
> >>
> >> Yes, rocker does that. But the problem is not just about getting
> >> parameters needed for VFs, which I forgot to mention in the cover letter
> >> and will explain below.
> >>
> >>>
> >>>>
> >>>> Keeping VF instances
> >>>> --------------------
> >>>>
> >>>> A problem with SR-IOV emulation is that it needs to hotplug the VFs as
> >>>> the guest requests. Previously, this behavior was implemented by
> >>>> realizing and unrealizing VFs at runtime. However, this strategy does
> >>>> not work well for the proposed virtio-net emulation; in this proposal,
> >>>> device options passed in the command line must be maintained as VFs
> >>>> are hotplugged, but they are consumed when the machine starts and not
> >>>> available after that, which makes realizing VFs at runtime impossible.
> >>>
> >>> Could we store the device options in the PF?
> >>
> >> I wrote it's to store the device options, but the problem is actually
> >> more about realizing VFs at runtime instead of at the initialization time.
> >>
> >> Realizing VFs at runtime have two major problems. One is that it delays
> >> the validations of options; invalid options will be noticed when the
> >> guest requests to realize VFs.
> >
> > If PCI spec allows the failure when creating VF, then it should not be
> > a problem.
>
> I doubt the spec cares such a failure at all. VF enablement should
> always work for a real hardware. It's neither user-friendly to tell
> configuration errors at runtime.

I'm not sure which options we should care about? Did you mean netdev
options or the virtio-net specific ones?

If VF stick to the same options as PF (except for the SRIOV), it
should be validated during the PF initialization.

>
> >
> >> netdevs also warn that they are not used
> >> at initialization time, not knowing that they will be used by VFs later.
> >
> > We could invent things to calm down this false positive.
> >
> >> References to other QEMU objects in the option may also die before VFs
> >> are realized.
> >
> > Is there any other thing than netdev we need to consider?
>
> You will also want to set a distinct mac for each VF. Other properties
> does not matter much in my opinion.

Qemu doesn't check mac duplication now. So it's up to the mgmt layer.

>
> >
> >>
> >> The other problem is that QEMU cannot interact with the unrealized VFs.
> >> For example, if you type "device_add virtio-net-pci,id=vf,sriov-pf=pf"
> >> in HMP, you will expect "device_del vf" works, but it's hard to
> >> implement such behaviors with unrealized VFs.
> >
> > I think hotplug can only be done at PF level if we do that.
>
> Assuming you mean to let netdev and mac accept arrays, yes.
>
> >
> >>
> >> I was first going to compromise and allow such quirky behaviors, but I
> >> realized such a compromise is unnecessary if we reuse the PCI power down
> >> logic so I wrote v2.
> >
> > Haven't checked the code, but anything related to the PM here?
>
> You mean power management? We don't have to care about PCI power down
> for VFs because powering down a SR-IOV PCI device will reset it and thus
> disable its VFs.

Ok.

Thanks

>
> Regards,
> Akihiko Odaki
>



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation
  2023-12-12  4:12         ` Jason Wang
@ 2023-12-12  9:34           ` Akihiko Odaki
  0 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-12  9:34 UTC (permalink / raw)
  To: Jason Wang
  Cc: Michael S. Tsirkin, Marcel Apfelbaum, Alex Williamson,
	Cédric Le Goater, Paolo Bonzini, Daniel P. Berrangé,
	Eduardo Habkost, Sriram Yagnaraman, Keith Busch, Klaus Jensen,
	qemu-devel, qemu-block, Yui Washizu

On 2023/12/12 13:12, Jason Wang wrote:
> On Mon, Dec 11, 2023 at 4:29 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>>
>> On 2023/12/11 16:26, Jason Wang wrote:
>>> On Mon, Dec 11, 2023 at 1:30 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>>>>
>>>> On 2023/12/11 11:52, Jason Wang wrote:
>>>>> On Sun, Dec 10, 2023 at 12:06 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>>>>>>
>>>>>> Introduction
>>>>>> ------------
>>>>>>
>>>>>> This series is based on the RFC series submitted by Yui Washizu[1].
>>>>>> See also [2] for the context.
>>>>>>
>>>>>> This series enables SR-IOV emulation for virtio-net. It is useful
>>>>>> to test SR-IOV support on the guest, or to expose several vDPA devices
>>>>>> in a VM. vDPA devices can also provide L2 switching feature for
>>>>>> offloading though it is out of scope to allow the guest to configure
>>>>>> such a feature.
>>>>>>
>>>>>> The PF side code resides in virtio-pci. The VF side code resides in
>>>>>> the PCI common infrastructure, but it is restricted to work only for
>>>>>> virtio-net-pci because of lack of validation.
>>>>>>
>>>>>> User Interface
>>>>>> --------------
>>>>>>
>>>>>> A user can configure a SR-IOV capable virtio-net device by adding
>>>>>> virtio-net-pci functions to a bus. Below is a command line example:
>>>>>>      -netdev user,id=n -netdev user,id=o
>>>>>>      -netdev user,id=p -netdev user,id=q
>>>>>>      -device pcie-root-port,id=b
>>>>>>      -device virtio-net-pci,bus=b,addr=0x0.0x3,netdev=q,sriov-pf=f
>>>>>>      -device virtio-net-pci,bus=b,addr=0x0.0x2,netdev=p,sriov-pf=f
>>>>>>      -device virtio-net-pci,bus=b,addr=0x0.0x1,netdev=o,sriov-pf=f
>>>>>>      -device virtio-net-pci,bus=b,addr=0x0.0x0,netdev=n,id=f
>>>>>>
>>>>>> The VFs specify the paired PF with "sriov-pf" property. The PF must be
>>>>>> added after all VFs. It is user's responsibility to ensure that VFs have
>>>>>> function numbers larger than one of the PF, and the function numbers
>>>>>> have a consistent stride.
>>>>>
>>>>> This seems not user friendly. Any reason we can't just allow user to
>>>>> specify the stride here?
>>>>
>>>> It should be possible to assign addr automatically without requiring
>>>> user to specify the stride. I'll try that in the next version.
>>>>
>>>>>
>>>>> Btw, I vaguely remember qemu allows the params to be accepted as a
>>>>> list. If this is true, we can accept a list of netdev here?
>>>>
>>>> Yes, rocker does that. But the problem is not just about getting
>>>> parameters needed for VFs, which I forgot to mention in the cover letter
>>>> and will explain below.
>>>>
>>>>>
>>>>>>
>>>>>> Keeping VF instances
>>>>>> --------------------
>>>>>>
>>>>>> A problem with SR-IOV emulation is that it needs to hotplug the VFs as
>>>>>> the guest requests. Previously, this behavior was implemented by
>>>>>> realizing and unrealizing VFs at runtime. However, this strategy does
>>>>>> not work well for the proposed virtio-net emulation; in this proposal,
>>>>>> device options passed in the command line must be maintained as VFs
>>>>>> are hotplugged, but they are consumed when the machine starts and not
>>>>>> available after that, which makes realizing VFs at runtime impossible.
>>>>>
>>>>> Could we store the device options in the PF?
>>>>
>>>> I wrote it's to store the device options, but the problem is actually
>>>> more about realizing VFs at runtime instead of at the initialization time.
>>>>
>>>> Realizing VFs at runtime have two major problems. One is that it delays
>>>> the validations of options; invalid options will be noticed when the
>>>> guest requests to realize VFs.
>>>
>>> If PCI spec allows the failure when creating VF, then it should not be
>>> a problem.
>>
>> I doubt the spec cares such a failure at all. VF enablement should
>> always work for a real hardware. It's neither user-friendly to tell
>> configuration errors at runtime.
> 
> I'm not sure which options we should care about? Did you mean netdev
> options or the virtio-net specific ones?
> 
> If VF stick to the same options as PF (except for the SRIOV), it
> should be validated during the PF initialization.

I'm aware that it's necessary to validate netdev options and PCI 
function numbers (a.k.a. addr/devfn). I'm not sure if the other options 
may result in an invalid VF configuration.

That said, I think it's better to let the VF realization code validate 
the configuration at PF realization - it's less error-prone and 
potentially requires less code. It also benefits existing SR-IOV devices 
(igb and nvme) so I'm going to push that change forward whether it will 
be needed for virtio-net SR-IOV emulation.

Assuming the change to realize VFs early is going to happen for igb and 
nvme, most of the changes *only* needed by virtio-net SR-IOV emulation 
is done by:
patch 10 "pcie_sriov: Allow user to create SR-IOV device".

> 
>>
>>>
>>>> netdevs also warn that they are not used
>>>> at initialization time, not knowing that they will be used by VFs later.
>>>
>>> We could invent things to calm down this false positive.
>>>
>>>> References to other QEMU objects in the option may also die before VFs
>>>> are realized.
>>>
>>> Is there any other thing than netdev we need to consider?
>>
>> You will also want to set a distinct mac for each VF. Other properties
>> does not matter much in my opinion.
> 
> Qemu doesn't check mac duplication now. So it's up to the mgmt layer.

Right. mac is not important; it's just nice to have.

Regards,
Akihiko Odaki


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC v2 01/12] hw/pci: Initialize PCI multifunction after realization
  2023-12-10  4:05 ` [PATCH RFC v2 01/12] hw/pci: Initialize PCI multifunction after realization Akihiko Odaki
@ 2023-12-12  9:59   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 23+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-12-12  9:59 UTC (permalink / raw)
  To: Akihiko Odaki, Michael S. Tsirkin, Marcel Apfelbaum,
	Alex Williamson, Cédric Le Goater, Paolo Bonzini,
	Daniel P. Berrangé, Eduardo Habkost, Jason Wang,
	Sriram Yagnaraman, Keith Busch, Klaus Jensen
  Cc: qemu-devel, qemu-block, Yui Washizu

On 10/12/23 05:05, Akihiko Odaki wrote:
> The device realization code may enable PCI multifunction for SR-IOV.
> 
> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> ---
>   hw/pci/pci.c | 17 +++++++++--------
>   1 file changed, 9 insertions(+), 8 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC v2 05/12] hw/qdev: Remove opts member
  2023-12-10  4:05 ` [PATCH RFC v2 05/12] hw/qdev: Remove opts member Akihiko Odaki
@ 2023-12-12 10:04   ` Philippe Mathieu-Daudé
  2023-12-12 11:15     ` Akihiko Odaki
  0 siblings, 1 reply; 23+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-12-12 10:04 UTC (permalink / raw)
  To: Akihiko Odaki, Michael S. Tsirkin, Marcel Apfelbaum,
	Alex Williamson, Cédric Le Goater, Paolo Bonzini,
	Daniel P. Berrangé, Eduardo Habkost, Jason Wang,
	Sriram Yagnaraman, Keith Busch, Klaus Jensen, Kevin Wolf
  Cc: qemu-devel, qemu-block, Yui Washizu

On 10/12/23 05:05, Akihiko Odaki wrote:
> It is no longer used.

Since commit f3558b1b76 ("qdev: Base object creation on QDict rather
than QemuOpts")?

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> ---
>   include/hw/qdev-core.h |  4 ----
>   hw/core/qdev.c         |  1 -
>   system/qdev-monitor.c  | 12 +++++++-----
>   3 files changed, 7 insertions(+), 10 deletions(-)
> 
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index 151d968238..6befbca311 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -237,10 +237,6 @@ struct DeviceState {
>        * @pending_deleted_expires_ms: optional timeout for deletion events
>        */
>       int64_t pending_deleted_expires_ms;
> -    /**
> -     * @opts: QDict of options for the device
> -     */
> -    QDict *opts;
>       /**
>        * @hotplugged: was device added after PHASE_MACHINE_READY?
>        */
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index 43d863b0c5..c98691a90d 100644
> --- a/hw/core/qdev.c
> +++ b/hw/core/qdev.c
> @@ -706,7 +706,6 @@ static void device_finalize(Object *obj)
>           dev->canonical_path = NULL;
>       }
>   
> -    qobject_unref(dev->opts);
>       g_free(dev->id);
>   }
>   
> diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
> index a13db763e5..71c00f62ee 100644
> --- a/system/qdev-monitor.c
> +++ b/system/qdev-monitor.c
> @@ -625,6 +625,7 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
>       char *id;
>       DeviceState *dev = NULL;
>       BusState *bus = NULL;
> +    QDict *properties;
>   
>       driver = qdict_get_try_str(opts, "driver");
>       if (!driver) {
> @@ -705,13 +706,14 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
>       }
>   
>       /* set properties */
> -    dev->opts = qdict_clone_shallow(opts);
> -    qdict_del(dev->opts, "driver");
> -    qdict_del(dev->opts, "bus");
> -    qdict_del(dev->opts, "id");
> +    properties = qdict_clone_shallow(opts);
> +    qdict_del(properties, "driver");
> +    qdict_del(properties, "bus");
> +    qdict_del(properties, "id");
>   
> -    object_set_properties_from_keyval(&dev->parent_obj, dev->opts, from_json,
> +    object_set_properties_from_keyval(&dev->parent_obj, properties, from_json,
>                                         errp);
> +    qobject_unref(properties);
>       if (*errp) {
>           goto err_del_dev;
>       }
> 



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC v2 05/12] hw/qdev: Remove opts member
  2023-12-12 10:04   ` Philippe Mathieu-Daudé
@ 2023-12-12 11:15     ` Akihiko Odaki
  0 siblings, 0 replies; 23+ messages in thread
From: Akihiko Odaki @ 2023-12-12 11:15 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, Michael S. Tsirkin, Marcel Apfelbaum,
	Alex Williamson, Cédric Le Goater, Paolo Bonzini,
	Daniel P. Berrangé, Eduardo Habkost, Jason Wang,
	Sriram Yagnaraman, Keith Busch, Klaus Jensen, Kevin Wolf
  Cc: qemu-devel, qemu-block, Yui Washizu

On 2023/12/12 19:04, Philippe Mathieu-Daudé wrote:
> On 10/12/23 05:05, Akihiko Odaki wrote:
>> It is no longer used.
> 
> Since commit f3558b1b76 ("qdev: Base object creation on QDict rather
> than QemuOpts")?

One usage still remains and it will be removed with an earlier patch, 
"[PATCH RFC v2 04/12] vfio: Avoid inspecting option QDict for rombar".


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation
  2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
                   ` (12 preceding siblings ...)
  2023-12-11  2:52 ` [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Jason Wang
@ 2023-12-19  8:37 ` Yui Washizu
  13 siblings, 0 replies; 23+ messages in thread
From: Yui Washizu @ 2023-12-19  8:37 UTC (permalink / raw)
  To: Akihiko Odaki, Michael S. Tsirkin, Marcel Apfelbaum,
	Alex Williamson, Cédric Le Goater, Paolo Bonzini,
	Daniel P. Berrangé, Eduardo Habkost, Jason Wang,
	Sriram Yagnaraman, Keith Busch, Klaus Jensen
  Cc: qemu-devel, qemu-block


On 2023/12/10 13:05, Akihiko Odaki wrote:
> Introduction
> ------------
>
> This series is based on the RFC series submitted by Yui Washizu[1].
> See also [2] for the context.
>
> This series enables SR-IOV emulation for virtio-net. It is useful
> to test SR-IOV support on the guest, or to expose several vDPA devices
> in a VM. vDPA devices can also provide L2 switching feature for
> offloading though it is out of scope to allow the guest to configure
> such a feature.
>
> The PF side code resides in virtio-pci. The VF side code resides in
> the PCI common infrastructure, but it is restricted to work only for
> virtio-net-pci because of lack of validation.
>
> User Interface
> --------------
>
> A user can configure a SR-IOV capable virtio-net device by adding
> virtio-net-pci functions to a bus. Below is a command line example:
>    -netdev user,id=n -netdev user,id=o
>    -netdev user,id=p -netdev user,id=q
>    -device pcie-root-port,id=b
>    -device virtio-net-pci,bus=b,addr=0x0.0x3,netdev=q,sriov-pf=f
>    -device virtio-net-pci,bus=b,addr=0x0.0x2,netdev=p,sriov-pf=f
>    -device virtio-net-pci,bus=b,addr=0x0.0x1,netdev=o,sriov-pf=f
>    -device virtio-net-pci,bus=b,addr=0x0.0x0,netdev=n,id=f
>
> The VFs specify the paired PF with "sriov-pf" property. The PF must be
> added after all VFs. It is user's responsibility to ensure that VFs have
> function numbers larger than one of the PF, and the function numbers
> have a consistent stride.


I attempted to create a VF on a VM using your patches and
tested the creation of one VF on the VM.
I initiated QEMU with the following commands:
-netdev tap,id=n,vhost=on -netdev tap,id=o,vhost=on
-device pcie-root-port,id=b
-device virtio-net-pci,bus=b,addr=0x0.0x1,netdev=o,sriov-pf=f
-device virtio-net-pci,bus=b,addr=0x0.0x0,netdev=n,id=f

However, when creating just one VF,
QEMU crashed at hw/pci/pci.c:1443.
---
uint32_t vf_num = (d->devfn - (pf->devfn + vf_offset)) / vf_stride;
---
The error output was:
'CPU 1/KVM trap divide error ip:... sp:... error:0 in kvm-qemu.'

Interestingly, when creating two VFs, QEMU did not crash.

>
> Keeping VF instances
> --------------------
>
> A problem with SR-IOV emulation is that it needs to hotplug the VFs as
> the guest requests. Previously, this behavior was implemented by
> realizing and unrealizing VFs at runtime. However, this strategy does
> not work well for the proposed virtio-net emulation; in this proposal,
> device options passed in the command line must be maintained as VFs
> are hotplugged, but they are consumed when the machine starts and not
> available after that, which makes realizing VFs at runtime impossible.
>
> As an strategy alternative to runtime realization/unrealization, this
> series proposes to reuse the code to power down PCI Express devices.
> When a PCI Express device is powered down, it will be hidden from the
> guest but will be kept realized. This effectively implements the
> behavior we need for the SR-IOV emulation.
>
> Summary
> -------
>
> Patch [1, 5] refactors the PCI infrastructure code.
> Patch [6, 10] adds user-created SR-IOV VF infrastructure.
> Patch 11 makes virtio-pci work as SR-IOV PF for user-created VFs.
> Patch 12 allows user to create SR-IOV VFs with virtio-net-pci.
>
> [1] https://patchew.org/QEMU/1689731808-3009-1-git-send-email-yui.washidu@gmail.com/
> [2] https://lore.kernel.org/all/5d46f455-f530-4e5e-9ae7-13a2297d4bc5@daynix.com/
>
> Co-developed-by: Yui Washizu <yui.washidu@gmail.com>
> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> ---
> Changes in v2:
> - Changed to keep VF instances.
> - Link to v1: https://lore.kernel.org/r/20231202-sriov-v1-0-32b3570f7bd6@daynix.com
>
> ---
> Akihiko Odaki (12):
>        hw/pci: Initialize PCI multifunction after realization
>        hw/pci: Determine if rombar is explicitly enabled
>        hw/pci: Do not add ROM BAR for SR-IOV VF
>        vfio: Avoid inspecting option QDict for rombar
>        hw/qdev: Remove opts member
>        pcie_sriov: Reuse SR-IOV VF device instances
>        pcie_sriov: Release VFs failed to realize
>        pcie_sriov: Ensure PF and VF are mutually exclusive
>        pcie_sriov: Check PCI Express for SR-IOV PF
>        pcie_sriov: Allow user to create SR-IOV device
>        virtio-pci: Implement SR-IOV PF
>        virtio-net: Implement SR-IOV VF
>
>   docs/pcie_sriov.txt         |   8 +-
>   include/hw/pci/pci.h        |   2 +-
>   include/hw/pci/pci_device.h |  13 +-
>   include/hw/pci/pcie_sriov.h |  25 ++-
>   include/hw/qdev-core.h      |   4 -
>   hw/core/qdev.c              |   1 -
>   hw/net/igb.c                |   3 +-
>   hw/nvme/ctrl.c              |   3 +-
>   hw/pci/pci.c                |  98 +++++++-----
>   hw/pci/pci_host.c           |   4 +-
>   hw/pci/pcie.c               |   4 +-
>   hw/pci/pcie_sriov.c         | 360 +++++++++++++++++++++++++++++++++-----------
>   hw/vfio/pci.c               |   3 +-
>   hw/virtio/virtio-net-pci.c  |   1 +
>   hw/virtio/virtio-pci.c      |   7 +
>   system/qdev-monitor.c       |  12 +-
>   16 files changed, 395 insertions(+), 153 deletions(-)
> ---
> base-commit: 4705fc0c8511d073bee4751c3c974aab2b10a970
> change-id: 20231202-sriov-9402fb262be8
>
> Best regards,


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2023-12-19  8:38 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-10  4:05 [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Akihiko Odaki
2023-12-10  4:05 ` [PATCH RFC v2 01/12] hw/pci: Initialize PCI multifunction after realization Akihiko Odaki
2023-12-12  9:59   ` Philippe Mathieu-Daudé
2023-12-10  4:05 ` [PATCH RFC v2 02/12] hw/pci: Determine if rombar is explicitly enabled Akihiko Odaki
2023-12-10  4:05 ` [PATCH RFC v2 03/12] hw/pci: Do not add ROM BAR for SR-IOV VF Akihiko Odaki
2023-12-10  4:05 ` [PATCH RFC v2 04/12] vfio: Avoid inspecting option QDict for rombar Akihiko Odaki
2023-12-10  4:05 ` [PATCH RFC v2 05/12] hw/qdev: Remove opts member Akihiko Odaki
2023-12-12 10:04   ` Philippe Mathieu-Daudé
2023-12-12 11:15     ` Akihiko Odaki
2023-12-10  4:05 ` [PATCH RFC v2 06/12] pcie_sriov: Reuse SR-IOV VF device instances Akihiko Odaki
2023-12-10  4:05 ` [PATCH RFC v2 07/12] pcie_sriov: Release VFs failed to realize Akihiko Odaki
2023-12-10  4:05 ` [PATCH RFC v2 08/12] pcie_sriov: Ensure PF and VF are mutually exclusive Akihiko Odaki
2023-12-10  4:05 ` [PATCH RFC v2 09/12] pcie_sriov: Check PCI Express for SR-IOV PF Akihiko Odaki
2023-12-10  4:05 ` [PATCH RFC v2 10/12] pcie_sriov: Allow user to create SR-IOV device Akihiko Odaki
2023-12-10  4:05 ` [PATCH RFC v2 11/12] virtio-pci: Implement SR-IOV PF Akihiko Odaki
2023-12-10  4:05 ` [PATCH RFC v2 12/12] virtio-net: Implement SR-IOV VF Akihiko Odaki
2023-12-11  2:52 ` [PATCH RFC v2 00/12] virtio-net: add support for SR-IOV emulation Jason Wang
2023-12-11  5:28   ` Akihiko Odaki
2023-12-11  7:26     ` Jason Wang
2023-12-11  8:29       ` Akihiko Odaki
2023-12-12  4:12         ` Jason Wang
2023-12-12  9:34           ` Akihiko Odaki
2023-12-19  8:37 ` Yui Washizu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).