[PATCH V1 0/3] ACPI/IORT: Honor Root Complex PASID descriptors on SMMUv3

Vidya Sagar
2026-04-23T19:15:01Z

Hi,
This series enhances Linux to read and honor the Root Complex (RC) PASID
descriptors introduced by IORT Issue E.c (ARM DEN 0049E.c, January 2022,
RC node revision 4):

- PASID Capabilities at byte offset 33, bits[4:0] = Max PASID Width.
- Flags at byte offset 36, bit 0 = "Root Complex supports PASID".

Both fields have been spec'd for over four years but are not consumed
anywhere in the tree. Worse, include/acpi/actbl2.h only covers the
PASID Capabilities field - the trailing "u8 reserved[]" flexible array
stops just before the Flags field at offset 36, so even firmware that
populates it cannot be read today. The existing ACPI_IORT_PRI_SUPPORTED,
ACPI_IORT_PASID_FWD_SUPPORTED and ACPI_IORT_PASID_MAX_WIDTH macros are
dead code, and ACPICA upstream has the same gap.

Today arm_smmu_enable_pasid() calls pci_enable_pasid() for any PCI
master with a PASID capability, regardless of whether the upstream RC
actually supports PASID and regardless of the RC's declared Max PASID
Width. On a platform whose RC cannot forward PASID to the SMMU, this
enables the PCIe PASID capability unnecessarily on the endpoint (the
traffic then gets dropped upstream) and sets a non-zero master->ssid_bits,
which complicates teardown ordering with ATS (see the comment block in
arm_smmu_probe_device() for that ordering constraint).

The series fixes this in three bite-sized patches, modeled on the
CANWBS support from commit 807404d66fcf ("ACPI/IORT: Support CANWBS
memory access flag"):

Patch 1 (ACPICA): extend struct acpi_iort_root_complex to cover the
offset-36 Flags field and add the ACPI_IORT_RC_PASID_SUPPORTED
mask. With #pragma pack(1) already in effect for actbl2.h, this
lands the new field at the spec-mandated absolute offset 36.

Patch 2 (ACPI/IORT): add three static helpers that read the new RC
PASID fields (guarded by node->revision >= 4 where appropriate),
set two new iommu_fwspec flags from iort_iommu_configure_id(), and
expose two device-facing wrappers so IOMMU drivers can clamp
endpoint PASID widths without walking the IORT themselves. Stubs
for !CONFIG_ACPI_IORT live in include/linux/acpi_iort.h.
IOMMU_FWSPEC_PCI_RC_PASID (bit 2): RC declares PASID support
IOMMU_FWSPEC_PCI_RC_PASID_FWD (bit 3): RC forwards PASID on
translated transactions
Patch 3 (arm-smmu-v3): consume the new fwspec flag and the new
max-width helper in arm_smmu_enable_pasid(). If the RC explicitly
declares no PASID support, skip pci_enable_pasid() silently.
Otherwise clamp num_pasids by min(endpoint cap, 1 << RC width) and
only proceed when the effective count is > 1.

Policy: all new gating is conditional on
iort_pci_rc_pasid_max_width_known(), i.e. the presence of an IORT RC
node at revision >= 4. Platforms booting with older IORT firmware (RC
node revision 0..3) see no behavioural change and continue to enable
PASID purely on the basis of the endpoint capability. This keeps the
series safe for platforms that ship pre-E.c tables.

Out of scope intentionally:
- Wiring the new fwspec flags into Intel/AMD IOMMU drivers - IORT
is ARM-only.
- Consuming IOMMU_FWSPEC_PCI_RC_PASID_FWD in arm-smmu-v3 beyond the
existing CD/STE programming. The fwspec flag is plumbed now so
future work (e.g. gating PASID forwarding hints in STE.S1DSS) has
the information available.
- Exposing a "pasid-num-bits" software node property for PCI devices,
parallel to what iort_named_component_init() already does for named
components. The direct helper is simpler and avoids creating a
software node per RC.

Thanks,
Vidya Sagar

Vidya Sagar (3):
ACPICA: IORT: Add Root Complex PASID Flags field
ACPI/IORT: Plumb Root Complex PASID descriptors into iommu_fwspec
iommu/arm-smmu-v3: Honor IORT Root Complex PASID descriptors

drivers/acpi/arm64/iort.c | 80 +++++++++++++++++++++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 26 ++++++-
include/acpi/actbl2.h | 6 +-
include/linux/acpi_iort.h | 6 ++
include/linux/iommu.h | 4 ++
5 files changed, 118 insertions(+), 4 deletions(-)

--
2.25.1