Re: [PATCH 1/4] x86/mm: fix missing pgtable destructor for vmemmap tables
From: Muchun Song
Date: Thu Oct 08 2026 - 04:42:54 EST
> On Oct 8, 2026, at 09:30, Muchun Song <songmuchun@xxxxxxxxxxxxx> wrote:
>
> Since commit 49f599666420 ("mm: call ctor/dtor for kernel PTEs"),
> pte_alloc_one_kernel() runs the page-table constructor for kernel PTE
> tables.
>
> HugeTLB vmemmap optimization uses pte_alloc_one_kernel() when splitting
> a PMD. Restoring the vmemmap backing pages does not collapse the PTE
> table, so a later memory hot-remove eventually frees that table through
> free_pagetable(). That path currently calls pagetable_free() directly
> without decrementing NR_PAGETABLE.
>
> Use PageTable() to identify constructor-backed tables and run the
> matching destructor before freeing them. Keep reserved and
> constructor-free tables on their existing paths. This also prepares
> vmemmap teardown for generic runtime allocations through the normal
> pgalloc helpers.
>
> Fixes: 49f599666420 ("mm: call ctor/dtor for kernel PTEs")
> Cc: stable@xxxxxxxxxxxxxxx
> Assisted-by: LLM
> Signed-off-by: Muchun Song <songmuchun@xxxxxxxxxxxxx>
> ---
> arch/x86/mm/init_64.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
> index 70e682180291..a3ea627157ab 100644
> --- a/arch/x86/mm/init_64.c
> +++ b/arch/x86/mm/init_64.c
> @@ -1003,6 +1003,8 @@ static void __meminit free_pagetable(struct page *page)
> {
> if (PageReserved(page))
> free_reserved_page(page);
> + else if (PageTable(page))
> + pagetable_dtor_free(page_ptdesc(page));
Sashiko mentioned that kernel page table pages and vmemmap pages are
freed to the buddy allocator before their parent entries are cleared
and before the TLB is flushed, creating a dangling pointer window.
That's a a real but pre-existing issue, I will not fix that in this
series.
> else
> pagetable_free(page_ptdesc(page));
> }
> --
> 2.54.0
>