@@ -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)
@@ -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,
}
};
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.duan@intel.com> --- include/hw/i386/intel_iommu.h | 1 + hw/vfio/iommufd.c | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+)