[PATCH 08/14] vfio: add vfio-pci-base class

John Levon posted 14 patches 7 months, 1 week ago
There is a newer version of this series
[PATCH 08/14] vfio: add vfio-pci-base class
Posted by John Levon 7 months, 1 week ago
Split out parts of TYPE_VFIO_PCI into a base TYPE_VFIO_PCI_BASE. The
base type contains properties generic to all vfio-pci implementations
(although we have not yet introduced another subclass).

Note that currently there is no need for additional data for
TYPE_VFIO_PCI, so it shares the same C struct type as
TYPE_VFIO_PCI_BASE, VFIOPCIDevice.

Originally-by: John Johnson <john.g.johnson@oracle.com>
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
Signed-off-by: John Levon <john.levon@nutanix.com>
---
 hw/vfio/device.c |   2 +-
 hw/vfio/pci.c    | 266 ++++++++++++++++++++++++++---------------------
 hw/vfio/pci.h    |  12 ++-
 3 files changed, 156 insertions(+), 124 deletions(-)

diff --git a/hw/vfio/device.c b/hw/vfio/device.c
index f74b9c25ea..b9473878fc 100644
--- a/hw/vfio/device.c
+++ b/hw/vfio/device.c
@@ -361,7 +361,7 @@ bool vfio_device_hiod_realize(VFIODevice *vbasedev, Error **errp)
 VFIODevice *vfio_get_vfio_device(Object *obj)
 {
     if (object_dynamic_cast(obj, TYPE_VFIO_PCI)) {
-        return &VFIO_PCI(obj)->vbasedev;
+        return &VFIO_PCI_BASE(obj)->vbasedev;
     } else {
         return NULL;
     }
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 81bf0dab28..090b2f2ef0 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -241,7 +241,7 @@ static void vfio_intx_update(VFIOPCIDevice *vdev, PCIINTxRoute *route)
 
 static void vfio_intx_routing_notifier(PCIDevice *pdev)
 {
-    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
+    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
     PCIINTxRoute route;
 
     if (vdev->interrupt != VFIO_INT_INTx) {
@@ -516,7 +516,7 @@ static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg,
 static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
                                    MSIMessage *msg, IOHandler *handler)
 {
-    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
+    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
     VFIOMSIVector *vector;
     int ret;
     bool resizing = !!(vdev->nr_vectors < nr + 1);
@@ -621,7 +621,7 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
 
 static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr)
 {
-    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
+    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
     VFIOMSIVector *vector = &vdev->msi_vectors[nr];
 
     trace_vfio_msix_vector_release(vdev->vbasedev.name, nr);
@@ -1169,7 +1169,7 @@ static const MemoryRegionOps vfio_vga_ops = {
  */
 static void vfio_sub_page_bar_update_mapping(PCIDevice *pdev, int bar)
 {
-    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
+    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
     VFIORegion *region = &vdev->bars[bar].region;
     MemoryRegion *mmap_mr, *region_mr, *base_mr;
     PCIIORegion *r;
@@ -1215,7 +1215,7 @@ static void vfio_sub_page_bar_update_mapping(PCIDevice *pdev, int bar)
  */
 uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len)
 {
-    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
+    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
     uint32_t emu_bits = 0, emu_val = 0, phys_val = 0, val;
 
     memcpy(&emu_bits, vdev->emulated_config_bits + addr, len);
@@ -1248,7 +1248,7 @@ uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len)
 void vfio_pci_write_config(PCIDevice *pdev,
                            uint32_t addr, uint32_t val, int len)
 {
-    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
+    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
     uint32_t val_le = cpu_to_le32(val);
 
     trace_vfio_pci_write_config(vdev->vbasedev.name, addr, val, len);
@@ -3091,7 +3091,7 @@ static bool vfio_interrupt_setup(VFIOPCIDevice *vdev, Error **errp)
 static void vfio_realize(PCIDevice *pdev, Error **errp)
 {
     ERRP_GUARD();
-    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
+    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
     VFIODevice *vbasedev = &vdev->vbasedev;
     int i, ret;
     char uuid[UUID_STR_LEN];
@@ -3260,7 +3260,7 @@ error:
 
 static void vfio_instance_finalize(Object *obj)
 {
-    VFIOPCIDevice *vdev = VFIO_PCI(obj);
+    VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj);
 
     vfio_display_finalize(vdev);
     vfio_bars_finalize(vdev);
@@ -3278,7 +3278,7 @@ static void vfio_instance_finalize(Object *obj)
 
 static void vfio_exitfn(PCIDevice *pdev)
 {
-    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
+    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
     VFIODevice *vbasedev = &vdev->vbasedev;
 
     vfio_unregister_req_notifier(vdev);
@@ -3302,7 +3302,7 @@ static void vfio_exitfn(PCIDevice *pdev)
 
 static void vfio_pci_reset(DeviceState *dev)
 {
-    VFIOPCIDevice *vdev = VFIO_PCI(dev);
+    VFIOPCIDevice *vdev = VFIO_PCI_BASE(dev);
 
     trace_vfio_pci_reset(vdev->vbasedev.name);
 
@@ -3342,7 +3342,7 @@ post_reset:
 static void vfio_instance_init(Object *obj)
 {
     PCIDevice *pci_dev = PCI_DEVICE(obj);
-    VFIOPCIDevice *vdev = VFIO_PCI(obj);
+    VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj);
     VFIODevice *vbasedev = &vdev->vbasedev;
 
     device_add_bootindex_property(obj, &vdev->bootindex,
@@ -3365,32 +3365,15 @@ static void vfio_instance_init(Object *obj)
 
 static PropertyInfo vfio_pci_migration_multifd_transfer_prop;
 
-static const Property vfio_pci_dev_properties[] = {
-    DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIOPCIDevice, host),
-    DEFINE_PROP_UUID_NODEFAULT("vf-token", VFIOPCIDevice, vf_token),
-    DEFINE_PROP_STRING("sysfsdev", VFIOPCIDevice, vbasedev.sysfsdev),
+static const Property vfio_pci_base_dev_properties[] = {
     DEFINE_PROP_ON_OFF_AUTO("x-pre-copy-dirty-page-tracking", VFIOPCIDevice,
                             vbasedev.pre_copy_dirty_page_tracking,
                             ON_OFF_AUTO_ON),
     DEFINE_PROP_ON_OFF_AUTO("x-device-dirty-page-tracking", VFIOPCIDevice,
                             vbasedev.device_dirty_page_tracking,
                             ON_OFF_AUTO_ON),
-    DEFINE_PROP_ON_OFF_AUTO("display", VFIOPCIDevice,
-                            display, ON_OFF_AUTO_OFF),
-    DEFINE_PROP_UINT32("xres", VFIOPCIDevice, display_xres, 0),
-    DEFINE_PROP_UINT32("yres", VFIOPCIDevice, display_yres, 0),
     DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIOPCIDevice,
                        intx.mmap_timeout, 1100),
-    DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features,
-                    VFIO_FEATURE_ENABLE_VGA_BIT, false),
-    DEFINE_PROP_BIT("x-req", VFIOPCIDevice, features,
-                    VFIO_FEATURE_ENABLE_REQ_BIT, true),
-    DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features,
-                    VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
-    DEFINE_PROP_BIT("x-igd-lpc", VFIOPCIDevice, features,
-                    VFIO_FEATURE_ENABLE_IGD_LPC_BIT, false),
-    DEFINE_PROP_ON_OFF_AUTO("x-igd-legacy-mode", VFIOPCIDevice,
-                            igd_legacy_mode, ON_OFF_AUTO_AUTO),
     DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
                             vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
     DEFINE_PROP("x-migration-multifd-transfer", VFIOPCIDevice,
@@ -3405,8 +3388,6 @@ static const Property vfio_pci_dev_properties[] = {
     DEFINE_PROP_BOOL("x-no-kvm-intx", VFIOPCIDevice, no_kvm_intx, false),
     DEFINE_PROP_BOOL("x-no-kvm-msi", VFIOPCIDevice, no_kvm_msi, false),
     DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false),
-    DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
-                     no_geforce_quirks, false),
     DEFINE_PROP_BOOL("x-no-kvm-ioeventfd", VFIOPCIDevice, no_kvm_ioeventfd,
                      false),
     DEFINE_PROP_BOOL("x-no-vfio-ioeventfd", VFIOPCIDevice, no_vfio_ioeventfd,
@@ -3417,61 +3398,55 @@ static const Property vfio_pci_dev_properties[] = {
                        sub_vendor_id, PCI_ANY_ID),
     DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
                        sub_device_id, PCI_ANY_ID),
-    DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
-    DEFINE_PROP_UNSIGNED_NODEFAULT("x-nv-gpudirect-clique", VFIOPCIDevice,
-                                   nv_gpudirect_clique,
-                                   qdev_prop_nv_gpudirect_clique, uint8_t),
     DEFINE_PROP_OFF_AUTO_PCIBAR("x-msix-relocation", VFIOPCIDevice, msix_relo,
                                 OFF_AUTO_PCIBAR_OFF),
-#ifdef CONFIG_IOMMUFD
-    DEFINE_PROP_LINK("iommufd", VFIOPCIDevice, vbasedev.iommufd,
-                     TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *),
-#endif
-    DEFINE_PROP_BOOL("skip-vsc-check", VFIOPCIDevice, skip_vsc_check, true),
 };
 
-#ifdef CONFIG_IOMMUFD
-static void vfio_pci_set_fd(Object *obj, const char *str, Error **errp)
-{
-    vfio_device_set_fd(&VFIO_PCI(obj)->vbasedev, str, errp);
-}
-#endif
 
-static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
+static void vfio_pci_base_dev_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *pdc = PCI_DEVICE_CLASS(klass);
 
-    device_class_set_legacy_reset(dc, vfio_pci_reset);
-    device_class_set_props(dc, vfio_pci_dev_properties);
-#ifdef CONFIG_IOMMUFD
-    object_class_property_add_str(klass, "fd", NULL, vfio_pci_set_fd);
-#endif
-    dc->desc = "VFIO-based PCI device assignment";
+    device_class_set_props(dc, vfio_pci_base_dev_properties);
+    dc->desc = "VFIO PCI base device";
     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
-    pdc->realize = vfio_realize;
     pdc->exit = vfio_exitfn;
     pdc->config_read = vfio_pci_read_config;
     pdc->config_write = vfio_pci_write_config;
 
-    object_class_property_set_description(klass, /* 1.3 */
-                                          "host",
-                                          "Host PCI address [domain:]<bus:slot.function> of assigned device");
+    object_class_property_set_description(klass, /* 5.2 */
+                                          "x-pre-copy-dirty-page-tracking",
+                                          "Disable dirty pages tracking during iterative phase "
+                                          "(DEBUG)");
+    object_class_property_set_description(klass, /* 9.1 */
+                                          "x-device-dirty-page-tracking",
+                                          "Disable device dirty page tracking and use "
+                                          "container-based dirty page tracking");
     object_class_property_set_description(klass, /* 1.3 */
                                           "x-intx-mmap-timeout-ms",
                                           "When EOI is not provided by KVM/QEMU, wait time "
                                           "(milliseconds) to re-enable device direct access "
                                           "after INTx (DEBUG)");
-    object_class_property_set_description(klass, /* 1.5 */
-                                          "x-vga",
-                                          "Expose VGA address spaces for device");
-    object_class_property_set_description(klass, /* 2.3 */
-                                          "x-req",
-                                          "Disable device request notification support (DEBUG)");
+    object_class_property_set_description(klass, /* 5.2, 8.0 non-experimetal */
+                                          "enable-migration",
+                                          "Enale device migration. Also requires a host VFIO PCI "
+                                          "variant or mdev driver with migration support enabled");
+    object_class_property_set_description(klass, /* 10.0 */
+                                          "x-migration-multifd-transfer",
+                                          "Transfer this device state via "
+                                          "multifd channels when live migrating it");
+    object_class_property_set_description(klass, /* 9.1 */
+                                          "migration-events",
+                                          "Emit VFIO migration QAPI event when a VFIO device "
+                                          "changes its migration state. For management applications");
     object_class_property_set_description(klass, /* 2.4 and 2.5 */
                                           "x-no-mmap",
                                           "Disable MMAP for device. Allows to trace MMIO "
                                           "accesses (DEBUG)");
+    object_class_property_set_description(klass, /* 3.1 */
+                                          "x-balloon-allowed",
+                                          "Override allowing ballooning with device (DEBUG, DANGER)");
     object_class_property_set_description(klass, /* 2.5 */
                                           "x-no-kvm-intx",
                                           "Disable direct VFIO->KVM INTx injection. Allows to "
@@ -3484,6 +3459,13 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
                                           "x-no-kvm-msix",
                                           "Disable direct VFIO->KVM MSIx injection. Allows to "
                                           "trace MSIx interrupts (DEBUG)");
+    object_class_property_set_description(klass, /* 3.0 */
+                                          "x-no-kvm-ioeventfd",
+                                          "Disable registration of ioeventfds with KVM (DEBUG)");
+    object_class_property_set_description(klass, /* 3.0 */
+                                          "x-no-vfio-ioeventfd",
+                                          "Disable linking of KVM ioeventfds to VFIO ioeventfds "
+                                          "(DEBUG)");
     object_class_property_set_description(klass, /* 2.5 */
                                           "x-pci-vendor-id",
                                           "Override PCI Vendor ID with provided value (DEBUG)");
@@ -3498,95 +3480,136 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
                                           "x-pci-sub-device-id",
                                           "Override PCI Subsystem Device ID with provided value "
                                           "(DEBUG)");
+    object_class_property_set_description(klass, /* 2.12 */
+                                          "x-msix-relocation",
+                                          "Specify MSI-X MMIO relocation to the end of specified "
+                                          "existing BAR or new BAR to avoid virtualization overhead "
+                                          "due to adjacent device registers");
+}
+
+static const TypeInfo vfio_pci_base_dev_info = {
+    .name = TYPE_VFIO_PCI_BASE,
+    .parent = TYPE_PCI_DEVICE,
+    .instance_size = 0,
+    .abstract = true,
+    .class_init = vfio_pci_base_dev_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { INTERFACE_PCIE_DEVICE },
+        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+        { }
+    },
+};
+
+static const Property vfio_pci_dev_properties[] = {
+    DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIOPCIDevice, host),
+    DEFINE_PROP_UUID_NODEFAULT("vf-token", VFIOPCIDevice, vf_token),
+    DEFINE_PROP_STRING("sysfsdev", VFIOPCIDevice, vbasedev.sysfsdev),
+    DEFINE_PROP_ON_OFF_AUTO("display", VFIOPCIDevice,
+                            display, ON_OFF_AUTO_OFF),
+    DEFINE_PROP_UINT32("xres", VFIOPCIDevice, display_xres, 0),
+    DEFINE_PROP_UINT32("yres", VFIOPCIDevice, display_yres, 0),
+    DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features,
+                    VFIO_FEATURE_ENABLE_VGA_BIT, false),
+    DEFINE_PROP_BIT("x-req", VFIOPCIDevice, features,
+                    VFIO_FEATURE_ENABLE_REQ_BIT, true),
+    DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features,
+                    VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
+    DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
+    DEFINE_PROP_BIT("x-igd-lpc", VFIOPCIDevice, features,
+                    VFIO_FEATURE_ENABLE_IGD_LPC_BIT, false),
+    DEFINE_PROP_ON_OFF_AUTO("x-igd-legacy-mode", VFIOPCIDevice,
+                            igd_legacy_mode, ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
+                     no_geforce_quirks, false),
+    DEFINE_PROP_UNSIGNED_NODEFAULT("x-nv-gpudirect-clique", VFIOPCIDevice,
+                                   nv_gpudirect_clique,
+                                   qdev_prop_nv_gpudirect_clique, uint8_t),
+#ifdef CONFIG_IOMMUFD
+    DEFINE_PROP_LINK("iommufd", VFIOPCIDevice, vbasedev.iommufd,
+                     TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *),
+#endif
+    DEFINE_PROP_BOOL("skip-vsc-check", VFIOPCIDevice, skip_vsc_check, true),
+};
+
+#ifdef CONFIG_IOMMUFD
+static void vfio_pci_set_fd(Object *obj, const char *str, Error **errp)
+{
+    VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj);
+    vfio_device_set_fd(&vdev->vbasedev, str, errp);
+}
+#endif
+
+static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *pdc = PCI_DEVICE_CLASS(klass);
+
+    device_class_set_legacy_reset(dc, vfio_pci_reset);
+    device_class_set_props(dc, vfio_pci_dev_properties);
+#ifdef CONFIG_IOMMUFD
+    object_class_property_add_str(klass, "fd", NULL, vfio_pci_set_fd);
+#endif
+    dc->desc = "VFIO-based PCI device assignment";
+    pdc->realize = vfio_realize;
+
+    object_class_property_set_description(klass, /* 1.3 */
+                                          "host",
+                                          "Host PCI address [domain:]<bus:slot.function> of assigned device");
+    object_class_property_set_description(klass, /* 8.1 */
+                                          "vf-token",
+                                          "Specify UUID VF token. Required for VF when PF is owned "
+                                          "by another VFIO driver");
     object_class_property_set_description(klass, /* 2.6 */
                                           "sysfsdev",
                                           "Host sysfs path of assigned device");
+    object_class_property_set_description(klass, /* 2.12 */
+                                          "display",
+                                          "Enable display support for device, ex. vGPU");
+    object_class_property_set_description(klass, /* 3.2 */
+                                          "xres",
+                                          "Set X display resolution the vGPU should use");
+    object_class_property_set_description(klass, /* 3.2 */
+                                          "yres",
+                                          "Set Y display resolution the vGPU should use");
+    object_class_property_set_description(klass, /* 1.5 */
+                                          "x-vga",
+                                          "Expose VGA address spaces for device");
+    object_class_property_set_description(klass, /* 2.3 */
+                                          "x-req",
+                                          "Disable device request notification support (DEBUG)");
     object_class_property_set_description(klass, /* 2.7 */
                                           "x-igd-opregion",
                                           "Expose host IGD OpRegion to guest");
     object_class_property_set_description(klass, /* 2.7 (See c4c45e943e51) */
                                           "x-igd-gms",
                                           "Override IGD data stolen memory size (32MiB units)");
-    object_class_property_set_description(klass, /* 2.11 */
-                                          "x-nv-gpudirect-clique",
-                                          "Add NVIDIA GPUDirect capability indicating P2P DMA "
-                                          "clique for device [0-15]");
     object_class_property_set_description(klass, /* 2.12 */
                                           "x-no-geforce-quirks",
                                           "Disable GeForce quirks (for NVIDIA Quadro/GRID/Tesla). "
                                           "Improves performance");
-    object_class_property_set_description(klass, /* 2.12 */
-                                          "display",
-                                          "Enable display support for device, ex. vGPU");
-    object_class_property_set_description(klass, /* 2.12 */
-                                          "x-msix-relocation",
-                                          "Specify MSI-X MMIO relocation to the end of specified "
-                                          "existing BAR or new BAR to avoid virtualization overhead "
-                                          "due to adjacent device registers");
-    object_class_property_set_description(klass, /* 3.0 */
-                                          "x-no-kvm-ioeventfd",
-                                          "Disable registration of ioeventfds with KVM (DEBUG)");
-    object_class_property_set_description(klass, /* 3.0 */
-                                          "x-no-vfio-ioeventfd",
-                                          "Disable linking of KVM ioeventfds to VFIO ioeventfds "
-                                          "(DEBUG)");
-    object_class_property_set_description(klass, /* 3.1 */
-                                          "x-balloon-allowed",
-                                          "Override allowing ballooning with device (DEBUG, DANGER)");
-    object_class_property_set_description(klass, /* 3.2 */
-                                          "xres",
-                                          "Set X display resolution the vGPU should use");
-    object_class_property_set_description(klass, /* 3.2 */
-                                          "yres",
-                                          "Set Y display resolution the vGPU should use");
-    object_class_property_set_description(klass, /* 5.2 */
-                                          "x-pre-copy-dirty-page-tracking",
-                                          "Disable dirty pages tracking during iterative phase "
-                                          "(DEBUG)");
-    object_class_property_set_description(klass, /* 5.2, 8.0 non-experimetal */
-                                          "enable-migration",
-                                          "Enale device migration. Also requires a host VFIO PCI "
-                                          "variant or mdev driver with migration support enabled");
-    object_class_property_set_description(klass, /* 8.1 */
-                                          "vf-token",
-                                          "Specify UUID VF token. Required for VF when PF is owned "
-                                          "by another VFIO driver");
+    object_class_property_set_description(klass, /* 2.11 */
+                                          "x-nv-gpudirect-clique",
+                                          "Add NVIDIA GPUDirect capability indicating P2P DMA "
+                                          "clique for device [0-15]");
 #ifdef CONFIG_IOMMUFD
     object_class_property_set_description(klass, /* 9.0 */
                                           "iommufd",
                                           "Set host IOMMUFD backend device");
 #endif
-    object_class_property_set_description(klass, /* 9.1 */
-                                          "x-device-dirty-page-tracking",
-                                          "Disable device dirty page tracking and use "
-                                          "container-based dirty page tracking");
-    object_class_property_set_description(klass, /* 9.1 */
-                                          "migration-events",
-                                          "Emit VFIO migration QAPI event when a VFIO device "
-                                          "changes its migration state. For management applications");
     object_class_property_set_description(klass, /* 9.1 */
                                           "skip-vsc-check",
                                           "Skip config space check for Vendor Specific Capability. "
                                           "Setting to false will enforce strict checking of VSC content "
                                           "(DEBUG)");
-    object_class_property_set_description(klass, /* 10.0 */
-                                          "x-migration-multifd-transfer",
-                                          "Transfer this device state via "
-                                          "multifd channels when live migrating it");
 }
 
 static const TypeInfo vfio_pci_dev_info = {
     .name = TYPE_VFIO_PCI,
-    .parent = TYPE_PCI_DEVICE,
+    .parent = TYPE_VFIO_PCI_BASE,
     .instance_size = sizeof(VFIOPCIDevice),
     .class_init = vfio_pci_dev_class_init,
     .instance_init = vfio_instance_init,
     .instance_finalize = vfio_instance_finalize,
-    .interfaces = (InterfaceInfo[]) {
-        { INTERFACE_PCIE_DEVICE },
-        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
-        { }
-    },
 };
 
 static const Property vfio_pci_dev_nohotplug_properties[] = {
@@ -3632,6 +3655,7 @@ static void register_vfio_pci_dev_type(void)
     vfio_pci_migration_multifd_transfer_prop = qdev_prop_on_off_auto;
     vfio_pci_migration_multifd_transfer_prop.realized_set_allowed = true;
 
+    type_register_static(&vfio_pci_base_dev_info);
     type_register_static(&vfio_pci_dev_info);
     type_register_static(&vfio_pci_nohotplug_dev_info);
 }
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index cbea3be029..4000ba804c 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -118,8 +118,13 @@ typedef struct VFIOMSIXInfo {
     bool noresize;
 } VFIOMSIXInfo;
 
