[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