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
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
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
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
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
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
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
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
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
© 2016 - 2026 Red Hat, Inc.