-#define TYPE_VFIO_PCI "vfio-pci"
-OBJECT_DECLARE_SIMPLE_TYPE(VFIOPCIDevice, VFIO_PCI)
+/*
+ * TYPE_VFIO_PCI_BASE is an abstract type used to share code
+ * between VFIO implementations that use a kernel driver
+ * with those that use user sockets.
+ */
+#define TYPE_VFIO_PCI_BASE "vfio-pci-base"
+OBJECT_DECLARE_SIMPLE_TYPE(VFIOPCIDevice, VFIO_PCI_BASE)
 
 struct VFIOPCIDevice {
     PCIDevice pdev;
@@ -187,6 +192,9 @@ struct VFIOPCIDevice {
     Notifier irqchip_change_notifier;
 };
 
+#define TYPE_VFIO_PCI "vfio-pci"
+/* TYPE_VFIO_PCI shares struct VFIOPCIDevice. */
+
 /* Use uin32_t for vendor & device so PCI_ANY_ID expands and cannot match hw */
 static inline bool vfio_pci_is(VFIOPCIDevice *vdev, uint32_t vendor, uint32_t device)
 {
-- 
2.34.1
Re: [PATCH 08/14] vfio: add vfio-pci-base class
Posted by Cédric Le Goater 6 months, 3 weeks ago
On 4/9/25 15:48, John Levon wrote:
> Split out parts of TYPE_VFIO_PCI into a base TYPE_VFIO_PCI_BASE. The
> base type contains properties generic to all vfio-pci implementations
> (although we have not yet introduced another subclass).
> 
> Note that currently there is no need for additional data for
> TYPE_VFIO_PCI, so it shares the same C struct type as
> TYPE_VFIO_PCI_BASE, VFIOPCIDevice.

I don't understand how the properties are distributed between the
abstract vfio-pci base class and the vfio-pci class. What's the
rationale ?

Can you remind me why the vfio-pci class for vfio-user can not
inherit directly from vfio-pci ?

Thanks,

C.

  
> Originally-by: John Johnson <john.g.johnson@oracle.com>
> Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
> Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
> Signed-off-by: John Levon <john.levon@nutanix.com>
> ---
>   hw/vfio/device.c |   2 +-
>   hw/vfio/pci.c    | 266 ++++++++++++++++++++++++++---------------------
>   hw/vfio/pci.h    |  12 ++-
>   3 files changed, 156 insertions(+), 124 deletions(-)
> 
> diff --git a/hw/vfio/device.c b/hw/vfio/device.c
> index f74b9c25ea..b9473878fc 100644
> --- a/hw/vfio/device.c
> +++ b/hw/vfio/device.c
> @@ -361,7 +361,7 @@ bool vfio_device_hiod_realize(VFIODevice *vbasedev, Error **errp)
>   VFIODevice *vfio_get_vfio_device(Object *obj)
>   {
>       if (object_dynamic_cast(obj, TYPE_VFIO_PCI)) {
> -        return &VFIO_PCI(obj)->vbasedev;
> +        return &VFIO_PCI_BASE(obj)->vbasedev;
>       } else {
>           return NULL;
>       }
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index 81bf0dab28..090b2f2ef0 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -241,7 +241,7 @@ static void vfio_intx_update(VFIOPCIDevice *vdev, PCIINTxRoute *route)
>   
>   static void vfio_intx_routing_notifier(PCIDevice *pdev)
>   {
> -    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
> +    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
>       PCIINTxRoute route;
>   
>       if (vdev->interrupt != VFIO_INT_INTx) {
> @@ -516,7 +516,7 @@ static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg,
>   static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
>                                      MSIMessage *msg, IOHandler *handler)
>   {
> -    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
> +    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
>       VFIOMSIVector *vector;
>       int ret;
>       bool resizing = !!(vdev->nr_vectors < nr + 1);
> @@ -621,7 +621,7 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
>   
>   static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr)
>   {
> -    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
> +    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
>       VFIOMSIVector *vector = &vdev->msi_vectors[nr];
>   
>       trace_vfio_msix_vector_release(vdev->vbasedev.name, nr);
> @@ -1169,7 +1169,7 @@ static const MemoryRegionOps vfio_vga_ops = {
>    */
>   static void vfio_sub_page_bar_update_mapping(PCIDevice *pdev, int bar)
>   {
> -    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
> +    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
>       VFIORegion *region = &vdev->bars[bar].region;
>       MemoryRegion *mmap_mr, *region_mr, *base_mr;
>       PCIIORegion *r;
> @@ -1215,7 +1215,7 @@ static void vfio_sub_page_bar_update_mapping(PCIDevice *pdev, int bar)
>    */
>   uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len)
>   {
> -    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
> +    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
>       uint32_t emu_bits = 0, emu_val = 0, phys_val = 0, val;
>   
>       memcpy(&emu_bits, vdev->emulated_config_bits + addr, len);
> @@ -1248,7 +1248,7 @@ uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len)
>   void vfio_pci_write_config(PCIDevice *pdev,
>                              uint32_t addr, uint32_t val, int len)
>   {
> -    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
> +    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
>       uint32_t val_le = cpu_to_le32(val);
>   
>       trace_vfio_pci_write_config(vdev->vbasedev.name, addr, val, len);
> @@ -3091,7 +3091,7 @@ static bool vfio_interrupt_setup(VFIOPCIDevice *vdev, Error **errp)
>   static void vfio_realize(PCIDevice *pdev, Error **errp)
>   {
>       ERRP_GUARD();
> -    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
> +    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
>       VFIODevice *vbasedev = &vdev->vbasedev;
>       int i, ret;
>       char uuid[UUID_STR_LEN];
> @@ -3260,7 +3260,7 @@ error:
>   
>   static void vfio_instance_finalize(Object *obj)
>   {
> -    VFIOPCIDevice *vdev = VFIO_PCI(obj);
> +    VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj);
>   
>       vfio_display_finalize(vdev);
>       vfio_bars_finalize(vdev);
> @@ -3278,7 +3278,7 @@ static void vfio_instance_finalize(Object *obj)
>   
>   static void vfio_exitfn(PCIDevice *pdev)
>   {
> -    VFIOPCIDevice *vdev = VFIO_PCI(pdev);
> +    VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
>       VFIODevice *vbasedev = &vdev->vbasedev;
>   
>       vfio_unregister_req_notifier(vdev);
> @@ -3302,7 +3302,7 @@ static void vfio_exitfn(PCIDevice *pdev)
>   
>   static void vfio_pci_reset(DeviceState *dev)
>   {
> -    VFIOPCIDevice *vdev = VFIO_PCI(dev);
> +    VFIOPCIDevice *vdev = VFIO_PCI_BASE(dev);
>   
>       trace_vfio_pci_reset(vdev->vbasedev.name);
>   
> @@ -3342,7 +3342,7 @@ post_reset:
>   static void vfio_instance_init(Object *obj)
>   {
>       PCIDevice *pci_dev = PCI_DEVICE(obj);
> -    VFIOPCIDevice *vdev = VFIO_PCI(obj);
> +    VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj);
>       VFIODevice *vbasedev = &vdev->vbasedev;
>   
>       device_add_bootindex_property(obj, &vdev->bootindex,
> @@ -3365,32 +3365,15 @@ static void vfio_instance_init(Object *obj)
>   
>   static PropertyInfo vfio_pci_migration_multifd_transfer_prop;
>   
> -static const Property vfio_pci_dev_properties[] = {
> -    DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIOPCIDevice, host),
> -    DEFINE_PROP_UUID_NODEFAULT("vf-token", VFIOPCIDevice, vf_token),
> -    DEFINE_PROP_STRING("sysfsdev", VFIOPCIDevice, vbasedev.sysfsdev),
> +static const Property vfio_pci_base_dev_properties[] = {
>       DEFINE_PROP_ON_OFF_AUTO("x-pre-copy-dirty-page-tracking", VFIOPCIDevice,
>                               vbasedev.pre_copy_dirty_page_tracking,
>                               ON_OFF_AUTO_ON),
>       DEFINE_PROP_ON_OFF_AUTO("x-device-dirty-page-tracking", VFIOPCIDevice,
>                               vbasedev.device_dirty_page_tracking,
>                               ON_OFF_AUTO_ON),
> -    DEFINE_PROP_ON_OFF_AUTO("display", VFIOPCIDevice,
> -                            display, ON_OFF_AUTO_OFF),
> -    DEFINE_PROP_UINT32("xres", VFIOPCIDevice, display_xres, 0),
> -    DEFINE_PROP_UINT32("yres", VFIOPCIDevice, display_yres, 0),
>       DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIOPCIDevice,
>                          intx.mmap_timeout, 1100),
> -    DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features,
> -                    VFIO_FEATURE_ENABLE_VGA_BIT, false),
> -    DEFINE_PROP_BIT("x-req", VFIOPCIDevice, features,
> -                    VFIO_FEATURE_ENABLE_REQ_BIT, true),
> -    DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features,
> -                    VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
> -    DEFINE_PROP_BIT("x-igd-lpc", VFIOPCIDevice, features,
> -                    VFIO_FEATURE_ENABLE_IGD_LPC_BIT, false),
> -    DEFINE_PROP_ON_OFF_AUTO("x-igd-legacy-mode", VFIOPCIDevice,
> -                            igd_legacy_mode, ON_OFF_AUTO_AUTO),
>       DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
>                               vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
>       DEFINE_PROP("x-migration-multifd-transfer", VFIOPCIDevice,
> @@ -3405,8 +3388,6 @@ static const Property vfio_pci_dev_properties[] = {
>       DEFINE_PROP_BOOL("x-no-kvm-intx", VFIOPCIDevice, no_kvm_intx, false),
>       DEFINE_PROP_BOOL("x-no-kvm-msi", VFIOPCIDevice, no_kvm_msi, false),
>       DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false),
> -    DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
> -                     no_geforce_quirks, false),
>       DEFINE_PROP_BOOL("x-no-kvm-ioeventfd", VFIOPCIDevice, no_kvm_ioeventfd,
>                        false),
>       DEFINE_PROP_BOOL("x-no-vfio-ioeventfd", VFIOPCIDevice, no_vfio_ioeventfd,
> @@ -3417,61 +3398,55 @@ static const Property vfio_pci_dev_properties[] = {
>                          sub_vendor_id, PCI_ANY_ID),
>       DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
>                          sub_device_id, PCI_ANY_ID),
> -    DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
> -    DEFINE_PROP_UNSIGNED_NODEFAULT("x-nv-gpudirect-clique", VFIOPCIDevice,
> -                                   nv_gpudirect_clique,
> -                                   qdev_prop_nv_gpudirect_clique, uint8_t),
>       DEFINE_PROP_OFF_AUTO_PCIBAR("x-msix-relocation", VFIOPCIDevice, msix_relo,
>                                   OFF_AUTO_PCIBAR_OFF),
> -#ifdef CONFIG_IOMMUFD
> -    DEFINE_PROP_LINK("iommufd", VFIOPCIDevice, vbasedev.iommufd,
> -                     TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *),
> -#endif
> -    DEFINE_PROP_BOOL("skip-vsc-check", VFIOPCIDevice, skip_vsc_check, true),
>   };
>   
> -#ifdef CONFIG_IOMMUFD
> -static void vfio_pci_set_fd(Object *obj, const char *str, Error **errp)
> -{
> -    vfio_device_set_fd(&VFIO_PCI(obj)->vbasedev, str, errp);
> -}
> -#endif
>   
> -static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
> +static void vfio_pci_base_dev_class_init(ObjectClass *klass, void *data)
>   {
>       DeviceClass *dc = DEVICE_CLASS(klass);
>       PCIDeviceClass *pdc = PCI_DEVICE_CLASS(klass);
>   
> -    device_class_set_legacy_reset(dc, vfio_pci_reset);
> -    device_class_set_props(dc, vfio_pci_dev_properties);
> -#ifdef CONFIG_IOMMUFD
> -    object_class_property_add_str(klass, "fd", NULL, vfio_pci_set_fd);
> -#endif
> -    dc->desc = "VFIO-based PCI device assignment";
> +    device_class_set_props(dc, vfio_pci_base_dev_properties);
> +    dc->desc = "VFIO PCI base device";
>       set_bit(DEVICE_CATEGORY_MISC, dc->categories);
> -    pdc->realize = vfio_realize;
>       pdc->exit = vfio_exitfn;
>       pdc->config_read = vfio_pci_read_config;
>       pdc->config_write = vfio_pci_write_config;
>   
> -    object_class_property_set_description(klass, /* 1.3 */
> -                                          "host",
> -                                          "Host PCI address [domain:]<bus:slot.function> of assigned device");
> +    object_class_property_set_description(klass, /* 5.2 */
> +                                          "x-pre-copy-dirty-page-tracking",
> +                                          "Disable dirty pages tracking during iterative phase "
> +                                          "(DEBUG)");
> +    object_class_property_set_description(klass, /* 9.1 */
> +                                          "x-device-dirty-page-tracking",
> +                                          "Disable device dirty page tracking and use "
> +                                          "container-based dirty page tracking");
>       object_class_property_set_description(klass, /* 1.3 */
>                                             "x-intx-mmap-timeout-ms",
>                                             "When EOI is not provided by KVM/QEMU, wait time "
>                                             "(milliseconds) to re-enable device direct access "
>                                             "after INTx (DEBUG)");
> -    object_class_property_set_description(klass, /* 1.5 */
> -                                          "x-vga",
> -                                          "Expose VGA address spaces for device");
> -    object_class_property_set_description(klass, /* 2.3 */
> -                                          "x-req",
> -                                          "Disable device request notification support (DEBUG)");
> +    object_class_property_set_description(klass, /* 5.2, 8.0 non-experimetal */
> +                                          "enable-migration",
> +                                          "Enale device migration. Also requires a host VFIO PCI "
> +                                          "variant or mdev driver with migration support enabled");
> +    object_class_property_set_description(klass, /* 10.0 */
> +                                          "x-migration-multifd-transfer",
> +                                          "Transfer this device state via "
> +                                          "multifd channels when live migrating it");
> +    object_class_property_set_description(klass, /* 9.1 */
> +                                          "migration-events",
> +                                          "Emit VFIO migration QAPI event when a VFIO device "
> +                                          "changes its migration state. For management applications");
>       object_class_property_set_description(klass, /* 2.4 and 2.5 */
>                                             "x-no-mmap",
>                                             "Disable MMAP for device. Allows to trace MMIO "
>                                             "accesses (DEBUG)");
> +    object_class_property_set_description(klass, /* 3.1 */
> +                                          "x-balloon-allowed",
> +                                          "Override allowing ballooning with device (DEBUG, DANGER)");
>       object_class_property_set_description(klass, /* 2.5 */
>                                             "x-no-kvm-intx",
>                                             "Disable direct VFIO->KVM INTx injection. Allows to "
> @@ -3484,6 +3459,13 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
>                                             "x-no-kvm-msix",
>                                             "Disable direct VFIO->KVM MSIx injection. Allows to "
>                                             "trace MSIx interrupts (DEBUG)");
> +    object_class_property_set_description(klass, /* 3.0 */
> +                                          "x-no-kvm-ioeventfd",
> +                                          "Disable registration of ioeventfds with KVM (DEBUG)");
> +    object_class_property_set_description(klass, /* 3.0 */
> +                                          "x-no-vfio-ioeventfd",
> +                                          "Disable linking of KVM ioeventfds to VFIO ioeventfds "
> +                                          "(DEBUG)");
>       object_class_property_set_description(klass, /* 2.5 */
>                                             "x-pci-vendor-id",
>                                             "Override PCI Vendor ID with provided value (DEBUG)");
> @@ -3498,95 +3480,136 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
>                                             "x-pci-sub-device-id",
>                                             "Override PCI Subsystem Device ID with provided value "
>                                             "(DEBUG)");
> +    object_class_property_set_description(klass, /* 2.12 */
> +                                          "x-msix-relocation",
> +                                          "Specify MSI-X MMIO relocation to the end of specified "
> +                                          "existing BAR or new BAR to avoid virtualization overhead "
> +                                          "due to adjacent device registers");
> +}
> +
> +static const TypeInfo vfio_pci_base_dev_info = {
> +    .name = TYPE_VFIO_PCI_BASE,
> +    .parent = TYPE_PCI_DEVICE,
> +    .instance_size = 0,
> +    .abstract = true,
> +    .class_init = vfio_pci_base_dev_class_init,
> +    .interfaces = (InterfaceInfo[]) {
> +        { INTERFACE_PCIE_DEVICE },
> +        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
> +        { }
> +    },
> +};
> +
> +static const Property vfio_pci_dev_properties[] = {
> +    DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIOPCIDevice, host),
> +    DEFINE_PROP_UUID_NODEFAULT("vf-token", VFIOPCIDevice, vf_token),
> +    DEFINE_PROP_STRING("sysfsdev", VFIOPCIDevice, vbasedev.sysfsdev),
> +    DEFINE_PROP_ON_OFF_AUTO("display", VFIOPCIDevice,
> +                            display, ON_OFF_AUTO_OFF),
> +    DEFINE_PROP_UINT32("xres", VFIOPCIDevice, display_xres, 0),
> +    DEFINE_PROP_UINT32("yres", VFIOPCIDevice, display_yres, 0),
> +    DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features,
> +                    VFIO_FEATURE_ENABLE_VGA_BIT, false),
> +    DEFINE_PROP_BIT("x-req", VFIOPCIDevice, features,
> +                    VFIO_FEATURE_ENABLE_REQ_BIT, true),
> +    DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features,
> +                    VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
> +    DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
> +    DEFINE_PROP_BIT("x-igd-lpc", VFIOPCIDevice, features,
> +                    VFIO_FEATURE_ENABLE_IGD_LPC_BIT, false),
> +    DEFINE_PROP_ON_OFF_AUTO("x-igd-legacy-mode", VFIOPCIDevice,
> +                            igd_legacy_mode, ON_OFF_AUTO_AUTO),
> +    DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
> +                     no_geforce_quirks, false),
> +    DEFINE_PROP_UNSIGNED_NODEFAULT("x-nv-gpudirect-clique", VFIOPCIDevice,
> +                                   nv_gpudirect_clique,
> +                                   qdev_prop_nv_gpudirect_clique, uint8_t),
> +#ifdef CONFIG_IOMMUFD
> +    DEFINE_PROP_LINK("iommufd", VFIOPCIDevice, vbasedev.iommufd,
> +                     TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *),
> +#endif
> +    DEFINE_PROP_BOOL("skip-vsc-check", VFIOPCIDevice, skip_vsc_check, true),
> +};
> +
> +#ifdef CONFIG_IOMMUFD
> +static void vfio_pci_set_fd(Object *obj, const char *str, Error **errp)
> +{
> +    VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj);
> +    vfio_device_set_fd(&vdev->vbasedev, str, errp);
> +}
> +#endif
> +
> +static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    PCIDeviceClass *pdc = PCI_DEVICE_CLASS(klass);
> +
> +    device_class_set_legacy_reset(dc, vfio_pci_reset);
> +    device_class_set_props(dc, vfio_pci_dev_properties);
> +#ifdef CONFIG_IOMMUFD
> +    object_class_property_add_str(klass, "fd", NULL, vfio_pci_set_fd);
> +#endif
> +    dc->desc = "VFIO-based PCI device assignment";
> +    pdc->realize = vfio_realize;
> +
> +    object_class_property_set_description(klass, /* 1.3 */
> +                                          "host",
> +                                          "Host PCI address [domain:]<bus:slot.function> of assigned device");
> +    object_class_property_set_description(klass, /* 8.1 */
> +                                          "vf-token",
> +                                          "Specify UUID VF token. Required for VF when PF is owned "
> +                                          "by another VFIO driver");
>       object_class_property_set_description(klass, /* 2.6 */
>                                             "sysfsdev",
>                                             "Host sysfs path of assigned device");
> +    object_class_property_set_description(klass, /* 2.12 */
> +                                          "display",
> +                                          "Enable display support for device, ex. vGPU");
> +    object_class_property_set_description(klass, /* 3.2 */
> +                                          "xres",
> +                                          "Set X display resolution the vGPU should use");
> +    object_class_property_set_description(klass, /* 3.2 */
> +                                          "yres",
> +                                          "Set Y display resolution the vGPU should use");
> +    object_class_property_set_description(klass, /* 1.5 */
> +                                          "x-vga",
> +                                          "Expose VGA address spaces for device");
> +    object_class_property_set_description(klass, /* 2.3 */
> +                                          "x-req",
> +                                          "Disable device request notification support (DEBUG)");
>       object_class_property_set_description(klass, /* 2.7 */
>                                             "x-igd-opregion",
>                                             "Expose host IGD OpRegion to guest");
>       object_class_property_set_description(klass, /* 2.7 (See c4c45e943e51) */
>                                             "x-igd-gms",
>                                             "Override IGD data stolen memory size (32MiB units)");
> -    object_class_property_set_description(klass, /* 2.11 */
> -                                          "x-nv-gpudirect-clique",
> -                                          "Add NVIDIA GPUDirect capability indicating P2P DMA "
> -                                          "clique for device [0-15]");
>       object_class_property_set_description(klass, /* 2.12 */
>                                             "x-no-geforce-quirks",
>                                             "Disable GeForce quirks (for NVIDIA Quadro/GRID/Tesla). "
>                                             "Improves performance");
> -    object_class_property_set_description(klass, /* 2.12 */
> -                                          "display",
> -                                          "Enable display support for device, ex. vGPU");
> -    object_class_property_set_description(klass, /* 2.12 */
> -                                          "x-msix-relocation",
> -                                          "Specify MSI-X MMIO relocation to the end of specified "
> -                                          "existing BAR or new BAR to avoid virtualization overhead "
> -                                          "due to adjacent device registers");
> -    object_class_property_set_description(klass, /* 3.0 */
> -                                          "x-no-kvm-ioeventfd",
> -                                          "Disable registration of ioeventfds with KVM (DEBUG)");
> -    object_class_property_set_description(klass, /* 3.0 */
> -                                          "x-no-vfio-ioeventfd",
> -                                          "Disable linking of KVM ioeventfds to VFIO ioeventfds "
> -                                          "(DEBUG)");
> -    object_class_property_set_description(klass, /* 3.1 */
> -                                          "x-balloon-allowed",
> -                                          "Override allowing ballooning with device (DEBUG, DANGER)");
> -    object_class_property_set_description(klass, /* 3.2 */
> -                                          "xres",
> -                                          "Set X display resolution the vGPU should use");
> -    object_class_property_set_description(klass, /* 3.2 */
> -                                          "yres",
> -                                          "Set Y display resolution the vGPU should use");
> -    object_class_property_set_description(klass, /* 5.2 */
> -                                          "x-pre-copy-dirty-page-tracking",
> -                                          "Disable dirty pages tracking during iterative phase "
> -                                          "(DEBUG)");
> -    object_class_property_set_description(klass, /* 5.2, 8.0 non-experimetal */
> -                                          "enable-migration",
> -                                          "Enale device migration. Also requires a host VFIO PCI "
> -                                          "variant or mdev driver with migration support enabled");
> -    object_class_property_set_description(klass, /* 8.1 */
> -                                          "vf-token",
> -                                          "Specify UUID VF token. Required for VF when PF is owned "
> -                                          "by another VFIO driver");
> +    object_class_property_set_description(klass, /* 2.11 */
> +                                          "x-nv-gpudirect-clique",
> +                                          "Add NVIDIA GPUDirect capability indicating P2P DMA "
> +                                          "clique for device [0-15]");
>   #ifdef CONFIG_IOMMUFD
>       object_class_property_set_description(klass, /* 9.0 */
>                                             "iommufd",
>                                             "Set host IOMMUFD backend device");
>   #endif
> -    object_class_property_set_description(klass, /* 9.1 */
> -                                          "x-device-dirty-page-tracking",
> -                                          "Disable device dirty page tracking and use "
> -                                          "container-based dirty page tracking");
> -    object_class_property_set_description(klass, /* 9.1 */
> -                                          "migration-events",
> -                                          "Emit VFIO migration QAPI event when a VFIO device "
> -                                          "changes its migration state. For management applications");
>       object_class_property_set_description(klass, /* 9.1 */
>                                             "skip-vsc-check",
>                                             "Skip config space check for Vendor Specific Capability. "
>                                             "Setting to false will enforce strict checking of VSC content "
>                                             "(DEBUG)");
> -    object_class_property_set_description(klass, /* 10.0 */
> -                                          "x-migration-multifd-transfer",
> -                                          "Transfer this device state via "
> -                                          "multifd channels when live migrating it");
>   }
>   
>   static const TypeInfo vfio_pci_dev_info = {
>       .name = TYPE_VFIO_PCI,
> -    .parent = TYPE_PCI_DEVICE,
> +    .parent = TYPE_VFIO_PCI_BASE,
>       .instance_size = sizeof(VFIOPCIDevice),
>       .class_init = vfio_pci_dev_class_init,
>       .instance_init = vfio_instance_init,
>       .instance_finalize = vfio_instance_finalize,
> -    .interfaces = (InterfaceInfo[]) {
> -        { INTERFACE_PCIE_DEVICE },
> -        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
> -        { }
> -    },
>   };
>   
>   static const Property vfio_pci_dev_nohotplug_properties[] = {
> @@ -3632,6 +3655,7 @@ static void register_vfio_pci_dev_type(void)
>       vfio_pci_migration_multifd_transfer_prop = qdev_prop_on_off_auto;
>       vfio_pci_migration_multifd_transfer_prop.realized_set_allowed = true;
>   
> +    type_register_static(&vfio_pci_base_dev_info);
>       type_register_static(&vfio_pci_dev_info);
>       type_register_static(&vfio_pci_nohotplug_dev_info);
>   }
> diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
> index cbea3be029..4000ba804c 100644
> --- a/hw/vfio/pci.h
> +++ b/hw/vfio/pci.h
> @@ -118,8 +118,13 @@ typedef struct VFIOMSIXInfo {
>       bool noresize;
>   } VFIOMSIXInfo;
>   
> -#define TYPE_VFIO_PCI "vfio-pci"
> -OBJECT_DECLARE_SIMPLE_TYPE(VFIOPCIDevice, VFIO_PCI)
> +/*
> + * TYPE_VFIO_PCI_BASE is an abstract type used to share code
> + * between VFIO implementations that use a kernel driver
> + * with those that use user sockets.
> + */
> +#define TYPE_VFIO_PCI_BASE "vfio-pci-base"
> +OBJECT_DECLARE_SIMPLE_TYPE(VFIOPCIDevice, VFIO_PCI_BASE)
>   
>   struct VFIOPCIDevice {
>       PCIDevice pdev;
> @@ -187,6 +192,9 @@ struct VFIOPCIDevice {
>       Notifier irqchip_change_notifier;
>   };
>   
> +#define TYPE_VFIO_PCI "vfio-pci"
> +/* TYPE_VFIO_PCI shares struct VFIOPCIDevice. */
> +
>   /* Use uin32_t for vendor & device so PCI_ANY_ID expands and cannot match hw */
>   static inline bool vfio_pci_is(VFIOPCIDevice *vdev, uint32_t vendor, uint32_t device)
>   {
Re: [PATCH 08/14] vfio: add vfio-pci-base class
Posted by John Levon 6 months, 3 weeks ago
On Thu, Apr 24, 2025 at 05:17:28PM +0200, Cédric Le Goater wrote:

> !-------------------------------------------------------------------|
>  CAUTION: External Email
> 
> |-------------------------------------------------------------------!
> 
> On 4/9/25 15:48, John Levon wrote:
> > Split out parts of TYPE_VFIO_PCI into a base TYPE_VFIO_PCI_BASE. The
> > base type contains properties generic to all vfio-pci implementations
> > (although we have not yet introduced another subclass).
> > 
> > Note that currently there is no need for additional data for
> > TYPE_VFIO_PCI, so it shares the same C struct type as
> > TYPE_VFIO_PCI_BASE, VFIOPCIDevice.
> 
> I don't understand how the properties are distributed between the
> abstract vfio-pci base class and the vfio-pci class. What's the
> rationale ?

It's for properties that apply to all vfio pci classes, and those that are
specific to the kernel vfio pci implementation.

> Can you remind me why the vfio-pci class for vfio-user can not
> inherit directly from vfio-pci ?

For the above reason: we'd inherit many properties that don't work for
vfio-user.

regards
john
Re: [PATCH 08/14] vfio: add vfio-pci-base class
Posted by Cédric Le Goater 6 months, 3 weeks ago
On 4/24/25 23:52, John Levon wrote:
> On Thu, Apr 24, 2025 at 05:17:28PM +0200, Cédric Le Goater wrote:
> 
>> !-------------------------------------------------------------------|
>>   CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> On 4/9/25 15:48, John Levon wrote:
>>> Split out parts of TYPE_VFIO_PCI into a base TYPE_VFIO_PCI_BASE. The
>>> base type contains properties generic to all vfio-pci implementations
>>> (although we have not yet introduced another subclass).
>>>
>>> Note that currently there is no need for additional data for
>>> TYPE_VFIO_PCI, so it shares the same C struct type as
>>> TYPE_VFIO_PCI_BASE, VFIOPCIDevice.
>>
>> I don't understand how the properties are distributed between the
>> abstract vfio-pci base class and the vfio-pci class. What's the
>> rationale ?
> 
> It's for properties that apply to all vfio pci classes, and those that are
> specific to the kernel vfio pci implementation.

It seems quite vague to me.

After this patch, here is what we have for the base class :
     
     static const Property vfio_pci_base_dev_properties[] = {
         DEFINE_PROP_ON_OFF_AUTO("x-pre-copy-dirty-page-tracking", VFIOPCIDevice,
                                 vbasedev.pre_copy_dirty_page_tracking,
                                 ON_OFF_AUTO_ON),
         DEFINE_PROP_ON_OFF_AUTO("x-device-dirty-page-tracking", VFIOPCIDevice,
                                 vbasedev.device_dirty_page_tracking,
                                 ON_OFF_AUTO_ON),
         DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIOPCIDevice,
                            intx.mmap_timeout, 1100),
         DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
                                 vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
         DEFINE_PROP("x-migration-multifd-transfer", VFIOPCIDevice,
                     vbasedev.migration_multifd_transfer,
                     vfio_pci_migration_multifd_transfer_prop, OnOffAuto,
                     .set_default = true, .defval.i = ON_OFF_AUTO_AUTO),
         DEFINE_PROP_BOOL("migration-events", VFIOPCIDevice,
                          vbasedev.migration_events, false),
         DEFINE_PROP_BOOL("x-no-mmap", VFIOPCIDevice, vbasedev.no_mmap, false),
         DEFINE_PROP_BOOL("x-balloon-allowed", VFIOPCIDevice,
                          vbasedev.ram_block_discard_allowed, false),
         DEFINE_PROP_BOOL("x-no-kvm-intx", VFIOPCIDevice, no_kvm_intx, false),
         DEFINE_PROP_BOOL("x-no-kvm-msi", VFIOPCIDevice, no_kvm_msi, false),
         DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false),
         DEFINE_PROP_BOOL("x-no-kvm-ioeventfd", VFIOPCIDevice, no_kvm_ioeventfd,
                          false),
         DEFINE_PROP_BOOL("x-no-vfio-ioeventfd", VFIOPCIDevice, no_vfio_ioeventfd,
                          false),
         DEFINE_PROP_UINT32("x-pci-vendor-id", VFIOPCIDevice, vendor_id, PCI_ANY_ID),
         DEFINE_PROP_UINT32("x-pci-device-id", VFIOPCIDevice, device_id, PCI_ANY_ID),
         DEFINE_PROP_UINT32("x-pci-sub-vendor-id", VFIOPCIDevice,
                            sub_vendor_id, PCI_ANY_ID),
         DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
                            sub_device_id, PCI_ANY_ID),
         DEFINE_PROP_OFF_AUTO_PCIBAR("x-msix-relocation", VFIOPCIDevice, msix_relo,
                                     OFF_AUTO_PCIBAR_OFF),
     };
     
and for vfio-pci :
     
     static const Property vfio_pci_dev_properties[] = {
         DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIOPCIDevice, host),
         DEFINE_PROP_UUID_NODEFAULT("vf-token", VFIOPCIDevice, vf_token),
         DEFINE_PROP_STRING("sysfsdev", VFIOPCIDevice, vbasedev.sysfsdev),
         DEFINE_PROP_ON_OFF_AUTO("display", VFIOPCIDevice,
                                 display, ON_OFF_AUTO_OFF),
         DEFINE_PROP_UINT32("xres", VFIOPCIDevice, display_xres, 0),
         DEFINE_PROP_UINT32("yres", VFIOPCIDevice, display_yres, 0),
         DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features,
                         VFIO_FEATURE_ENABLE_VGA_BIT, false),
         DEFINE_PROP_BIT("x-req", VFIOPCIDevice, features,
                         VFIO_FEATURE_ENABLE_REQ_BIT, true),
         DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features,
                         VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
         DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
         DEFINE_PROP_BIT("x-igd-lpc", VFIOPCIDevice, features,
                         VFIO_FEATURE_ENABLE_IGD_LPC_BIT, false),
         DEFINE_PROP_ON_OFF_AUTO("x-igd-legacy-mode", VFIOPCIDevice,
                                 igd_legacy_mode, ON_OFF_AUTO_AUTO),
         DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
                          no_geforce_quirks, false),
         DEFINE_PROP_UNSIGNED_NODEFAULT("x-nv-gpudirect-clique", VFIOPCIDevice,
                                        nv_gpudirect_clique,
                                        qdev_prop_nv_gpudirect_clique, uint8_t),
     #ifdef CONFIG_IOMMUFD
         DEFINE_PROP_LINK("iommufd", VFIOPCIDevice, vbasedev.iommufd,
                          TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *),
     #endif
         DEFINE_PROP_BOOL("skip-vsc-check", VFIOPCIDevice, skip_vsc_check, true),
     };
    
