--- b/arch/x86/mm/pgtable.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff -puN arch/x86/mm/pgtable.c~pud_free_pmd_page-simplify arch/x86/mm/pgtable.c --- a/arch/x86/mm/pgtable.c~pud_free_pmd_page-simplify 2026-09-23 15:30:32.035610475 -0700 +++ b/arch/x86/mm/pgtable.c 2026-09-23 15:36:56.663747586 -0700 @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +pud_free_pmd_page-simplify// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -711,44 +711,34 @@ int pmd_clear_huge(pmd_t *pmd) * @addr: Virtual address associated with PUD * * Context: The PUD range has been unmapped and TLB purged. - * Return: 1 if clearing the entry succeeded. 0 otherwise. * * NOTE: Callers must allow a single page allocation. */ -int pud_free_pmd_page(pud_t *pud, unsigned long addr) +void pud_free_pmd_page(pud_t *pud, unsigned long addr) { - pmd_t *pmd, *pmd_sv; struct ptdesc *pt; + pmd_t *pmd; int i; pmd = pud_pgtable(*pud); - pmd_sv = (pmd_t *)__get_free_page(GFP_KERNEL); - if (!pmd_sv) - return 0; - - for (i = 0; i < PTRS_PER_PMD; i++) { - pmd_sv[i] = pmd[i]; - if (!pmd_none(pmd[i])) - pmd_clear(&pmd[i]); - } pud_clear(pud); - /* INVLPG to clear all paging-structure caches */ + /* + * 'pmd' and all its descendents are unreachable + * via normal page walks. Make them unreachable + * in cached mid-level walks too: + */ flush_tlb_kernel_range(addr, addr + PAGE_SIZE-1); for (i = 0; i < PTRS_PER_PMD; i++) { - if (!pmd_none(pmd_sv[i])) { - pt = page_ptdesc(pmd_page(pmd_sv[i])); + if (!pmd_none(pmd[i])) { + pt = page_ptdesc(pmd_page(pmd[i])); pagetable_dtor_free(pt); } } - free_page((unsigned long)pmd_sv); - pmd_free(&init_mm, pmd); - - return 1; } /** _