From: Jagannathan Raman <jag.raman@oracle.com>
Split out code specific to the kernel-side vfio implementation from the
VFIOPCIDevice class into a VFIOKernelPCIDevice. The forthcoming
VFIOUserPCIDevice will share the base VFIOPCIDevice class.
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/helpers.c | 2 +-
hw/vfio/pci.c | 107 ++++++++++++++++++++++++++++------------------
hw/vfio/pci.h | 16 ++++++-
3 files changed, 80 insertions(+), 45 deletions(-)
diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 3c923d23b9..94bbc5747c 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -744,7 +744,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(obj)->device.vbasedev;
} else {
return NULL;
}
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index a4f99fc5e0..812743e9dd 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -239,7 +239,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) {
@@ -514,7 +514,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);
@@ -619,7 +619,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);
@@ -1167,7 +1167,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;
@@ -1213,7 +1213,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);
@@ -1246,7 +1246,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);
@@ -3084,7 +3084,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];
@@ -3274,7 +3274,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);
@@ -3292,7 +3292,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);
@@ -3316,7 +3316,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);
@@ -3356,7 +3356,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,
@@ -3377,28 +3377,15 @@ static void vfio_instance_init(Object *obj)
pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
}
-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_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
DEFINE_PROP_BOOL("migration-events", VFIOPCIDevice,
@@ -3409,8 +3396,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,
@@ -3421,12 +3406,57 @@ 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_OFF_AUTO_PCIBAR("x-msix-relocation", VFIOPCIDevice, msix_relo,
+ OFF_AUTO_PCIBAR_OFF),
+};
+
+
+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_props(dc, vfio_pci_base_dev_properties);
+ dc->desc = "VFIO PCI base device";
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ pdc->exit = vfio_exitfn;
+ pdc->config_read = vfio_pci_read_config;
+ pdc->config_write = vfio_pci_write_config;
+}
+
+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_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
+ no_geforce_quirks, false),
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 *),
@@ -3437,7 +3467,8 @@ static const Property vfio_pci_dev_properties[] = {
#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);
+ VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj);
+ vfio_device_set_fd(&vdev->vbasedev, str, errp);
}
#endif
@@ -3452,25 +3483,16 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
object_class_property_add_str(klass, "fd", NULL, vfio_pci_set_fd);
#endif
dc->desc = "VFIO-based PCI device assignment";
- 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;
}
static const TypeInfo vfio_pci_dev_info = {
.name = TYPE_VFIO_PCI,
- .parent = TYPE_PCI_DEVICE,
- .instance_size = sizeof(VFIOPCIDevice),
+ .parent = TYPE_VFIO_PCI_BASE,
+ .instance_size = sizeof(VFIOKernelPCIDevice),
.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[] = {
@@ -3490,12 +3512,13 @@ static void vfio_pci_nohotplug_dev_class_init(ObjectClass *klass, void *data)
static const TypeInfo vfio_pci_nohotplug_dev_info = {
.name = TYPE_VFIO_PCI_NOHOTPLUG,
.parent = TYPE_VFIO_PCI,
- .instance_size = sizeof(VFIOPCIDevice),
+ .instance_size = sizeof(VFIOKernelPCIDevice),
.class_init = vfio_pci_nohotplug_dev_class_init,
};
static void register_vfio_pci_dev_type(void)
{
+ 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 43c166680a..8e79740ddb 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -116,8 +116,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;
@@ -182,6 +187,13 @@ struct VFIOPCIDevice {
Notifier irqchip_change_notifier;
};
+#define TYPE_VFIO_PCI "vfio-pci"
+OBJECT_DECLARE_SIMPLE_TYPE(VFIOKernelPCIDevice, VFIO_PCI)
+
+struct VFIOKernelPCIDevice {
+ VFIOPCIDevice device;
+};
+
/* 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
On 2/19/25 15:48, John Levon wrote:
> From: Jagannathan Raman <jag.raman@oracle.com>
>
> Split out code specific to the kernel-side vfio implementation from the
> VFIOPCIDevice class into a VFIOKernelPCIDevice. The forthcoming
> VFIOUserPCIDevice will share the base VFIOPCIDevice class.
The new VFIOKernelPCIDevice struct is not needed. Please drop it.
I am not sure the new TYPE_VFIO_PCI_BASE class is needed too.
Are the properties the only difference ?
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/helpers.c | 2 +-
> hw/vfio/pci.c | 107 ++++++++++++++++++++++++++++------------------
> hw/vfio/pci.h | 16 ++++++-
> 3 files changed, 80 insertions(+), 45 deletions(-)
>
> diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
> index 3c923d23b9..94bbc5747c 100644
> --- a/hw/vfio/helpers.c
> +++ b/hw/vfio/helpers.c
> @@ -744,7 +744,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(obj)->device.vbasedev;
> } else {
> return NULL;
> }
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index a4f99fc5e0..812743e9dd 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -239,7 +239,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) {
> @@ -514,7 +514,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);
> @@ -619,7 +619,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);
> @@ -1167,7 +1167,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;
> @@ -1213,7 +1213,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);
> @@ -1246,7 +1246,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);
> @@ -3084,7 +3084,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];
> @@ -3274,7 +3274,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);
> @@ -3292,7 +3292,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);
> @@ -3316,7 +3316,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);
>
> @@ -3356,7 +3356,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,
> @@ -3377,28 +3377,15 @@ static void vfio_instance_init(Object *obj)
> pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
> }
>
> -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_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
> vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
> DEFINE_PROP_BOOL("migration-events", VFIOPCIDevice,
> @@ -3409,8 +3396,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,
> @@ -3421,12 +3406,57 @@ 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_OFF_AUTO_PCIBAR("x-msix-relocation", VFIOPCIDevice, msix_relo,
> + OFF_AUTO_PCIBAR_OFF),
> +};
> +
> +
> +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_props(dc, vfio_pci_base_dev_properties);
> + dc->desc = "VFIO PCI base device";
> + set_bit(DEVICE_CATEGORY_MISC, dc->categories);
> + pdc->exit = vfio_exitfn;
> + pdc->config_read = vfio_pci_read_config;
> + pdc->config_write = vfio_pci_write_config;
> +}
> +
> +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_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
> + no_geforce_quirks, false),
> 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 *),
> @@ -3437,7 +3467,8 @@ static const Property vfio_pci_dev_properties[] = {
> #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);
> + VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj);
> + vfio_device_set_fd(&vdev->vbasedev, str, errp);
> }
> #endif
>
> @@ -3452,25 +3483,16 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
> object_class_property_add_str(klass, "fd", NULL, vfio_pci_set_fd);
> #endif
> dc->desc = "VFIO-based PCI device assignment";
> - 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;
> }
>
> static const TypeInfo vfio_pci_dev_info = {
> .name = TYPE_VFIO_PCI,
> - .parent = TYPE_PCI_DEVICE,
> - .instance_size = sizeof(VFIOPCIDevice),
> + .parent = TYPE_VFIO_PCI_BASE,
> + .instance_size = sizeof(VFIOKernelPCIDevice),
> .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[] = {
> @@ -3490,12 +3512,13 @@ static void vfio_pci_nohotplug_dev_class_init(ObjectClass *klass, void *data)
> static const TypeInfo vfio_pci_nohotplug_dev_info = {
> .name = TYPE_VFIO_PCI_NOHOTPLUG,
> .parent = TYPE_VFIO_PCI,
> - .instance_size = sizeof(VFIOPCIDevice),
> + .instance_size = sizeof(VFIOKernelPCIDevice),
> .class_init = vfio_pci_nohotplug_dev_class_init,
> };
>
> static void register_vfio_pci_dev_type(void)
> {
> + 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 43c166680a..8e79740ddb 100644
> --- a/hw/vfio/pci.h
> +++ b/hw/vfio/pci.h
> @@ -116,8 +116,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;
> @@ -182,6 +187,13 @@ struct VFIOPCIDevice {
> Notifier irqchip_change_notifier;
> };
>
> +#define TYPE_VFIO_PCI "vfio-pci"
> +OBJECT_DECLARE_SIMPLE_TYPE(VFIOKernelPCIDevice, VFIO_PCI)
> +
> +struct VFIOKernelPCIDevice {
> + VFIOPCIDevice device;
> +};
> +
> /* 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)
> {
On Thu, Apr 03, 2025 at 07:13:30PM +0200, Cédric Le Goater wrote: > On 2/19/25 15:48, John Levon wrote: > > From: Jagannathan Raman <jag.raman@oracle.com> > > > > Split out code specific to the kernel-side vfio implementation from the > > VFIOPCIDevice class into a VFIOKernelPCIDevice. The forthcoming > > VFIOUserPCIDevice will share the base VFIOPCIDevice class. > > The new VFIOKernelPCIDevice struct is not needed. Please drop it. I presume the idea was if something was ever needed in the struct that was kernel vfio specific, it could go there. But sure. > I am not sure the new TYPE_VFIO_PCI_BASE class is needed too. > Are the properties the only difference ? I'm not sure if you're talking about the type specifically (a bit sketchy on how qemu's klass/type system works) or the existence of the base/kernel/user separation at all. If it's possible to set up vfio_user_pci_dev_info and its callbacks without needing a sub-type then maybe not? Honestly I'm not really sure why we have sub-classes and inheritance like this. regards john
On 4/3/25 20:08, John Levon wrote: > On Thu, Apr 03, 2025 at 07:13:30PM +0200, Cédric Le Goater wrote: > >> On 2/19/25 15:48, John Levon wrote: >>> From: Jagannathan Raman <jag.raman@oracle.com> >>> >>> Split out code specific to the kernel-side vfio implementation from the >>> VFIOPCIDevice class into a VFIOKernelPCIDevice. The forthcoming >>> VFIOUserPCIDevice will share the base VFIOPCIDevice class. >> >> The new VFIOKernelPCIDevice struct is not needed. Please drop it. > > I presume the idea was if something was ever needed in the struct that was > kernel vfio specific, it could go there. But sure. > >> I am not sure the new TYPE_VFIO_PCI_BASE class is needed too. >> Are the properties the only difference ? > > I'm not sure if you're talking about the type specifically (a bit sketchy on how > qemu's klass/type system works) or the existence of the base/kernel/user > separation at all. I am talking about the base/kernel/user separation. > If it's possible to set up vfio_user_pci_dev_info and its callbacks without > needing a sub-type then maybe not? I think the vfio-user-device could inherit directly from vfio-pci and override the io ops callbacks. It would minimize the changes. > Honestly I'm not really sure why we have sub-classes and inheritance like this. The VFIO Devices have a double nature : VFIO and a bus device nature (PCI, AP, etc) and multi-inheritance is not (well) supported by QOM. We have interfaces but they are stateless. Thanks, C.
On Fri, Apr 04, 2025 at 02:49:40PM +0200, Cédric Le Goater wrote: > > If it's possible to set up vfio_user_pci_dev_info and its callbacks without > > needing a sub-type then maybe not? > > I think the vfio-user-device could inherit directly from vfio-pci > and override the io ops callbacks. It would minimize the changes. We'd get all the kernel-vfio specific properties then though? regards john
On 4/4/25 16:21, John Levon wrote: > On Fri, Apr 04, 2025 at 02:49:40PM +0200, Cédric Le Goater wrote: > >>> If it's possible to set up vfio_user_pci_dev_info and its callbacks without >>> needing a sub-type then maybe not? >> >> I think the vfio-user-device could inherit directly from vfio-pci >> and override the io ops callbacks. It would minimize the changes. > > We'd get all the kernel-vfio specific properties then though? OK. That's what I thought. It was not clear in the diff. Let's give it a try in the next spin but please remove the VFIOKernelPCIDevice type. it is not needed. Thanks, C.
On Fri, Apr 04, 2025 at 04:48:10PM +0200, Cédric Le Goater wrote: > On 4/4/25 16:21, John Levon wrote: > > On Fri, Apr 04, 2025 at 02:49:40PM +0200, Cédric Le Goater wrote: > > > > > > If it's possible to set up vfio_user_pci_dev_info and its callbacks without > > > > needing a sub-type then maybe not? > > > > > > I think the vfio-user-device could inherit directly from vfio-pci > > > and override the io ops callbacks. It would minimize the changes. > > > > We'd get all the kernel-vfio specific properties then though? > > OK. That's what I thought. It was not clear in the diff. > > Let's give it a try in the next spin but please remove the > VFIOKernelPCIDevice type. it is not needed. Sure thanks john
© 2016 - 2026 Red Hat, Inc.