[PATCH v2 7/8] iommu/arm-smmu-v3: Change how the tlbi describes the invalidation

Jason Gunthorpe jgg at nvidia.com
Wed Jul 8 11:27:10 PDT 2026


On Tue, Jul 07, 2026 at 06:41:23PM -0700, Nicolin Chen wrote:
> On Mon, Jul 06, 2026 at 01:26:44PM -0300, Jason Gunthorpe wrote:
> > @@ -2331,8 +2331,8 @@ static struct arm_smmu_cmd arm_smmu_atc_inv_to_cmd(u32 sid, int ssid,
> >  	 * This has the unpleasant side-effect of invalidating all PASID-tagged
> >  	 * ATC entries within the address range.
> >  	 */
> > -	page_start = tlbi->iova >> inval_grain_shift;
> > -	page_end = (tlbi->iova + tlbi->size - 1) >> inval_grain_shift;
> > +	page_start = tlbi->start >> inval_grain_shift;
> > +	page_end = tlbi->last >> inval_grain_shift;
> 
> arm_smmu_domain_inv() in the header passes in start=last=0, but
> it's supposed to flush the entire ATC, right?

Yeah, that's a mistake! The invalidate all needs to set last=ULONG_MAX

        /* Prefilled for invalidate all */
        struct arm_smmu_tlbi tlbi = {
+               .start = 0,
+               .last = ULONG_MAX,

> >  static void arm_smmu_iotlb_sync(struct iommu_domain *domain,
> >  				struct iommu_iotlb_gather *gather)
> >  {
> > +	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
> > +	unsigned int tg = smmu_domain->tgsz_lg2;
> >  	struct arm_smmu_tlbi tlbi = {
> > -		.smmu_domain = to_smmu_domain(domain),
> > -		.iova = gather->start,
> > -		.size = gather->end - gather->start + 1,
> > -		.iopte_granule = gather->pgsize,
> > -		.leaf_only = true,
> > +		.smmu_domain = smmu_domain,
> > +		.start = gather->start,
> > +		.last = gather->end,
> > +		.leaf_levels_bitmap =
> [...]
> > +			BIT((ilog2(gather->pgsize) - tg) / (tg - 3)),
> >  	};
> >  
> >  	if (!gather->pgsize)
> 
> pgsize=0 is checked after ilog2(0).

Yes, but gather->pgsize = 0 also can't happen.. But lets do better:

@@ -4096,13 +4096,13 @@ static void arm_smmu_iotlb_sync(struct iommu_domain *domain,
                .tgsz_lg2 = smmu_domain->tgsz_lg2,
                .start = gather->start,
                .last = gather->end,
-               .leaf_levels_bitmap =
-                       BIT((ilog2(gather->pgsize) - tg) / (tg - 3)),
        };
 
-       if (!gather->pgsize)
+       if (WARN_ON(gather->pgsize < BIT(tg)))
                return;
 
+       tlbi.leaf_levels_bitmap = BIT((ilog2(gather->pgsize) - tg) / (tg - 3));
+
        arm_smmu_domain_tlbi(&tlbi, smmu_domain);
 }


Jason



More information about the linux-arm-kernel mailing list