Skip to content

Commit 40cd0e8

Browse files
ranxiaokaiakpm00
authored andcommitted
KHO: fix boot failure due to kmemleak access to non-PRESENT pages
When booting with debug_pagealloc=on while having: CONFIG_KEXEC_HANDOVER_ENABLE_DEFAULT=y CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=n the system fails to boot due to page faults during kmemleak scanning. This occurs because: With debug_pagealloc is enabled, __free_pages() invokes debug_pagealloc_unmap_pages(), clearing the _PAGE_PRESENT bit for freed pages in the kernel page table. KHO scratch areas are allocated from memblock and noted by kmemleak. But these areas don't remain reserved but released later to the page allocator using init_cma_reserved_pageblock(). This causes subsequent kmemleak scans access non-PRESENT pages, leading to fatal page faults. Mark scratch areas with kmemleak_ignore_phys() after they are allocated from memblock to exclude them from kmemleak scanning before they are released to buddy allocator to fix this. [ran.xiaokai@zte.com.cn: add comment] Link: https://lkml.kernel.org/r/20251127122700.103927-1-ranxiaokai627@163.com Link: https://lkml.kernel.org/r/20251122182929.92634-1-ranxiaokai627@163.com Signed-off-by: Ran Xiaokai <ran.xiaokai@zte.com.cn> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Pratyush Yadav <pratyush@kernel.org> Cc: Alexander Graf <graf@amazon.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Changyuan Lyu <changyuanl@google.com> Cc: Pasha Tatashin <pasha.tatashin@soleen.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent fb5c364 commit 40cd0e8

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

kernel/liveupdate/kexec_handover.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <linux/cleanup.h>
1313
#include <linux/cma.h>
14+
#include <linux/kmemleak.h>
1415
#include <linux/count_zeros.h>
1516
#include <linux/kexec.h>
1617
#include <linux/kexec_handover.h>
@@ -1369,6 +1370,15 @@ static __init int kho_init(void)
13691370
unsigned long count = kho_scratch[i].size >> PAGE_SHIFT;
13701371
unsigned long pfn;
13711372

1373+
/*
1374+
* When debug_pagealloc is enabled, __free_pages() clears the
1375+
* corresponding PRESENT bit in the kernel page table.
1376+
* Subsequent kmemleak scans of these pages cause the
1377+
* non-PRESENT page faults.
1378+
* Mark scratch areas with kmemleak_ignore_phys() to exclude
1379+
* them from kmemleak scanning.
1380+
*/
1381+
kmemleak_ignore_phys(kho_scratch[i].addr);
13721382
for (pfn = base_pfn; pfn < base_pfn + count;
13731383
pfn += pageblock_nr_pages)
13741384
init_cma_reserved_pageblock(pfn_to_page(pfn));

0 commit comments

Comments
 (0)