Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* TLB free bug in 4c640eb4181c ("mm: move pte table reclaim code to memory.c")
@ 2026-08-01 14:00 Andy Lutomirski
  2026-08-03  8:31 ` David Hildenbrand (Arm)
  0 siblings, 1 reply; 4+ messages in thread
From: Andy Lutomirski @ 2026-08-01 14:00 UTC (permalink / raw)
  To: David Hildenbrand, zhengqi.arch, Liam R . Howlett,
	Lorenzo Stoakes, Michal Hocko, Mike Rapoport, Suren Baghdasaryan,
	Vlastimil Babka, Andrew Morton, Shakeel Butt, Linux-MM

Hi all-

I saw a fun bug report in ripgrep and a studious but pretty bad
AI-generated analysis, and I peeked at the actual code.  I'm rather
suspicious of this:

    if (can_reclaim_pt) {
        if (direct_reclaim || zap_pte_table_if_empty(mm, pmd, start, &pmdval)) {
            pte_free_tlb(tlb, pmd_pgtable(pmdval), addr);  <-- what is
addr here?
            mm_dec_nr_ptes(mm);
        }
    }

It looks to me (and an LLM -- I can *never* remember what all the
tlb_xyz functions do, so I asked an LLM for a summary), like addr is
not guaranteed to point at the range being zapped, because the do loop
above may increment it right past the end.

On x86, by my reading of the extremely vague text in the SDM volume 3,
INVLPG doesn't care in the sense that (most of?) the code paths
reaching this have already validated that there weren't any live PTEs
in the page and INVLPG promises to flush higher level paging structure
caches for *all* addresses.  But INVPCID makes no such promise that I
can see.

So it kind of seems like this code might end up flushing the wrong
paging structure caches, leaving all *actual mappings* in the TLB
valid but also leaving a cached reference to the to-be-freed
pagetable.  Which would be quite bad.

Original report here:

https://github.com/BurntSushi/ripgrep/issues/3494

I haven't sent a patch because I *still* don't pretend to have
followed what all the tlb_ functions promise to do, and I don't want
to submit a subtle patch based just on an LLM telling me what *it*
thinks those functions do.  I could trace though all this mess
manually, but I bet that one of you actually remembers :)

--Andy


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: TLB free bug in 4c640eb4181c ("mm: move pte table reclaim code to memory.c")
  2026-08-01 14:00 TLB free bug in 4c640eb4181c ("mm: move pte table reclaim code to memory.c") Andy Lutomirski
@ 2026-08-03  8:31 ` David Hildenbrand (Arm)
  2026-08-03  8:33   ` David Hildenbrand (Arm)
  2026-08-03  9:18   ` David Hildenbrand (Arm)
  0 siblings, 2 replies; 4+ messages in thread
From: David Hildenbrand (Arm) @ 2026-08-03  8:31 UTC (permalink / raw)
  To: Andy Lutomirski, zhengqi.arch, Liam R . Howlett, Lorenzo Stoakes,
	Michal Hocko, Mike Rapoport, Suren Baghdasaryan, Vlastimil Babka,
	Andrew Morton, Shakeel Butt, Linux-MM

On 8/1/26 16:00, Andy Lutomirski wrote:
> Hi all-
> 
> I saw a fun bug report in ripgrep and a studious but pretty bad
> AI-generated analysis, and I peeked at the actual code.  I'm rather
> suspicious of this:
> 
>     if (can_reclaim_pt) {
>         if (direct_reclaim || zap_pte_table_if_empty(mm, pmd, start, &pmdval)) {
>             pte_free_tlb(tlb, pmd_pgtable(pmdval), addr);  <-- what is
> addr here?
>             mm_dec_nr_ptes(mm);
>         }
>     }
> 
> It looks to me (and an LLM -- I can *never* remember what all the
> tlb_xyz functions do, so I asked an LLM for a summary), like addr is
> not guaranteed to point at the range being zapped, because the do loop
> above may increment it right past the end.

It will actually always point at the end, whereby the end is at
the start of the next page table :/

pte_table_reclaim_possible() makes sure that we reclaim only when covering a full
page table.

Subtracting "PMD_SIZE" from start would ... or just remembering the original start.

> 
> On x86, by my reading of the extremely vague text in the SDM volume 3,
> INVLPG doesn't care in the sense that (most of?) the code paths
> reaching this have already validated that there weren't any live PTEs
> in the page and INVLPG promises to flush higher level paging structure
> caches for *all* addresses.  But INVPCID makes no such promise that I
> can see.
> 
> So it kind of seems like this code might end up flushing the wrong
> paging structure caches, leaving all *actual mappings* in the TLB
> valid but also leaving a cached reference to the to-be-freed
> pagetable.  Which would be quite bad.

