@samitouri / QOSamiQemu / commits / fa1ce94ea8

intel_iommu_accel: Add pasid bits size check

If pasid bits size is bigger than host side, host could fail to emulate all bindings in guest. Add a check to fail device plug early. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Tested-by: Xudong Hao <xudong.hao@intel.com> Reviewed-by: Clement Mathieu--Drif <clement.mathieu--drif@bull.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20260527054658.1021096-17-zhenzhong.duan@intel.com>

Zhenzhong Duan committed May 27, 2026 at 01:46 UTC fa1ce94ea83d857bd541818ff7bdbb0f95eed998
2 files changed +9
hw/i386/intel_iommu_accel.c
+8
@@ -22,6 +22,7 @@ bool vtd_check_hiod_accel(IntelIOMMUState *s, VTDHostIOMMUDevice *vtd_hiod,
22 HostIOMMUDevice *hiod = vtd_hiod->hiod;
23 struct HostIOMMUDeviceCaps *caps = &hiod->caps;
24 struct iommu_hw_info_vtd *vtd = &caps->vendor_caps.vtd;
25 + uint8_t hpasid = VTD_ECAP_GET_PSS(vtd->ecap_reg) + 1;
26 PCIBus *bus = vtd_hiod->bus;
27 PCIDevice *pdev = bus->devices[vtd_hiod->devfn];
28
@@ -42,6 +43,13 @@ bool vtd_check_hiod_accel(IntelIOMMUState *s, VTDHostIOMMUDevice *vtd_hiod,
43 return false;
44 }
45
46 + /* Only do the check when host device support PASIDs */
47 + if (caps->max_pasid_log2 && s->pasid > hpasid) {
48 + error_setg(errp, "PASID bits size %d > host IOMMU PASID bits size %d",
49 + s->pasid, hpasid);
50 + return false;
51 + }
52 +
53 if (pci_device_get_iommu_bus_devfn(pdev, &bus, NULL, NULL)) {
54 error_setg(errp, "Host device downstream to a PCI bridge is "
55 "unsupported when fsts=on");
hw/i386/intel_iommu_internal.h
+1
@@ -196,6 +196,7 @@
196 #define VTD_ECAP_SRS (1ULL << 31)
197 #define VTD_ECAP_NWFS (1ULL << 33)
198 #define VTD_ECAP_SET_PSS(x, v) ((x)->ecap = deposit64((x)->ecap, 35, 5, v))
199 +#define VTD_ECAP_GET_PSS(ecap) extract64(ecap, 35, 5)
200 #define VTD_ECAP_PASID (1ULL << 40)
201 #define VTD_ECAP_PDS (1ULL << 42)
202 #define VTD_ECAP_SMTS (1ULL << 43)