Re: [PATCH v2 00/11] iommu/arm-smmu-v3: Add PRI support
From: harsha . v
Date: Fri Jun 26 2026 - 10:59:17 EST
Hi Nicolin Chen,
On 5/28/2026 1:29 PM, Nicolin Chen wrote:
The SMMUv3 driver doesn't handle events on the PRI queue or respond to IOPF
faults. This series adds the missing pieces, using the IOPF infrastructure,
to convert PRI page requests into iopf_faults and issue CMDQ_OP_PRI_RESP.
The iopf_queue_flush_dev() contract requires the driver to first drain the
hardware PRI queue and synchronize using a threaded IRQ handler before the
IOPF software flush. This drove the additional commits compared to v1:
- arm_smmu_drain_queue_for_iopf() drains the hardware queue to the PROD
snapshot
- arm_smmu_attach_release() moves the teardown outside the global lock
- synchronize_irq() closes the gap before the final flush
This is on Github:
https://github.com/nicolinc/iommufd/commits/smmuv3_pri-v2
FWIW, engineers on the NVIDIA side have managed to verify the PRI feature.
Changelog
v2:
* Allocate evtq.iopf for ARM_SMMU_FEAT_PRI
* Pick up Jean's PRI stubs and PRI export patches
* Enable PRI for PCI devices in arm_smmu_probe_device()
* Add arm_smmu_drain_queue_for_iopf() for EVTQ and PRIQ
* Add arm_smmu_attach_release() to rework the IOPF drain
* Add IOMMU_FAULT_PAGE_REQUEST_STALLS_TRANS for STALL mode
* Gate pci_enable_pri() on FEAT_PRI plus a non-NULL evtq.iopf
* Deny unrecognised-StreamID PRG_LAST in arm_smmu_handle_ppr()
* Disable PRI when no IRQ handler is registered (unique or combined IRQ)
v1:
https://lore.kernel.org/all/cover.1772568590.git.nicolinc@xxxxxxxxxx/
Jean-Philippe Brucker (2):
PCI/ATS: Add PRI stubs
PCI/ATS: Export pci_enable_pri() and pci_reset_pri()
Malak Marrid (1):
iommu/arm-smmu-v3: Submit CMDQ_OP_PRI_RESP for IOPF event
Nicolin Chen (8):
iommu/arm-smmu-v3: Add arm_smmu_attach_release()
iommu/arm-smmu-v3: Factor out __queue_empty() and __queue_consumed()
iommu/arm-smmu-v3: Add arm_smmu_drain_queue_for_iopf() helper
iommu/arm-smmu-v3: Drain in-flight fault handlers
iommu/arm-smmu-v3: Support PRI Page Request in arm_smmu_handle_ppr()
iommu/arm-smmu-v3: Disable PRI when no IRQ handler is registered
iommu/arm-smmu-v3: Allocate IOPF queue for ARM_SMMU_FEAT_PRI
iommu/arm-smmu-v3: Enable PRI for PCI device in
arm_smmu_probe_device()
drivers/iommu/arm/Kconfig | 1 +
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 3 +
include/linux/iommu.h | 1 +
include/linux/pci-ats.h | 5 +
.../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 1 +
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 244 +++++++++++++++---
drivers/pci/ats.c | 2 +
7 files changed, 221 insertions(+), 36 deletions(-)
base-commit: 74fa4c177ad09800b007cba043370c887bb1b4e3
One thing I noticed while reviewing: when arm_smmu_priq_thread() detects
PRIQ overflow, partial faults (non-LAST pages stored via
report_partial_fault()) whose LAST page was lost in the overflow remain
permanently in iopf_param->partial. This is a monotonic memory leak —
it grows with each overflow event.
Intel VT-d handles this in prq_event_thread() (drivers/iommu/intel/prq.c):
if (head == tail) {
iopf_queue_discard_partial(iommu->iopf_queue);
writel(DMA_PRS_PRO, iommu->reg + DMAR_PRS_REG);
}
iopf_queue_discard_partial() was written for exactly this scenario.
Could we add the same here arm_smmu_priq_thread()
(drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c) ?
if (queue_sync_prod_in(q) == -EOVERFLOW) {
dev_err(smmu->dev, "PRIQ overflow detected -- requests lost\n");
+ iopf_queue_discard_partial(smmu->evtq.iopf);
}
At this point all surviving entries have already been consumed by the
loop above, so discarding unconditionally is safe — implicitly matching
Intel's "head == tail" guard.
Best Regards,
Harsha Vardhan V