Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

kmemleak: powerpc: skip scanning holes in the .bss section

Commit 2d4f567103ff ("KVM: PPC: Introduce kvm_tmp framework") adds
kvm_tmp[] into the .bss section and then free the rest of unused spaces
back to the page allocator.

kernel_init
kvm_guest_init
kvm_free_tmp
free_reserved_area
free_unref_page
free_unref_page_prepare

With DEBUG_PAGEALLOC=y, it will unmap those pages from kernel. As the
result, kmemleak scan will trigger a panic when it scans the .bss
section with unmapped pages.

This patch creates dedicated kmemleak objects for the .data, .bss and
potentially .data..ro_after_init sections to allow partial freeing via
the kmemleak_free_part() in the powerpc kvm_free_tmp() function.

Link: http://lkml.kernel.org/r/20190321171917.62049-1-catalin.marinas@arm.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Reported-by: Qian Cai <cai@lca.pw>
Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)
Tested-by: Qian Cai <cai@lca.pw>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Avi Kivity <avi@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krcmar <rkrcmar@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Catalin Marinas and committed by
Linus Torvalds
298a32b1 5f074f3e

+18 -5
+7
arch/powerpc/kernel/kvm.c
··· 22 22 #include <linux/kvm_host.h> 23 23 #include <linux/init.h> 24 24 #include <linux/export.h> 25 + #include <linux/kmemleak.h> 25 26 #include <linux/kvm_para.h> 26 27 #include <linux/slab.h> 27 28 #include <linux/of.h> ··· 713 712 714 713 static __init void kvm_free_tmp(void) 715 714 { 715 + /* 716 + * Inform kmemleak about the hole in the .bss section since the 717 + * corresponding pages will be unmapped with DEBUG_PAGEALLOC=y. 718 + */ 719 + kmemleak_free_part(&kvm_tmp[kvm_tmp_index], 720 + ARRAY_SIZE(kvm_tmp) - kvm_tmp_index); 716 721 free_reserved_area(&kvm_tmp[kvm_tmp_index], 717 722 &kvm_tmp[ARRAY_SIZE(kvm_tmp)], -1, NULL); 718 723 }
+11 -5
mm/kmemleak.c
··· 1529 1529 } 1530 1530 rcu_read_unlock(); 1531 1531 1532 - /* data/bss scanning */ 1533 - scan_large_block(_sdata, _edata); 1534 - scan_large_block(__bss_start, __bss_stop); 1535 - scan_large_block(__start_ro_after_init, __end_ro_after_init); 1536 - 1537 1532 #ifdef CONFIG_SMP 1538 1533 /* per-cpu sections scanning */ 1539 1534 for_each_possible_cpu(i) ··· 2065 2070 kmemleak_free_enabled = 1; 2066 2071 } 2067 2072 local_irq_restore(flags); 2073 + 2074 + /* register the data/bss sections */ 2075 + create_object((unsigned long)_sdata, _edata - _sdata, 2076 + KMEMLEAK_GREY, GFP_ATOMIC); 2077 + create_object((unsigned long)__bss_start, __bss_stop - __bss_start, 2078 + KMEMLEAK_GREY, GFP_ATOMIC); 2079 + /* only register .data..ro_after_init if not within .data */ 2080 + if (__start_ro_after_init < _sdata || __end_ro_after_init > _edata) 2081 + create_object((unsigned long)__start_ro_after_init, 2082 + __end_ro_after_init - __start_ro_after_init, 2083 + KMEMLEAK_GREY, GFP_ATOMIC); 2068 2084 2069 2085 /* 2070 2086 * This is the point where tracking allocations is safe. Automatic