[PATCH v8 8/9] iommu/arm-smmu-v3: Change how the tlbi describes the invalidation
Jason Gunthorpe
jgg at nvidia.com
Sun Oct 4 10:00:12 PDT 2026
On Sun, Oct 04, 2026 at 02:43:33PM +0100, Will Deacon wrote:
> > + /*
> > + * Assumes the page table is formed properly and does not trigger the
> > + * 16k TTL=1 condition for leaf-only unless DS is enabled.
> > + *
> > + * ARM level -1 never has a leaf so something has gone wrong. ARM Level
> > + * 0 cannot be hinted because ttl=0 means no-hint.
> > + */
>
> nit: This isn't strictly true for the non-range invalidation operations, so
> I think it would be handy to have a big note saying that this function only
> works for range invalidation or even stick "range" in the function name
> somewhere.
I figured "ttl" was enough since ttl is only used as part of the range
invalidation command. I can change it to range ttl
> > @@ -2917,12 +2998,17 @@ static void arm_smmu_tlb_inv_walk(unsigned long iova, size_t size,
> > size_t granule, void *cookie)
> > {
> > struct arm_smmu_domain *smmu_domain = cookie;
> > + u8 tgsz_lg2 = smmu_domain->tgsz_lg2;
> > struct arm_smmu_tlbi tlbi = {
> > .tgsz_lg2 = smmu_domain->tgsz_lg2,
> > - .iova = iova,
> > - .size = size,
> > - .iopte_size = 1 << smmu_domain->tgsz_lg2,
> > + .start = iova,
> > + .last = iova + size - 1,
> > };
> > + u8 table_levels =
> > + BIT(arm_smmu_pt_lg2sz_to_level(tgsz_lg2, ilog2(size)));
> > +
> > + tlbi.table_levels_bitmap = table_levels;
> > + tlbi.leaf_levels_bitmap = table_levels - 1;
>
> I'm having a tough time understanding this part. Specifically, I'm trying
> to work out what happens if we end up doing a non-leaf invalidation at the
> PGD (1GiB) level with leaves at the PTE (4KiB) level. In that case, don't
> we need to have table_levels describing both PGD and PMD levels so that
> the TTL describes the 4k leaf entries?
The comment you clipped off tried to explain it:
/*
* Called by io-pgtable-arm.c for each single table level it wants to remove.
* size is the size of the table level and granule is the tg in bytes. This must
* clear the walk cache and any leaves within the range.
*/
But, I had AI double check this statement "each single table level"
and it agrees with you and gave the same example. It does look like I
understood it wrong, I thought the segmantion logic in the core code
would save things but it doesn't work quite like that.
This still works right as-is because the leaf_levels_bitmap disables TTL
and forces single to step at 4k, so it isn't a functional bug, but the
comment is wrong and the logic should be more like:
tlbi.table_levels_bitmap = (table_levels | (table_levels - 1)) & ~BIT(0);
Jason
More information about the linux-arm-kernel
mailing list