[RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check

Zhenzhong Duan posted 13 patches 1 month, 3 weeks ago
Maintainers: Yi Liu <yi.l.liu@intel.com>, Eric Auger <eric.auger@redhat.com>, Zhenzhong Duan <zhenzhong.duan@intel.com>, Peter Maydell <peter.maydell@linaro.org>, "Michael S. Tsirkin" <mst@redhat.com>, Jason Wang <jasowang@redhat.com>, "Clément Mathieu--Drif" <clement.mathieu--drif@eviden.com>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Paolo Bonzini <pbonzini@redhat.com>, Richard Henderson <richard.henderson@linaro.org>, Eduardo Habkost <eduardo@habkost.net>, Alex Williamson <alex@shazbot.org>, "Cédric Le Goater" <clg@redhat.com>
There is a newer version of this series
[RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check
Posted by Zhenzhong Duan 1 month, 3 weeks ago
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 <zhenzhong.duan@intel.com>
---
 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
Re: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check
Posted by CLEMENT MATHIEU--DRIF 1 month, 2 weeks ago
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 <zhenzhong.duan@intel.com>
Sent: 14 February 2026 04:41
To: qemu-devel@nongnu.org <qemu-devel@nongnu.org>
Cc: alex@shazbot.org <alex@shazbot.org>; clg@redhat.com <clg@redhat.com>; eric.auger@redhat.com <eric.auger@redhat.com>; mst@redhat.com <mst@redhat.com>; jasowang@redhat.com <jasowang@redhat.com>; jgg@nvidia.com <jgg@nvidia.com>; nicolinc@nvidia.com <nicolinc@nvidia.com>; skolothumtho@nvidia.com <skolothumtho@nvidia.com>; joao.m.martins@oracle.com <joao.m.martins@oracle.com>; CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>; kevin.tian@intel.com <kevin.tian@intel.com>; yi.l.liu@intel.com <yi.l.liu@intel.com>; xudong.hao@intel.com <xudong.hao@intel.com>; Zhenzhong Duan <zhenzhong.duan@intel.com>
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 <zhenzhong.duan@intel.com>
---
 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

RE: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check
Posted by Duan, Zhenzhong 1 month, 2 weeks ago
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 <clement.mathieu--drif@eviden.com>
Sent: Wednesday, February 25, 2026 2:42 PM
To: Duan, Zhenzhong <zhenzhong.duan@intel.com>; qemu-devel@nongnu.org
Cc: alex@shazbot.org; clg@redhat.com; eric.auger@redhat.com; mst@redhat.com; jasowang@redhat.com; jgg@nvidia.com; nicolinc@nvidia.com; skolothumtho@nvidia.com; joao.m.martins@oracle.com; Tian, Kevin <kevin.tian@intel.com>; Liu, Yi L <yi.l.liu@intel.com>; Hao, Xudong <xudong.hao@intel.com>
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 <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
Sent: 14 February 2026 04:41
To: qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org> <qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org>>
Cc: alex@shazbot.org<mailto:alex@shazbot.org> <alex@shazbot.org<mailto:alex@shazbot.org>>; clg@redhat.com<mailto:clg@redhat.com> <clg@redhat.com<mailto:clg@redhat.com>>; eric.auger@redhat.com<mailto:eric.auger@redhat.com> <eric.auger@redhat.com<mailto:eric.auger@redhat.com>>; mst@redhat.com<mailto:mst@redhat.com> <mst@redhat.com<mailto:mst@redhat.com>>; jasowang@redhat.com<mailto:jasowang@redhat.com> <jasowang@redhat.com<mailto:jasowang@redhat.com>>; jgg@nvidia.com<mailto:jgg@nvidia.com> <jgg@nvidia.com<mailto:jgg@nvidia.com>>; nicolinc@nvidia.com<mailto:nicolinc@nvidia.com> <nicolinc@nvidia.com<mailto:nicolinc@nvidia.com>>; skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com> <skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com>>; joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com> <joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com>>; CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com<mailto:clement.mathieu--drif@eviden.com>>; kevin.tian@intel.com<mailto:kevin.tian@intel.com> <kevin.tian@intel.com<mailto:kevin.tian@intel.com>>; yi.l.liu@intel.com<mailto:yi.l.liu@intel.com> <yi.l.liu@intel.com<mailto:yi.l.liu@intel.com>>; xudong.hao@intel.com<mailto:xudong.hao@intel.com> <xudong.hao@intel.com<mailto:xudong.hao@intel.com>>; Zhenzhong Duan <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
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 <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
---
 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
Re: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check
Posted by CLEMENT MATHIEU--DRIF 1 month, 2 weeks ago
Hi Zhenzhong,

In this hunk:

if (s->pasid >= PCI_EXT_CAP_PASID_MAX_WIDTH)

s->pasid comes from the prop and is the actual size right? not size - 1 ? Shouldn't the comparison be > instead of >= ?

cmd

________________________________
From: Duan, Zhenzhong <zhenzhong.duan@intel.com>
Sent: 26 February 2026 04:37
To: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>; qemu-devel@nongnu.org <qemu-devel@nongnu.org>
Cc: alex@shazbot.org <alex@shazbot.org>; clg@redhat.com <clg@redhat.com>; eric.auger@redhat.com <eric.auger@redhat.com>; mst@redhat.com <mst@redhat.com>; jasowang@redhat.com <jasowang@redhat.com>; jgg@nvidia.com <jgg@nvidia.com>; nicolinc@nvidia.com <nicolinc@nvidia.com>; skolothumtho@nvidia.com <skolothumtho@nvidia.com>; joao.m.martins@oracle.com <joao.m.martins@oracle.com>; Tian, Kevin <kevin.tian@intel.com>; Liu, Yi L <yi.l.liu@intel.com>; Hao, Xudong <xudong.hao@intel.com>
Subject: RE: [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.


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 <clement.mathieu--drif@eviden.com>
Sent: Wednesday, February 25, 2026 2:42 PM
To: Duan, Zhenzhong <zhenzhong.duan@intel.com>; qemu-devel@nongnu.org
Cc: alex@shazbot.org; clg@redhat.com; eric.auger@redhat.com; mst@redhat.com; jasowang@redhat.com; jgg@nvidia.com; nicolinc@nvidia.com; skolothumtho@nvidia.com; joao.m.martins@oracle.com; Tian, Kevin <kevin.tian@intel.com>; Liu, Yi L <yi.l.liu@intel.com>; Hao, Xudong <xudong.hao@intel.com>
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 <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
Sent: 14 February 2026 04:41
To: qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org> <qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org>>
Cc: alex@shazbot.org<mailto:alex@shazbot.org> <alex@shazbot.org<mailto:alex@shazbot.org>>; clg@redhat.com<mailto:clg@redhat.com> <clg@redhat.com<mailto:clg@redhat.com>>; eric.auger@redhat.com<mailto:eric.auger@redhat.com> <eric.auger@redhat.com<mailto:eric.auger@redhat.com>>; mst@redhat.com<mailto:mst@redhat.com> <mst@redhat.com<mailto:mst@redhat.com>>; jasowang@redhat.com<mailto:jasowang@redhat.com> <jasowang@redhat.com<mailto:jasowang@redhat.com>>; jgg@nvidia.com<mailto:jgg@nvidia.com> <jgg@nvidia.com<mailto:jgg@nvidia.com>>; nicolinc@nvidia.com<mailto:nicolinc@nvidia.com> <nicolinc@nvidia.com<mailto:nicolinc@nvidia.com>>; skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com> <skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com>>; joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com> <joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com>>; CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com<mailto:clement.mathieu--drif@eviden.com>>; kevin.tian@intel.com<mailto:kevin.tian@intel.com> <kevin.tian@intel.com<mailto:kevin.tian@intel.com>>; yi.l.liu@intel.com<mailto:yi.l.liu@intel.com> <yi.l.liu@intel.com<mailto:yi.l.liu@intel.com>>; xudong.hao@intel.com<mailto:xudong.hao@intel.com> <xudong.hao@intel.com<mailto:xudong.hao@intel.com>>; Zhenzhong Duan <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
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 <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
---
 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
RE: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check
Posted by Duan, Zhenzhong 1 month, 2 weeks ago
Oh, good catch! Will fix, thanks

BRs,
Zhenzhong

From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
Sent: Thursday, February 26, 2026 2:35 PM
To: Duan, Zhenzhong <zhenzhong.duan@intel.com>; qemu-devel@nongnu.org
Cc: alex@shazbot.org; clg@redhat.com; eric.auger@redhat.com; mst@redhat.com; jasowang@redhat.com; jgg@nvidia.com; nicolinc@nvidia.com; skolothumtho@nvidia.com; joao.m.martins@oracle.com; Tian, Kevin <kevin.tian@intel.com>; Liu, Yi L <yi.l.liu@intel.com>; Hao, Xudong <xudong.hao@intel.com>
Subject: Re: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check

Hi Zhenzhong,

In this hunk:

if (s->pasid >= PCI_EXT_CAP_PASID_MAX_WIDTH)

s->pasid comes from the prop and is the actual size right? not size - 1 ? Shouldn't the comparison be > instead of >= ?

cmd

________________________________
From: Duan, Zhenzhong <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
Sent: 26 February 2026 04:37
To: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com<mailto:clement.mathieu--drif@eviden.com>>; qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org> <qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org>>
Cc: alex@shazbot.org<mailto:alex@shazbot.org> <alex@shazbot.org<mailto:alex@shazbot.org>>; clg@redhat.com<mailto:clg@redhat.com> <clg@redhat.com<mailto:clg@redhat.com>>; eric.auger@redhat.com<mailto:eric.auger@redhat.com> <eric.auger@redhat.com<mailto:eric.auger@redhat.com>>; mst@redhat.com<mailto:mst@redhat.com> <mst@redhat.com<mailto:mst@redhat.com>>; jasowang@redhat.com<mailto:jasowang@redhat.com> <jasowang@redhat.com<mailto:jasowang@redhat.com>>; jgg@nvidia.com<mailto:jgg@nvidia.com> <jgg@nvidia.com<mailto:jgg@nvidia.com>>; nicolinc@nvidia.com<mailto:nicolinc@nvidia.com> <nicolinc@nvidia.com<mailto:nicolinc@nvidia.com>>; skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com> <skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com>>; joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com> <joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com>>; Tian, Kevin <kevin.tian@intel.com<mailto:kevin.tian@intel.com>>; Liu, Yi L <yi.l.liu@intel.com<mailto:yi.l.liu@intel.com>>; Hao, Xudong <xudong.hao@intel.com<mailto:xudong.hao@intel.com>>
Subject: RE: [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.


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 <clement.mathieu--drif@eviden.com<mailto:clement.mathieu--drif@eviden.com>>
Sent: Wednesday, February 25, 2026 2:42 PM
To: Duan, Zhenzhong <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>; qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org>
Cc: alex@shazbot.org<mailto:alex@shazbot.org>; clg@redhat.com<mailto:clg@redhat.com>; eric.auger@redhat.com<mailto:eric.auger@redhat.com>; mst@redhat.com<mailto:mst@redhat.com>; jasowang@redhat.com<mailto:jasowang@redhat.com>; jgg@nvidia.com<mailto:jgg@nvidia.com>; nicolinc@nvidia.com<mailto:nicolinc@nvidia.com>; skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com>; joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com>; Tian, Kevin <kevin.tian@intel.com<mailto:kevin.tian@intel.com>>; Liu, Yi L <yi.l.liu@intel.com<mailto:yi.l.liu@intel.com>>; Hao, Xudong <xudong.hao@intel.com<mailto:xudong.hao@intel.com>>
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 <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
Sent: 14 February 2026 04:41
To: qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org> <qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org>>
Cc: alex@shazbot.org<mailto:alex@shazbot.org> <alex@shazbot.org<mailto:alex@shazbot.org>>; clg@redhat.com<mailto:clg@redhat.com> <clg@redhat.com<mailto:clg@redhat.com>>; eric.auger@redhat.com<mailto:eric.auger@redhat.com> <eric.auger@redhat.com<mailto:eric.auger@redhat.com>>; mst@redhat.com<mailto:mst@redhat.com> <mst@redhat.com<mailto:mst@redhat.com>>; jasowang@redhat.com<mailto:jasowang@redhat.com> <jasowang@redhat.com<mailto:jasowang@redhat.com>>; jgg@nvidia.com<mailto:jgg@nvidia.com> <jgg@nvidia.com<mailto:jgg@nvidia.com>>; nicolinc@nvidia.com<mailto:nicolinc@nvidia.com> <nicolinc@nvidia.com<mailto:nicolinc@nvidia.com>>; skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com> <skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com>>; joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com> <joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com>>; CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com<mailto:clement.mathieu--drif@eviden.com>>; kevin.tian@intel.com<mailto:kevin.tian@intel.com> <kevin.tian@intel.com<mailto:kevin.tian@intel.com>>; yi.l.liu@intel.com<mailto:yi.l.liu@intel.com> <yi.l.liu@intel.com<mailto:yi.l.liu@intel.com>>; xudong.hao@intel.com<mailto:xudong.hao@intel.com> <xudong.hao@intel.com<mailto:xudong.hao@intel.com>>; Zhenzhong Duan <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
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 <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
---
 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
Re: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check
Posted by CLEMENT MATHIEU--DRIF 1 month, 2 weeks ago
Hi Zhenzhong,

I'm a bit confused about this patch.

All the other VTD_ECAP_* are masks for the ecap qword.
The purpose of this new definition of ECAP_PSS differs a bit as it extracts the field itself :/

cmd

________________________________
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Sent: 14 February 2026 04:41
To: qemu-devel@nongnu.org <qemu-devel@nongnu.org>
Cc: alex@shazbot.org <alex@shazbot.org>; clg@redhat.com <clg@redhat.com>; eric.auger@redhat.com <eric.auger@redhat.com>; mst@redhat.com <mst@redhat.com>; jasowang@redhat.com <jasowang@redhat.com>; jgg@nvidia.com <jgg@nvidia.com>; nicolinc@nvidia.com <nicolinc@nvidia.com>; skolothumtho@nvidia.com <skolothumtho@nvidia.com>; joao.m.martins@oracle.com <joao.m.martins@oracle.com>; CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>; kevin.tian@intel.com <kevin.tian@intel.com>; yi.l.liu@intel.com <yi.l.liu@intel.com>; xudong.hao@intel.com <xudong.hao@intel.com>; Zhenzhong Duan <zhenzhong.duan@intel.com>
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 <zhenzhong.duan@intel.com>
---
 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

RE: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check
Posted by Duan, Zhenzhong 1 month, 2 weeks ago
Hi Clement,

This is to follow Eric's suggestion in previous iommufd nesting series
where he suggested to use extra32/64 syntax, copied here:

+#define VTD_INV_DESC_PASIDC_DSI        (0ULL << 4)
+#define VTD_INV_DESC_PASIDC_PASID_SI   (1ULL << 4)
+#define VTD_INV_DESC_PASIDC_GLOBAL     (3ULL << 4)
as those are values for the granularity field using

VTD_INV_DESC_PASIDC_G_* look relevant to me.

I think you would gain in readability if you adopt extract32/64 syntax
like in hw/arm/smmuv3-internal.h
Looks more readable to me.

See https://lore.kernel.org/qemu-devel/2cbb91d3-9acc-4e7a-9a0a-19d9b5efe21b@redhat.com/ for details.

BRs,
Zhenzhong

From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
Sent: Wednesday, February 25, 2026 2:38 PM
To: Duan, Zhenzhong <zhenzhong.duan@intel.com>; qemu-devel@nongnu.org
Cc: alex@shazbot.org; clg@redhat.com; eric.auger@redhat.com; mst@redhat.com; jasowang@redhat.com; jgg@nvidia.com; nicolinc@nvidia.com; skolothumtho@nvidia.com; joao.m.martins@oracle.com; Tian, Kevin <kevin.tian@intel.com>; Liu, Yi L <yi.l.liu@intel.com>; Hao, Xudong <xudong.hao@intel.com>
Subject: Re: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check

Hi Zhenzhong,

I'm a bit confused about this patch.

All the other VTD_ECAP_* are masks for the ecap qword.
The purpose of this new definition of ECAP_PSS differs a bit as it extracts the field itself :/

cmd

________________________________
From: Zhenzhong Duan <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
Sent: 14 February 2026 04:41
To: qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org> <qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org>>
Cc: alex@shazbot.org<mailto:alex@shazbot.org> <alex@shazbot.org<mailto:alex@shazbot.org>>; clg@redhat.com<mailto:clg@redhat.com> <clg@redhat.com<mailto:clg@redhat.com>>; eric.auger@redhat.com<mailto:eric.auger@redhat.com> <eric.auger@redhat.com<mailto:eric.auger@redhat.com>>; mst@redhat.com<mailto:mst@redhat.com> <mst@redhat.com<mailto:mst@redhat.com>>; jasowang@redhat.com<mailto:jasowang@redhat.com> <jasowang@redhat.com<mailto:jasowang@redhat.com>>; jgg@nvidia.com<mailto:jgg@nvidia.com> <jgg@nvidia.com<mailto:jgg@nvidia.com>>; nicolinc@nvidia.com<mailto:nicolinc@nvidia.com> <nicolinc@nvidia.com<mailto:nicolinc@nvidia.com>>; skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com> <skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com>>; joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com> <joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com>>; CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com<mailto:clement.mathieu--drif@eviden.com>>; kevin.tian@intel.com<mailto:kevin.tian@intel.com> <kevin.tian@intel.com<mailto:kevin.tian@intel.com>>; yi.l.liu@intel.com<mailto:yi.l.liu@intel.com> <yi.l.liu@intel.com<mailto:yi.l.liu@intel.com>>; xudong.hao@intel.com<mailto:xudong.hao@intel.com> <xudong.hao@intel.com<mailto:xudong.hao@intel.com>>; Zhenzhong Duan <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
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 <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
---
 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
Re: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check
Posted by CLEMENT MATHIEU--DRIF 1 month, 2 weeks ago
Hi Zhenzhong,

Oh ok, I did not remember this comment from Eric, my mistake.

From what I see in the smmu:
- "getters" use extract and are named according to the field they extract.
- "setters" use deposit and use the following naming pattern "XXX_SET_THENAME"

Do you think we should follow the same way?

cmd

________________________________
From: Duan, Zhenzhong <zhenzhong.duan@intel.com>
Sent: 26 February 2026 04:12
To: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>; qemu-devel@nongnu.org <qemu-devel@nongnu.org>
Cc: alex@shazbot.org <alex@shazbot.org>; clg@redhat.com <clg@redhat.com>; eric.auger@redhat.com <eric.auger@redhat.com>; mst@redhat.com <mst@redhat.com>; jasowang@redhat.com <jasowang@redhat.com>; jgg@nvidia.com <jgg@nvidia.com>; nicolinc@nvidia.com <nicolinc@nvidia.com>; skolothumtho@nvidia.com <skolothumtho@nvidia.com>; joao.m.martins@oracle.com <joao.m.martins@oracle.com>; Tian, Kevin <kevin.tian@intel.com>; Liu, Yi L <yi.l.liu@intel.com>; Hao, Xudong <xudong.hao@intel.com>
Subject: RE: [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.


Hi Clement,



This is to follow Eric’s suggestion in previous iommufd nesting series

where he suggested to use extra32/64 syntax, copied here:



+#define VTD_INV_DESC_PASIDC_DSI        (0ULL << 4)

+#define VTD_INV_DESC_PASIDC_PASID_SI   (1ULL << 4)

+#define VTD_INV_DESC_PASIDC_GLOBAL     (3ULL << 4)

as those are values for the granularity field using



VTD_INV_DESC_PASIDC_G_* look relevant to me.



I think you would gain in readability if you adopt extract32/64 syntax

like in hw/arm/smmuv3-internal.h

Looks more readable to me.



See https://lore.kernel.org/qemu-devel/2cbb91d3-9acc-4e7a-9a0a-19d9b5efe21b@redhat.com/ for details.



BRs,

Zhenzhong



From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
Sent: Wednesday, February 25, 2026 2:38 PM
To: Duan, Zhenzhong <zhenzhong.duan@intel.com>; qemu-devel@nongnu.org
Cc: alex@shazbot.org; clg@redhat.com; eric.auger@redhat.com; mst@redhat.com; jasowang@redhat.com; jgg@nvidia.com; nicolinc@nvidia.com; skolothumtho@nvidia.com; joao.m.martins@oracle.com; Tian, Kevin <kevin.tian@intel.com>; Liu, Yi L <yi.l.liu@intel.com>; Hao, Xudong <xudong.hao@intel.com>
Subject: Re: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check



Hi Zhenzhong,



I'm a bit confused about this patch.



All the other VTD_ECAP_* are masks for the ecap qword.

The purpose of this new definition of ECAP_PSS differs a bit as it extracts the field itself :/



cmd



________________________________

From: Zhenzhong Duan <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
Sent: 14 February 2026 04:41
To: qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org> <qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org>>
Cc: alex@shazbot.org<mailto:alex@shazbot.org> <alex@shazbot.org<mailto:alex@shazbot.org>>; clg@redhat.com<mailto:clg@redhat.com> <clg@redhat.com<mailto:clg@redhat.com>>; eric.auger@redhat.com<mailto:eric.auger@redhat.com> <eric.auger@redhat.com<mailto:eric.auger@redhat.com>>; mst@redhat.com<mailto:mst@redhat.com> <mst@redhat.com<mailto:mst@redhat.com>>; jasowang@redhat.com<mailto:jasowang@redhat.com> <jasowang@redhat.com<mailto:jasowang@redhat.com>>; jgg@nvidia.com<mailto:jgg@nvidia.com> <jgg@nvidia.com<mailto:jgg@nvidia.com>>; nicolinc@nvidia.com<mailto:nicolinc@nvidia.com> <nicolinc@nvidia.com<mailto:nicolinc@nvidia.com>>; skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com> <skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com>>; joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com> <joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com>>; CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com<mailto:clement.mathieu--drif@eviden.com>>; kevin.tian@intel.com<mailto:kevin.tian@intel.com> <kevin.tian@intel.com<mailto:kevin.tian@intel.com>>; yi.l.liu@intel.com<mailto:yi.l.liu@intel.com> <yi.l.liu@intel.com<mailto:yi.l.liu@intel.com>>; xudong.hao@intel.com<mailto:xudong.hao@intel.com> <xudong.hao@intel.com<mailto:xudong.hao@intel.com>>; Zhenzhong Duan <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
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 <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
---
 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
RE: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check
Posted by Duan, Zhenzhong 1 month, 2 weeks ago
Hi Clement,

That's a good idea, it looks simpler to use extract32/64 for multi bits field, for one bit field, just keep it as is. Will change as below, let me know if I misunderstand your suggestion.

diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index e5518a94ea..d6674861fd 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -195,7 +195,8 @@
#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_SET_PSS(x, v)      ((x)->ecap = deposit64((x)->ecap, 35, 5, v))
+#define VTD_ECAP_PSS(ecap)          extract64(ecap, 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 94a691d423..dd7073fc08 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -5027,7 +5027,8 @@ static void vtd_cap_init(IntelIOMMUState *s)
     }

     if (s->pasid) {
-        s->ecap = VTD_ECAP_PASID | deposit64(s->ecap, 35, 5, s->pasid - 1);
+        VTD_ECAP_SET_PSS(s, s->pasid - 1);
+        s->ecap |= VTD_ECAP_PASID;
     }
}

BRs,
Zhenzhong

From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
Sent: Thursday, February 26, 2026 2:30 PM
To: Duan, Zhenzhong <zhenzhong.duan@intel.com>; qemu-devel@nongnu.org
Cc: alex@shazbot.org; clg@redhat.com; eric.auger@redhat.com; mst@redhat.com; jasowang@redhat.com; jgg@nvidia.com; nicolinc@nvidia.com; skolothumtho@nvidia.com; joao.m.martins@oracle.com; Tian, Kevin <kevin.tian@intel.com>; Liu, Yi L <yi.l.liu@intel.com>; Hao, Xudong <xudong.hao@intel.com>
Subject: Re: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check

Hi Zhenzhong,

Oh ok, I did not remember this comment from Eric, my mistake.

From what I see in the smmu:
- "getters" use extract and are named according to the field they extract.
- "setters" use deposit and use the following naming pattern "XXX_SET_THENAME"

Do you think we should follow the same way?

cmd

________________________________
From: Duan, Zhenzhong <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
Sent: 26 February 2026 04:12
To: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com<mailto:clement.mathieu--drif@eviden.com>>; qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org> <qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org>>
Cc: alex@shazbot.org<mailto:alex@shazbot.org> <alex@shazbot.org<mailto:alex@shazbot.org>>; clg@redhat.com<mailto:clg@redhat.com> <clg@redhat.com<mailto:clg@redhat.com>>; eric.auger@redhat.com<mailto:eric.auger@redhat.com> <eric.auger@redhat.com<mailto:eric.auger@redhat.com>>; mst@redhat.com<mailto:mst@redhat.com> <mst@redhat.com<mailto:mst@redhat.com>>; jasowang@redhat.com<mailto:jasowang@redhat.com> <jasowang@redhat.com<mailto:jasowang@redhat.com>>; jgg@nvidia.com<mailto:jgg@nvidia.com> <jgg@nvidia.com<mailto:jgg@nvidia.com>>; nicolinc@nvidia.com<mailto:nicolinc@nvidia.com> <nicolinc@nvidia.com<mailto:nicolinc@nvidia.com>>; skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com> <skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com>>; joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com> <joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com>>; Tian, Kevin <kevin.tian@intel.com<mailto:kevin.tian@intel.com>>; Liu, Yi L <yi.l.liu@intel.com<mailto:yi.l.liu@intel.com>>; Hao, Xudong <xudong.hao@intel.com<mailto:xudong.hao@intel.com>>
Subject: RE: [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.


Hi Clement,



This is to follow Eric's suggestion in previous iommufd nesting series

where he suggested to use extra32/64 syntax, copied here:



+#define VTD_INV_DESC_PASIDC_DSI        (0ULL << 4)

+#define VTD_INV_DESC_PASIDC_PASID_SI   (1ULL << 4)

+#define VTD_INV_DESC_PASIDC_GLOBAL     (3ULL << 4)

as those are values for the granularity field using



VTD_INV_DESC_PASIDC_G_* look relevant to me.



I think you would gain in readability if you adopt extract32/64 syntax

like in hw/arm/smmuv3-internal.h

Looks more readable to me.



See https://lore.kernel.org/qemu-devel/2cbb91d3-9acc-4e7a-9a0a-19d9b5efe21b@redhat.com/ for details.



BRs,

Zhenzhong



From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com<mailto:clement.mathieu--drif@eviden.com>>
Sent: Wednesday, February 25, 2026 2:38 PM
To: Duan, Zhenzhong <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>; qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org>
Cc: alex@shazbot.org<mailto:alex@shazbot.org>; clg@redhat.com<mailto:clg@redhat.com>; eric.auger@redhat.com<mailto:eric.auger@redhat.com>; mst@redhat.com<mailto:mst@redhat.com>; jasowang@redhat.com<mailto:jasowang@redhat.com>; jgg@nvidia.com<mailto:jgg@nvidia.com>; nicolinc@nvidia.com<mailto:nicolinc@nvidia.com>; skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com>; joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com>; Tian, Kevin <kevin.tian@intel.com<mailto:kevin.tian@intel.com>>; Liu, Yi L <yi.l.liu@intel.com<mailto:yi.l.liu@intel.com>>; Hao, Xudong <xudong.hao@intel.com<mailto:xudong.hao@intel.com>>
Subject: Re: [RFCv2 PATCH 12/13] intel_iommu_accel: Add pasid bits size check



Hi Zhenzhong,



I'm a bit confused about this patch.



All the other VTD_ECAP_* are masks for the ecap qword.

The purpose of this new definition of ECAP_PSS differs a bit as it extracts the field itself :/



cmd



________________________________

From: Zhenzhong Duan <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
Sent: 14 February 2026 04:41
To: qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org> <qemu-devel@nongnu.org<mailto:qemu-devel@nongnu.org>>
Cc: alex@shazbot.org<mailto:alex@shazbot.org> <alex@shazbot.org<mailto:alex@shazbot.org>>; clg@redhat.com<mailto:clg@redhat.com> <clg@redhat.com<mailto:clg@redhat.com>>; eric.auger@redhat.com<mailto:eric.auger@redhat.com> <eric.auger@redhat.com<mailto:eric.auger@redhat.com>>; mst@redhat.com<mailto:mst@redhat.com> <mst@redhat.com<mailto:mst@redhat.com>>; jasowang@redhat.com<mailto:jasowang@redhat.com> <jasowang@redhat.com<mailto:jasowang@redhat.com>>; jgg@nvidia.com<mailto:jgg@nvidia.com> <jgg@nvidia.com<mailto:jgg@nvidia.com>>; nicolinc@nvidia.com<mailto:nicolinc@nvidia.com> <nicolinc@nvidia.com<mailto:nicolinc@nvidia.com>>; skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com> <skolothumtho@nvidia.com<mailto:skolothumtho@nvidia.com>>; joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com> <joao.m.martins@oracle.com<mailto:joao.m.martins@oracle.com>>; CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com<mailto:clement.mathieu--drif@eviden.com>>; kevin.tian@intel.com<mailto:kevin.tian@intel.com> <kevin.tian@intel.com<mailto:kevin.tian@intel.com>>; yi.l.liu@intel.com<mailto:yi.l.liu@intel.com> <yi.l.liu@intel.com<mailto:yi.l.liu@intel.com>>; xudong.hao@intel.com<mailto:xudong.hao@intel.com> <xudong.hao@intel.com<mailto:xudong.hao@intel.com>>; Zhenzhong Duan <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
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 <zhenzhong.duan@intel.com<mailto:zhenzhong.duan@intel.com>>
---
 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