From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Implement get_host_iommu_quirks() callback to retrieve the vendor specific
hardware information data and convert it into bitmaps defined with enum
host_iommu_quirks. It will be used by VFIO in subsequent patch.
Suggested-by: Eric Auger <eric.auger@redhat.com>
Suggested-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Link: https://lore.kernel.org/qemu-devel/20260106062808.316574-3-zhenzhong.duan@intel.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
---
hw/i386/intel_iommu_accel.h | 5 +++++
hw/i386/intel_iommu.c | 2 ++
hw/i386/intel_iommu_accel.c | 21 +++++++++++++++++++++
3 files changed, 28 insertions(+)
diff --git a/hw/i386/intel_iommu_accel.h b/hw/i386/intel_iommu_accel.h
index 6dec8788f18d0196550b3d0047dc5a5b29ed2c6b..e5f0b077b4b9ab7a58796107e78ab8a7d0a0bd20 100644
--- a/hw/i386/intel_iommu_accel.h
+++ b/hw/i386/intel_iommu_accel.h
@@ -20,6 +20,7 @@ bool vtd_propagate_guest_pasid(VTDAddressSpace *vtd_as, Error **errp);
void vtd_flush_host_piotlb_all_locked(IntelIOMMUState *s, uint16_t domain_id,
uint32_t pasid, hwaddr addr,
uint64_t npages, bool ih);
+void vtd_iommu_ops_update_accel(PCIIOMMUOps *ops);
#else
static inline bool vtd_check_hiod_accel(IntelIOMMUState *s,
VTDHostIOMMUDevice *vtd_hiod,
@@ -47,5 +48,9 @@ static inline void vtd_flush_host_piotlb_all_locked(IntelIOMMUState *s,
uint64_t npages, bool ih)
{
}
+
+static inline void vtd_iommu_ops_update_accel(PCIIOMMUOps *ops)
+{
+}
#endif
#endif
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index bb21ae1743d2bf0dc91c4fc18026f449a290814b..e8a6f50a5a03e71b5f6025dce5f9510e0a31f020 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -5590,6 +5590,8 @@ static void vtd_class_init(ObjectClass *klass, const void *data)
x86_class->int_remap = vtd_int_remap;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
dc->desc = "Intel IOMMU (VT-d) DMA Remapping device";
+
+ vtd_iommu_ops_update_accel(&vtd_iommu_ops);
}
static const TypeInfo vtd_info = {
diff --git a/hw/i386/intel_iommu_accel.c b/hw/i386/intel_iommu_accel.c
index 250232b5a979e9b34d161fde554fd0c64b0cd3d9..67d54849f2f08187629fca5e2c081f8dd003b6b2 100644
--- a/hw/i386/intel_iommu_accel.c
+++ b/hw/i386/intel_iommu_accel.c
@@ -12,6 +12,7 @@
#include "system/iommufd.h"
#include "intel_iommu_internal.h"
#include "intel_iommu_accel.h"
+#include "hw/core/iommu.h"
#include "hw/pci/pci_bus.h"
#include "trace.h"
@@ -249,3 +250,23 @@ void vtd_flush_host_piotlb_all_locked(IntelIOMMUState *s, uint16_t domain_id,
g_hash_table_foreach(s->vtd_address_spaces,
vtd_flush_host_piotlb_locked, &piotlb_info);
}
+
+static uint64_t vtd_get_host_iommu_quirks(uint32_t type,
+ void *caps, uint32_t size)
+{
+ struct iommu_hw_info_vtd *vtd = caps;
+ uint64_t quirks = 0;
+
+ if (type == IOMMU_HW_INFO_TYPE_INTEL_VTD &&
+ sizeof(struct iommu_hw_info_vtd) <= size &&
+ vtd->flags & IOMMU_HW_INFO_VTD_ERRATA_772415_SPR17) {
+ quirks |= HOST_IOMMU_QUIRK_NESTING_PARENT_BYPASS_RO;
+ }
+
+ return quirks;
+}
+
+void vtd_iommu_ops_update_accel(PCIIOMMUOps *ops)
+{
+ ops->get_host_iommu_quirks = vtd_get_host_iommu_quirks;
+}
--
2.52.0