[PATCH V1 3/3] iommu/arm-smmu-v3: Honor IORT Root Complex PASID descriptors

Jason Gunthorpe jgg at ziepe.ca
Thu Apr 23 15:45:08 PDT 2026


On Fri, Apr 24, 2026 at 12:44:17AM +0530, Vidya Sagar wrote:
> The SMMUv3 driver currently calls pci_enable_pasid() for any PCI
> master that exposes a PASID capability, regardless of whether the
> upstream Root Complex actually supports PASID and regardless of the
> RC's declared Max PASID Width. With IORT spec E.c (RC node revision
> >= 4) firmware reports both, so we can do better:
> 
>   - If the IORT Root Complex node says PASID is not supported
>     (Flags bit 0 == 0 at byte offset 36), enabling PASID on the
>     endpoint is futile - the RC will not forward the PASID prefix to
>     the SMMU - so skip pci_enable_pasid() silently.
> 
>   - If the IORT Root Complex node reports a Max PASID Width (bits[4:0]
>     of PASID Capabilities at offset 33), clamp the endpoint's
>     pci_max_pasids() result by 1 << width before computing the SMMU
>     SSID width. This prevents master->ssid_bits from exceeding what
>     the RC can actually carry.
> 
> Both behaviours are gated on iort_pci_rc_pasid_max_width_known(), i.e.
> RC node revision >= 4, so platforms with older IORT firmware see no
> behavioural change and continue to enable PASID purely on the basis
> of the endpoint capability.
> 
> Use the new IOMMU_FWSPEC_PCI_RC_PASID fwspec flag (set by IORT) for
> the support check, and call iort_pci_rc_pasid_max_width_for_dev() for
> the width clamp; both pieces are wired up in
> iort_iommu_configure_id() by the previous patch.
> 
> Signed-off-by: Vidya Sagar <vidyas at nvidia.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 26 ++++++++++++++++++---
>  1 file changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index e8d7dbe495f0..2b269307fd33 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -3071,16 +3071,28 @@ static void arm_smmu_enable_ats(struct arm_smmu_master *master)
>  
>  static int arm_smmu_enable_pasid(struct arm_smmu_master *master)
>  {
> -	int ret;
> -	int features;
> -	int num_pasids;
> +	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(master->dev);
>  	struct pci_dev *pdev;
> +	int features, num_pasids, ret, rc_width;

Don't reformat the code like this.

Otherwise the series broadly makes sense to me

Jason



More information about the linux-arm-kernel mailing list