Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Gunthorpe <jgg@nvidia.com>
To: Nicolin Chen <nicolinc@nvidia.com>
Cc: iommu@lists.linux.dev, "Joerg Roedel (AMD)" <joro@8bytes.org>,
	Jean-Philippe Brucker <jpb@kernel.org>,
	linux-arm-kernel@lists.infradead.org,
	Robin Murphy <robin.murphy@arm.com>,
	Will Deacon <will@kernel.org>,
	David Matlack <dmatlack@google.com>,
	Pasha Tatashin <pasha.tatashin@soleen.com>,
	patches@lists.linux.dev, Pranjal Shrivastava <praan@google.com>,
	Samiullah Khawaja <skhawaja@google.com>,
	Mostafa Saleh <smostafa@google.com>
Subject: Re: [PATCH v2 7/8] iommu/arm-smmu-v3: Change how the tlbi describes the invalidation
Date: Thu, 9 Jul 2026 15:25:59 -0300	[thread overview]
Message-ID: <20260709182559.GH422027@nvidia.com> (raw)
In-Reply-To: <ak3gPqsdg94TTDLJ@Asurada-Nvidia>

On Tue, Jul 07, 2026 at 10:29:34PM -0700, Nicolin Chen wrote:

> > +/*
> > + * One TLBI command per stride-sized entry. Sets use_full_inv if too many
> 
> This is raised by Claude; not sure whether it is a false positive
> or not.

It is not right as written but there is something wrong here..

> This changes a previous per-pte invalidation to per-pmd one. Yet,
> the spec states in 4.4 TLB invalidation (last paragraph):
> 
>   To match a TLB entry, the least significant bits of the address
>   are ignored as needed, given the size of the entry.
> 
> So, the following scenario would likely miss leaf entries:
> 
> VFIO_IOMMU_UNMAP_DMA / IOMMU_IOAS_UNMAP
>   iommu_unmap(domain, iova=0x40000000, size=2M)
>     __iommu_unmap()
>       iommu_pgsize()  -> picks pgsize=2M (aligned, 2M in pgsize_bitmap;
>                          irrelevant that the region was mapped as 4K pages)
>       arm_lpae_unmap_pages(iova, 2M, pgcount=1, gather)
>         __arm_lpae_unmap(lvl=0) -> lvl=1 -> lvl=2:    size == BLOCK_SIZE(lvl 2)
>           pte = READ_ONCE(*ptep)         -> a TABLE descriptor, not a block
>           __arm_lpae_clear_pte()          # L2 descriptor := 0
>           io_pgtable_tlb_flush_walk(iova, 2M, granule=4K)
>             arm_smmu_tlb_inv_walk()
>               tlbi = { start=0x40000000, last=0x401fffff,
>                        table_levels_bitmap = BIT((ilog2(2M)-12)/9) = 0b010,
>                        leaf_levels_bitmap  = 0 }              <-- the false claim
>               arm_smmu_domain_tlbi()
>                 arm_smmu_tlbi_calc_single():
>                   calc_stride: __ffs(0b010) = 1 -> stride = 2M
>                   num_ops = 2M >> 21 = 1
>                 arm_smmu_domain_tlbi_inv()
>                   non-RIL entry: ONE TLBI_NH_VA @0x40000000, Leaf=0
>                     -> kills the walk entry + the 4K leaf at base
>                     -> 511 4K leaves SURVIVE
>           __arm_lpae_free_pgtable()       # subtree freed, no invalidation
>     iommu_iotlb_sync(domain, &gather)     # gather->pgsize == 0 -> returns immediately

This conclusion is wrong, gather->pgsize is never 0.

I wonder if this Claude was thinking about a kernel before
84b2baf427968c1 where this flow would have been as-described?

With the kernel today the arm_smmu_tlb_inv_walk() is supposed to clear
out the walk cache before freeing the table entry and the gather is
supposed to clear out the leaf entries themselves. 84b2baf427968c1
changed things so we always have a second leaf-only gather that covers
the entire unmap range, which also introduced the double invalidation.

What I missed is that because of that commit gather->pgsize is no
longer correct, it will be 2M even if __arm_lpae_free_pgtable()
unmapped 4k leaves. So we will still miss leaf invalidation :\

I'm going to add a patch to correct this in the io-pgtable-arm.c

> > +	 * If leaf_levels_bitmap is 0 then this is a walk cache only
> > +	 * invalidation.
> [...]
> > +	u8 leaf_levels_bitmap;
> 
> Or is that only to implement a walkcache-only invalidation, such
> that the leaf entries will have separate invalidation call(s)?

That was the plan

Thanks,
Jason


  reply	other threads:[~2026-07-09 18:26 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-06 16:26 [PATCH v2 0/8] Organize the SMMUv3 invalidation flow so iommupt can use it Jason Gunthorpe
2026-07-06 16:26 ` [PATCH v2 1/8] iommu/arm-smmu-v3: Pass the parameters for the invalidation in a struct Jason Gunthorpe
2026-07-07  3:04   ` Nicolin Chen
2026-07-07 11:18   ` Mostafa Saleh
2026-07-06 16:26 ` [PATCH v2 2/8] iommu/arm-smmu-v3: Move pgsize out of arm_smmu_inv Jason Gunthorpe
2026-07-07  3:57   ` Nicolin Chen
2026-07-07 16:15     ` Jason Gunthorpe
2026-07-07 17:21       ` Nicolin Chen
2026-07-08 18:43         ` Jason Gunthorpe
2026-07-07 11:24   ` Mostafa Saleh
2026-07-07 18:08     ` Jason Gunthorpe
2026-07-11 17:38       ` Daniel Mentz
2026-07-10  4:06   ` Daniel Mentz
2026-07-10 14:28     ` Jason Gunthorpe
2026-07-06 16:26 ` [PATCH v2 3/8] iommu/arm-smmu-v3: Optimize range invalidation for latency Jason Gunthorpe
2026-07-07  7:27   ` Nicolin Chen
2026-07-07 19:13     ` Jason Gunthorpe
2026-07-07 21:07       ` Nicolin Chen
2026-07-07 11:45   ` Mostafa Saleh
2026-07-08  0:10     ` Jason Gunthorpe
2026-07-06 16:26 ` [PATCH v2 4/8] iommu/arm-smmu-v3: Keep track in the arm_smmu_invs if RIL is used Jason Gunthorpe
2026-07-07  7:27   ` Nicolin Chen
2026-07-07 11:46   ` Mostafa Saleh
2026-07-06 16:26 ` [PATCH v2 5/8] iommu/arm-smmu-v3: Precompute the invalidation commands Jason Gunthorpe
2026-07-07 11:52   ` Mostafa Saleh
2026-07-07 14:58     ` Jason Gunthorpe
2026-07-08  9:00       ` Mostafa Saleh
2026-07-08 13:15         ` Jason Gunthorpe
2026-07-07 20:31   ` Nicolin Chen
2026-07-09 12:07     ` Jason Gunthorpe
2026-07-09 19:10       ` Nicolin Chen
2026-07-06 16:26 ` [PATCH v2 6/8] iommu/arm-smmu-v3: Populate the tlbi at the top of the call chain Jason Gunthorpe
2026-07-07 11:57   ` Mostafa Saleh
2026-07-08 18:09     ` Jason Gunthorpe
2026-07-07 21:51   ` Nicolin Chen
2026-07-08 18:40     ` Jason Gunthorpe
2026-07-06 16:26 ` [PATCH v2 7/8] iommu/arm-smmu-v3: Change how the tlbi describes the invalidation Jason Gunthorpe
2026-07-06 18:00   ` Robin Murphy
2026-07-06 19:45     ` Jason Gunthorpe
2026-07-08  1:41   ` Nicolin Chen
2026-07-08 18:27     ` Jason Gunthorpe
2026-07-08  5:29   ` Nicolin Chen
2026-07-09 18:25     ` Jason Gunthorpe [this message]
2026-07-09 21:32       ` Nicolin Chen
2026-07-06 16:26 ` [PATCH v2 8/8] iommu/arm-smmu-v3: Support the DS expansion of RIL's SCALE Jason Gunthorpe
2026-07-07 23:20   ` Nicolin Chen
2026-07-08  0:02     ` Jason Gunthorpe
2026-07-08  2:10       ` Nicolin Chen
2026-07-08 13:05         ` Jason Gunthorpe
2026-07-07 12:25 ` [PATCH v2 0/8] Organize the SMMUv3 invalidation flow so iommupt can use it Mostafa Saleh
2026-07-07 15:00   ` Jason Gunthorpe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260709182559.GH422027@nvidia.com \
    --to=jgg@nvidia.com \
    --cc=dmatlack@google.com \
    --cc=iommu@lists.linux.dev \
    --cc=joro@8bytes.org \
    --cc=jpb@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=nicolinc@nvidia.com \
    --cc=pasha.tatashin@soleen.com \
    --cc=patches@lists.linux.dev \
    --cc=praan@google.com \
    --cc=robin.murphy@arm.com \
    --cc=skhawaja@google.com \
    --cc=smostafa@google.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox