Re: [PATCH 1/1] x86/mm: fix incomplete page-table invalidation with TCE

From: Pedro Falcato

Date: Mon Oct 05 2026 - 06:26:50 EST


On Mon, Oct 05, 2026 at 03:29:22PM +0800, Lance Yang wrote:
>
>
> On 2026/10/5 14:09, Pedro Falcato wrote:
> > On Mon, Oct 05, 2026 at 01:23:02PM +0800, Lance Yang wrote:
> > > pud_free_pmd_page() uses a single-address invalidation to flush the
> > > paging-structure caches before freeing the page tables. With AMD TCE
> > > enabled, this only invalidates upper-level entries associated with the
> > > target address. Cached PMD entries for other addresses in the PUD range can
> > > still reference the PTE pages being freed.
> > >
> > > The AMD manual quoted in the commit enabling TCE says these instructions
> > > remove
> > >
> > > "only those upper-level entries that lead to the target PTE in the page
> > > table hierarchy, leaving unrelated upper-level entries intact."
> > >
> > > Even with all PTEs cleared, speculative page walks can cache present PMD
> > > entries after the earlier TLB purge.
> > >
> > > Use a full TLB flush before freeing the page tables on CPUs with TCE. Keep
> > > the single-address invalidation otherwise.
> > >
> > > Fixes: 440a65b7d25f ("x86/mm: Enable AMD translation cache extensions")
> > > Cc: stable@xxxxxxxxxxxxxxx
> > > Signed-off-by: Lance Yang <lance.yang@xxxxxxxxx>
> >
> > I'm not sure this is correct. The PUD is clear. We invalidate the TLB, which
> > invalidates the translation caches for that walk. invlpg will notice the PUD
> > isn't present. I don't see a case where it can ever not clear the rest
> > of the translation caches for all leaves. And, in fact, by that point the CPU
> > can (does?) probably formally treat the PUD as the leaf.
>
> IIUC, clearing the PUD in memory doesn't invalidate cached PMD entries by
> itself. With TCE enabled, flushing one address only invalidates the entries
> associated with that address ...
>
> (That's how I read the manual, but AMD folks, please correct me if I'm
> missing something.)
>
> So couldn't other cached PMDs under the same PUD survive?

I don't read it as that. I read it as "flushing one address only invalidates
the entries on that path". So, if you flush one address, you'll flush the
whole translation cache for that range. And page table zapping agrees; if you
follow the code from zap_pte_range() -> pte_free_tlb(), it will do a single flush
for each PTE table (if the whole table is empty/non-present).

--
Pedro