:/

> 
> Original report here:
> 
> https://github.com/BurntSushi/ripgrep/issues/3494
> 
> I haven't sent a patch because I *still* don't pretend to have
> followed what all the tlb_ functions promise to do, and I don't want
> to submit a subtle patch based just on an LLM telling me what *it*
> thinks those functions do.  I could trace though all this mess
> manually, but I bet that one of you actually remembers :)

The memory.c code is definitely broken. I guess the real question is,
what the effect of that is.

-- 
Cheers,

David


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: TLB free bug in 4c640eb4181c ("mm: move pte table reclaim code to memory.c")
  2026-08-03  8:31 ` David Hildenbrand (Arm)
@ 2026-08-03  8:33   ` David Hildenbrand (Arm)
  2026-08-03  9:18   ` David Hildenbrand (Arm)
  1 sibling, 0 replies; 4+ messages in thread
From: David Hildenbrand (Arm) @ 2026-08-03  8:33 UTC (permalink / raw)
  To: Andy Lutomirski, zhengqi.arch, Liam R . Howlett, Lorenzo Stoakes,
	Michal Hocko, Mike Rapoport, Suren Baghdasaryan, Vlastimil Babka,
	Andrew Morton, Shakeel Butt, Linux-MM

On 8/3/26 10:31, David Hildenbrand (Arm) wrote:
> On 8/1/26 16:00, Andy Lutomirski wrote:
>> Hi all-
>>
>> I saw a fun bug report in ripgrep and a studious but pretty bad
>> AI-generated analysis, and I peeked at the actual code.  I'm rather
>> suspicious of this:
>>
>>     if (can_reclaim_pt) {
>>         if (direct_reclaim || zap_pte_table_if_empty(mm, pmd, start, &pmdval)) {
>>             pte_free_tlb(tlb, pmd_pgtable(pmdval), addr);  <-- what is
>> addr here?
>>             mm_dec_nr_ptes(mm);
>>         }
>>     }
>>
>> It looks to me (and an LLM -- I can *never* remember what all the
>> tlb_xyz functions do, so I asked an LLM for a summary), like addr is
>> not guaranteed to point at the range being zapped, because the do loop
>> above may increment it right past the end.
> 
> It will actually always point at the end, whereby the end is at
> the start of the next page table :/
> 
> pte_table_reclaim_possible() makes sure that we reclaim only when covering a full
> page table.
> 
> Subtracting "PMD_SIZE" from start would ... or just remembering the original start.

Stupid me, we have "start" right there that we can just use.

-- 
Cheers,

David


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: TLB free bug in 4c640eb4181c ("mm: move pte table reclaim code to memory.c")
  2026-08-03  8:31 ` David Hildenbrand (Arm)
  2026-08-03  8:33   ` David Hildenbrand (Arm)
@ 2026-08-03  9:18   ` David Hildenbrand (Arm)
  1 sibling, 0 replies; 4+ messages in thread
From: David Hildenbrand (Arm) @ 2026-08-03  9:18 UTC (permalink / raw)
  To: Andy Lutomirski, zhengqi.arch, Liam R . Howlett, Lorenzo Stoakes,
	Michal Hocko, Mike Rapoport, Suren Baghdasaryan, Vlastimil Babka,
	Andrew Morton, Shakeel Butt, Linux-MM

>> Original report here:
>>
>> https://github.com/BurntSushi/ripgrep/issues/3494
>>
>> I haven't sent a patch because I *still* don't pretend to have
>> followed what all the tlb_ functions promise to do, and I don't want
>> to submit a subtle patch based just on an LLM telling me what *it*
>> thinks those functions do.  I could trace though all this mess
>> manually, but I bet that one of you actually remembers :)
> 
> The memory.c code is definitely broken. I guess the real question is,
> what the effect of that is.

We should end up in tlb_flush_mmu_tlbonly(tlb) -> tlb_flush(tlb) ->
flush_tlb_mm_range() with the wrong range, so yes, please send a
fix asap, thanks!

-- 
Cheers,

David


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-08-03 13:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-01 14:00 TLB free bug in 4c640eb4181c ("mm: move pte table reclaim code to memory.c") Andy Lutomirski
2026-08-03  8:31 ` David Hildenbrand (Arm)
2026-08-03  8:33   ` David Hildenbrand (Arm)
2026-08-03  9:18   ` David Hildenbrand (Arm)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox