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)