Hi Clement, Exactly, copied from PCIe spec:
Max PASID Width - Indicates the width of the PASID field supported by an applicable Endpoint Function. The value n indicates support for PASID values 0 through 2n -1 (inclusive). The value 0 indicates support for a single PASID (0). The value 20 indicates support for all PASID values (20 bits). This field must be between 0 and 20 (inclusive) BRs, Zhenzhong From: CLEMENT MATHIEU--DRIF <[email protected]> Sent: Wednesday, February 25, 2026 2:42 PM To: Duan, Zhenzhong <[email protected]>; [email protected] Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Tian, Kevin <[email protected]>; Liu, Yi L <[email protected]>; Hao, Xudong <[email protected]> Subject: Re: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check Hi Zhenzhong, Why do we capitalize the first letter of each word in "Max PASID Width"? I guess you try to match the pcie spec, but just want to confirm :) cmd ________________________________ From: Zhenzhong Duan <[email protected]<mailto:[email protected]>> Sent: 14 February 2026 04:41 To: [email protected]<mailto:[email protected]> <[email protected]<mailto:[email protected]>> Cc: [email protected]<mailto:[email protected]> <[email protected]<mailto:[email protected]>>; [email protected]<mailto:[email protected]> <[email protected]<mailto:[email protected]>>; [email protected]<mailto:[email protected]> <[email protected]<mailto:[email protected]>>; [email protected]<mailto:[email protected]> <[email protected]<mailto:[email protected]>>; [email protected]<mailto:[email protected]> <[email protected]<mailto:[email protected]>>; [email protected]<mailto:[email protected]> <[email protected]<mailto:[email protected]>>; [email protected]<mailto:[email protected]> <[email protected]<mailto:[email protected]>>; [email protected]<mailto:[email protected]> <[email protected]<mailto:[email protected]>>; [email protected]<mailto:[email protected]> <[email protected]<mailto:[email protected]>>; CLEMENT MATHIEU--DRIF <[email protected]<mailto:[email protected]>>; [email protected]<mailto:[email protected]> <[email protected]<mailto:[email protected]>>; [email protected]<mailto:[email protected]> <[email protected]<mailto:[email protected]>>; [email protected]<mailto:[email protected]> <[email protected]<mailto:[email protected]>>; Zhenzhong Duan <[email protected]<mailto:[email protected]>> Subject: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check Caution: External email. Do not open attachments or click links, unless this email comes from a known sender and you know the content is safe. 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. Pasid bits size should also be no more than 20 bits according to PCI spec. Signed-off-by: Zhenzhong Duan <[email protected]<mailto:[email protected]>> --- hw/i386/intel_iommu_internal.h | 1 + hw/i386/intel_iommu.c | 5 +++++ hw/i386/intel_iommu_accel.c | 8 ++++++++ 3 files changed, 14 insertions(+) diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index e4bcc884b0..e5518a94ea 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -195,6 +195,7 @@ #define VTD_ECAP_MHMV (15ULL << 20) #define VTD_ECAP_SRS (1ULL << 31) #define VTD_ECAP_NWFS (1ULL << 33) +#define VTD_ECAP_PSS(x) extract64(x, 35, 5) #define VTD_ECAP_PASID (1ULL << 40) #define VTD_ECAP_PDS (1ULL << 42) #define VTD_ECAP_SMTS (1ULL << 43) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 6483cb3d85..c1b31b17de 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -5545,6 +5545,11 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp) error_setg(errp, "Need to set scalable mode for PASID"); return false; } + if (s->pasid >= PCI_EXT_CAP_PASID_MAX_WIDTH) { + error_setg(errp, "PASID width %d, exceed Max PASID Width %d allowed " + "in PCI spec", s->pasid, PCI_EXT_CAP_PASID_MAX_WIDTH); + return false; + } if (s->svm) { if (!x86_iommu->dt_supported) { diff --git a/hw/i386/intel_iommu_accel.c b/hw/i386/intel_iommu_accel.c index acb1b1e238..15412123d5 100644 --- a/hw/i386/intel_iommu_accel.c +++ b/hw/i386/intel_iommu_accel.c @@ -44,6 +44,7 @@ bool vtd_check_hiod_accel(IntelIOMMUState *s, VTDHostIOMMUDevice *vtd_hiod, HostIOMMUDevice *hiod = vtd_hiod->hiod; struct HostIOMMUDeviceCaps *caps = &hiod->caps; struct iommu_hw_info_vtd *vtd = &caps->vendor_caps.vtd; + uint8_t hpasid = VTD_ECAP_PSS(vtd->ecap_reg) + 1; PCIBus *bus = vtd_hiod->bus; PCIDevice *pdev = bus->devices[vtd_hiod->devfn]; @@ -64,6 +65,13 @@ bool vtd_check_hiod_accel(IntelIOMMUState *s, VTDHostIOMMUDevice *vtd_hiod, return false; } + /* Only do the check when host device support PASIDs */ + if (caps->max_pasid_log2 && s->pasid > hpasid) { + error_setg(errp, "PASID bits size %d > host IOMMU PASID bits size %d", + s->pasid, hpasid); + return false; + } + if (pci_device_get_iommu_bus_devfn(pdev, &bus, NULL, NULL)) { error_setg(errp, "Host device downstream to a PCI bridge is " "unsupported when x-flts=on"); -- 2.47.3
