It calls iommufd_backend_get_device_info() to get host IOMMU related information and translate it into HostIOMMUDeviceCaps for query with .check_cap().
Introduce macro VTD_MGAW_FROM_CAP to get MGAW which equals to (aw_bits - 1). Signed-off-by: Zhenzhong Duan <zhenzhong.d...@intel.com> --- include/hw/i386/intel_iommu.h | 1 + hw/vfio/iommufd.c | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 7fa0a695c8..7d694b0813 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -47,6 +47,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(IntelIOMMUState, INTEL_IOMMU_DEVICE) #define VTD_HOST_AW_48BIT 48 #define VTD_HOST_ADDRESS_WIDTH VTD_HOST_AW_39BIT #define VTD_HAW_MASK(aw) ((1ULL << (aw)) - 1) +#define VTD_MGAW_FROM_CAP(cap) ((cap >> 16) & 0x3fULL) #define DMAR_REPORT_F_INTR (1) diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c index 997f4ac43e..6bc2dc68f6 100644 --- a/hw/vfio/iommufd.c +++ b/hw/vfio/iommufd.c @@ -25,6 +25,7 @@ #include "qemu/cutils.h" #include "qemu/chardev_open.h" #include "pci.h" +#include "hw/i386/intel_iommu_internal.h" static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova, ram_addr_t size, void *vaddr, bool readonly) @@ -634,6 +635,48 @@ static void vfio_iommu_iommufd_class_init(ObjectClass *klass, void *data) vioc->pci_hot_reset = iommufd_cdev_pci_hot_reset; }; +static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque, + Error **errp) +{ + VFIODevice *vdev = opaque; + HostIOMMUDeviceIOMMUFD *idev = HOST_IOMMU_DEVICE_IOMMUFD(hiod); + HostIOMMUDeviceCaps *caps = &hiod->caps; + enum iommu_hw_info_type type; + union { + struct iommu_hw_info_vtd vtd; + } data; + int ret; + + HOST_IOMMU_DEVICE_IOMMUFD_VFIO(hiod)->vdev = vdev; + idev->iommufd = vdev->iommufd; + idev->devid = vdev->devid; + + ret = iommufd_backend_get_device_info(idev->iommufd, idev->devid, + &type, &data, sizeof(data), errp); + if (ret) { + return false; + } + + caps->type = type; + + switch (type) { + case IOMMU_HW_INFO_TYPE_INTEL_VTD: + caps->aw_bits = VTD_MGAW_FROM_CAP(data.vtd.cap_reg) + 1; + break; + case IOMMU_HW_INFO_TYPE_NONE: + break; + } + + return true; +} + +static void hiod_iommufd_vfio_class_init(ObjectClass *oc, void *data) +{ + HostIOMMUDeviceClass *hiodc = HOST_IOMMU_DEVICE_CLASS(oc); + + hiodc->realize = hiod_iommufd_vfio_realize; +}; + static const TypeInfo types[] = { { .name = TYPE_VFIO_IOMMU_IOMMUFD, @@ -643,6 +686,7 @@ static const TypeInfo types[] = { .name = TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO, .parent = TYPE_HOST_IOMMU_DEVICE_IOMMUFD, .instance_size = sizeof(HostIOMMUDeviceIOMMUFDVFIO), + .class_init = hiod_iommufd_vfio_class_init, } }; -- 2.34.1