Graphic property and host device definitions are excluded from the
base class it seems. This might fit vfio-user needs but it looks
like a quick hack from the vfio-pci side. It needs more work.

>> Can you remind me why the vfio-pci class for vfio-user can not
>> inherit directly from vfio-pci ?
>
> For the above reason: we'd inherit many properties that don't work for
> vfio-user.

What do you mean by "don't work" ? functionally irrelevant ?

Thanks,

C.


Re: [PATCH 08/14] vfio: add vfio-pci-base class
Posted by John Levon 6 months, 3 weeks ago
On Fri, Apr 25, 2025 at 02:46:48PM +0200, Cédric Le Goater wrote:

> After this patch, here is what we have for the base class :
>     static const Property vfio_pci_base_dev_properties[] = {
>         DEFINE_PROP_ON_OFF_AUTO("x-pre-copy-dirty-page-tracking", VFIOPCIDevice,
>                                 vbasedev.pre_copy_dirty_page_tracking,
>                                 ON_OFF_AUTO_ON),
>         DEFINE_PROP_ON_OFF_AUTO("x-device-dirty-page-tracking", VFIOPCIDevice,
>                                 vbasedev.device_dirty_page_tracking,
>                                 ON_OFF_AUTO_ON),
>         DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIOPCIDevice,
>                            intx.mmap_timeout, 1100),
>         DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
>                                 vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
>         DEFINE_PROP("x-migration-multifd-transfer", VFIOPCIDevice,
>                     vbasedev.migration_multifd_transfer,
>                     vfio_pci_migration_multifd_transfer_prop, OnOffAuto,
>                     .set_default = true, .defval.i = ON_OFF_AUTO_AUTO),
>         DEFINE_PROP_BOOL("migration-events", VFIOPCIDevice,
>                          vbasedev.migration_events, false),
>         DEFINE_PROP_BOOL("x-no-mmap", VFIOPCIDevice, vbasedev.no_mmap, false),
>         DEFINE_PROP_BOOL("x-balloon-allowed", VFIOPCIDevice,
>                          vbasedev.ram_block_discard_allowed, false),
>         DEFINE_PROP_BOOL("x-no-kvm-intx", VFIOPCIDevice, no_kvm_intx, false),
>         DEFINE_PROP_BOOL("x-no-kvm-msi", VFIOPCIDevice, no_kvm_msi, false),
>         DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false),
>         DEFINE_PROP_BOOL("x-no-kvm-ioeventfd", VFIOPCIDevice, no_kvm_ioeventfd,
>                          false),
>         DEFINE_PROP_BOOL("x-no-vfio-ioeventfd", VFIOPCIDevice, no_vfio_ioeventfd,
>                          false),
>         DEFINE_PROP_UINT32("x-pci-vendor-id", VFIOPCIDevice, vendor_id, PCI_ANY_ID),
>         DEFINE_PROP_UINT32("x-pci-device-id", VFIOPCIDevice, device_id, PCI_ANY_ID),
>         DEFINE_PROP_UINT32("x-pci-sub-vendor-id", VFIOPCIDevice,
>                            sub_vendor_id, PCI_ANY_ID),
>         DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
>                            sub_device_id, PCI_ANY_ID),
>         DEFINE_PROP_OFF_AUTO_PCIBAR("x-msix-relocation", VFIOPCIDevice, msix_relo,
>                                     OFF_AUTO_PCIBAR_OFF),
>     };
> and for vfio-pci :
>     static const Property vfio_pci_dev_properties[] = {
>         DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIOPCIDevice, host),
>         DEFINE_PROP_UUID_NODEFAULT("vf-token", VFIOPCIDevice, vf_token),
>         DEFINE_PROP_STRING("sysfsdev", VFIOPCIDevice, vbasedev.sysfsdev),
>         DEFINE_PROP_ON_OFF_AUTO("display", VFIOPCIDevice,
>                                 display, ON_OFF_AUTO_OFF),
>         DEFINE_PROP_UINT32("xres", VFIOPCIDevice, display_xres, 0),
>         DEFINE_PROP_UINT32("yres", VFIOPCIDevice, display_yres, 0),
>         DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features,
>                         VFIO_FEATURE_ENABLE_VGA_BIT, false),
>         DEFINE_PROP_BIT("x-req", VFIOPCIDevice, features,
>                         VFIO_FEATURE_ENABLE_REQ_BIT, true),
>         DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features,
>                         VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
>         DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
>         DEFINE_PROP_BIT("x-igd-lpc", VFIOPCIDevice, features,
>                         VFIO_FEATURE_ENABLE_IGD_LPC_BIT, false),
>         DEFINE_PROP_ON_OFF_AUTO("x-igd-legacy-mode", VFIOPCIDevice,
>                                 igd_legacy_mode, ON_OFF_AUTO_AUTO),
>         DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
>                          no_geforce_quirks, false),
>         DEFINE_PROP_UNSIGNED_NODEFAULT("x-nv-gpudirect-clique", VFIOPCIDevice,
>                                        nv_gpudirect_clique,
>                                        qdev_prop_nv_gpudirect_clique, uint8_t),
>     #ifdef CONFIG_IOMMUFD
>         DEFINE_PROP_LINK("iommufd", VFIOPCIDevice, vbasedev.iommufd,
>                          TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *),
>     #endif
>         DEFINE_PROP_BOOL("skip-vsc-check", VFIOPCIDevice, skip_vsc_check, true),
>     };
> Graphic property and host device definitions are excluded from the
> base class it seems. This might fit vfio-user needs but it looks
> like a quick hack from the vfio-pci side. It needs more work.

