Initialize IOMMUFDDevice in vfio and pass to vIOMMU, so that vIOMMU could get hw IOMMU information.
In VFIO legacy backend mode, we still pass a NULL IOMMUFDDevice to vIOMMU, in case vIOMMU needs some processing for VFIO legacy backend mode. Originally-by: Yi Liu <yi.l....@intel.com> Signed-off-by: Nicolin Chen <nicol...@nvidia.com> Signed-off-by: Yi Sun <yi.y....@linux.intel.com> Signed-off-by: Zhenzhong Duan <zhenzhong.d...@intel.com> --- include/hw/vfio/vfio-common.h | 2 ++ hw/vfio/iommufd.c | 2 ++ hw/vfio/pci.c | 24 +++++++++++++++++++----- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index 9b7ef7d02b..fde0d0ca60 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -31,6 +31,7 @@ #endif #include "sysemu/sysemu.h" #include "hw/vfio/vfio-container-base.h" +#include "sysemu/iommufd_device.h" #define VFIO_MSG_PREFIX "vfio %s: " @@ -126,6 +127,7 @@ typedef struct VFIODevice { bool dirty_tracking; int devid; IOMMUFDBackend *iommufd; + IOMMUFDDevice idev; } VFIODevice; struct VFIODeviceOps { diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c index 9bfddc1360..cbd035f148 100644 --- a/hw/vfio/iommufd.c +++ b/hw/vfio/iommufd.c @@ -309,6 +309,7 @@ static int iommufd_cdev_attach(const char *name, VFIODevice *vbasedev, VFIOContainerBase *bcontainer; VFIOIOMMUFDContainer *container; VFIOAddressSpace *space; + IOMMUFDDevice *idev = &vbasedev->idev; struct vfio_device_info dev_info = { .argsz = sizeof(dev_info) }; int ret, devfd; uint32_t ioas_id; @@ -428,6 +429,7 @@ found_container: QLIST_INSERT_HEAD(&bcontainer->device_list, vbasedev, container_next); QLIST_INSERT_HEAD(&vfio_device_list, vbasedev, global_next); + iommufd_device_init(idev, sizeof(*idev), container->be, vbasedev->devid); trace_iommufd_cdev_device_info(vbasedev->name, devfd, vbasedev->num_irqs, vbasedev->num_regions, vbasedev->flags); return 0; diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index d7fe06715c..2c3a5d267b 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -3107,11 +3107,21 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) vfio_bars_register(vdev); - ret = vfio_add_capabilities(vdev, errp); + if (vbasedev->iommufd) { + ret = pci_device_set_iommu_device(pdev, &vbasedev->idev, errp); + } else { + ret = pci_device_set_iommu_device(pdev, 0, errp); + } if (ret) { + error_prepend(errp, "Failed to set iommu_device: "); goto out_teardown; } + ret = vfio_add_capabilities(vdev, errp); + if (ret) { + goto out_unset_idev; + } + if (vdev->vga) { vfio_vga_quirk_setup(vdev); } @@ -3128,7 +3138,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) error_setg(errp, "cannot support IGD OpRegion feature on hotplugged " "device"); - goto out_teardown; + goto out_unset_idev; } ret = vfio_get_dev_region_info(vbasedev, @@ -3137,13 +3147,13 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) if (ret) { error_setg_errno(errp, -ret, "does not support requested IGD OpRegion feature"); - goto out_teardown; + goto out_unset_idev; } ret = vfio_pci_igd_opregion_init(vdev, opregion, errp); g_free(opregion); if (ret) { - goto out_teardown; + goto out_unset_idev; } } @@ -3229,6 +3239,8 @@ out_deregister: if (vdev->intx.mmap_timer) { timer_free(vdev->intx.mmap_timer); } +out_unset_idev: + pci_device_unset_iommu_device(pdev); out_teardown: vfio_teardown_msi(vdev); vfio_bars_exit(vdev); @@ -3257,6 +3269,7 @@ static void vfio_instance_finalize(Object *obj) static void vfio_exitfn(PCIDevice *pdev) { VFIOPCIDevice *vdev = VFIO_PCI(pdev); + VFIODevice *vbasedev = &vdev->vbasedev; vfio_unregister_req_notifier(vdev); vfio_unregister_err_notifier(vdev); @@ -3271,7 +3284,8 @@ static void vfio_exitfn(PCIDevice *pdev) vfio_teardown_msi(vdev); vfio_pci_disable_rp_atomics(vdev); vfio_bars_exit(vdev); - vfio_migration_exit(&vdev->vbasedev); + vfio_migration_exit(vbasedev); + pci_device_unset_iommu_device(pdev); } static void vfio_pci_reset(DeviceState *dev) -- 2.34.1