Can you suggest a preferred approach? I'm definitely not wedded to the current
way (after all, I didn't write it !), but I'm not sure how else we could do it.

Perhaps if there's some way to deregister properties when vfio-user
instantiates?

> > > Can you remind me why the vfio-pci class for vfio-user can not
> > > inherit directly from vfio-pci ?
> > 
> > For the above reason: we'd inherit many properties that don't work for
> > vfio-user.
> 
> What do you mean by "don't work" ? functionally irrelevant ?

I don't know the answer to that in general. Certainly some are just irrelevant
(like sysfsdev), but it's entirely possible the other stuff actively breaks.
Presumably you agree it's not good to introduce potential footguns for users
here?

regards
john
Re: [PATCH 08/14] vfio: add vfio-pci-base class
Posted by Cédric Le Goater 6 months, 3 weeks ago
On 4/25/25 15:01, John Levon wrote:
> On Fri, Apr 25, 2025 at 02:46:48PM +0200, Cédric Le Goater wrote:
> 
>> After this patch, here is what we have for the base class :
>>      static const Property vfio_pci_base_dev_properties[] = {
>>          DEFINE_PROP_ON_OFF_AUTO("x-pre-copy-dirty-page-tracking", VFIOPCIDevice,
>>                                  vbasedev.pre_copy_dirty_page_tracking,
>>                                  ON_OFF_AUTO_ON),
>>          DEFINE_PROP_ON_OFF_AUTO("x-device-dirty-page-tracking", VFIOPCIDevice,
>>                                  vbasedev.device_dirty_page_tracking,
>>                                  ON_OFF_AUTO_ON),
>>          DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIOPCIDevice,
>>                             intx.mmap_timeout, 1100),
>>          DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
>>                                  vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
>>          DEFINE_PROP("x-migration-multifd-transfer", VFIOPCIDevice,
>>                      vbasedev.migration_multifd_transfer,
>>                      vfio_pci_migration_multifd_transfer_prop, OnOffAuto,
>>                      .set_default = true, .defval.i = ON_OFF_AUTO_AUTO),
>>          DEFINE_PROP_BOOL("migration-events", VFIOPCIDevice,
>>                           vbasedev.migration_events, false),
>>          DEFINE_PROP_BOOL("x-no-mmap", VFIOPCIDevice, vbasedev.no_mmap, false),
>>          DEFINE_PROP_BOOL("x-balloon-allowed", VFIOPCIDevice,
>>                           vbasedev.ram_block_discard_allowed, false),
>>          DEFINE_PROP_BOOL("x-no-kvm-intx", VFIOPCIDevice, no_kvm_intx, false),
>>          DEFINE_PROP_BOOL("x-no-kvm-msi", VFIOPCIDevice, no_kvm_msi, false),
>>          DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false),
>>          DEFINE_PROP_BOOL("x-no-kvm-ioeventfd", VFIOPCIDevice, no_kvm_ioeventfd,
>>                           false),
>>          DEFINE_PROP_BOOL("x-no-vfio-ioeventfd", VFIOPCIDevice, no_vfio_ioeventfd,
>>                           false),
>>          DEFINE_PROP_UINT32("x-pci-vendor-id", VFIOPCIDevice, vendor_id, PCI_ANY_ID),
>>          DEFINE_PROP_UINT32("x-pci-device-id", VFIOPCIDevice, device_id, PCI_ANY_ID),
>>          DEFINE_PROP_UINT32("x-pci-sub-vendor-id", VFIOPCIDevice,
>>                             sub_vendor_id, PCI_ANY_ID),
>>          DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
>>                             sub_device_id, PCI_ANY_ID),
>>          DEFINE_PROP_OFF_AUTO_PCIBAR("x-msix-relocation", VFIOPCIDevice, msix_relo,
>>                                      OFF_AUTO_PCIBAR_OFF),
>>      };
>> and for vfio-pci :
>>      static const Property vfio_pci_dev_properties[] = {
>>          DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIOPCIDevice, host),
>>          DEFINE_PROP_UUID_NODEFAULT("vf-token", VFIOPCIDevice, vf_token),
>>          DEFINE_PROP_STRING("sysfsdev", VFIOPCIDevice, vbasedev.sysfsdev),
>>          DEFINE_PROP_ON_OFF_AUTO("display", VFIOPCIDevice,
>>                                  display, ON_OFF_AUTO_OFF),
>>          DEFINE_PROP_UINT32("xres", VFIOPCIDevice, display_xres, 0),
>>          DEFINE_PROP_UINT32("yres", VFIOPCIDevice, display_yres, 0),
>>          DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features,
>>                          VFIO_FEATURE_ENABLE_VGA_BIT, false),
>>          DEFINE_PROP_BIT("x-req", VFIOPCIDevice, features,
>>                          VFIO_FEATURE_ENABLE_REQ_BIT, true),
>>          DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features,
>>                          VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
>>          DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
>>          DEFINE_PROP_BIT("x-igd-lpc", VFIOPCIDevice, features,
>>                          VFIO_FEATURE_ENABLE_IGD_LPC_BIT, false),
>>          DEFINE_PROP_ON_OFF_AUTO("x-igd-legacy-mode", VFIOPCIDevice,
>>                                  igd_legacy_mode, ON_OFF_AUTO_AUTO),
>>          DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
>>                           no_geforce_quirks, false),
>>          DEFINE_PROP_UNSIGNED_NODEFAULT("x-nv-gpudirect-clique", VFIOPCIDevice,
>>                                         nv_gpudirect_clique,
>>                                         qdev_prop_nv_gpudirect_clique, uint8_t),
>>      #ifdef CONFIG_IOMMUFD
>>          DEFINE_PROP_LINK("iommufd", VFIOPCIDevice, vbasedev.iommufd,
>>                           TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *),
>>      #endif
>>          DEFINE_PROP_BOOL("skip-vsc-check", VFIOPCIDevice, skip_vsc_check, true),
>>      };
>> Graphic property and host device definitions are excluded from the
>> base class it seems. This might fit vfio-user needs but it looks
>> like a quick hack from the vfio-pci side. It needs more work.
> 
> Can you suggest a preferred approach? I'm definitely not wedded to the current
> way (after all, I didn't write it !), but I'm not sure how else we could do it.
> 
> Perhaps if there's some way to deregister properties when vfio-user
> instantiates?
> 
>>>> Can you remind me why the vfio-pci class for vfio-user can not
>>>> inherit directly from vfio-pci ?
>>>
>>> For the above reason: we'd inherit many properties that don't work for
>>> vfio-user.
>>
>> What do you mean by "don't work" ? functionally irrelevant ?
> 
> I don't know the answer to that in general. Certainly some are just irrelevant
> (like sysfsdev), but it's entirely possible the other stuff actively breaks.
> Presumably you agree it's not good to introduce potential footguns for users
> here?
Do we know which properties are required for the vfio-user variant of the
vfio-pci device ?

I'd be tempted to start with an empty abstract vfio-pci-base device class.
This wouldn't change the current vfio-pci device much, and the vfio-user
variant would duplicate the necessary properties.


Thanks,

C.