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.

memblock: exclude MEMBLOCK_NOMAP regions from kmemleak

Vladimir Zapolskiy reports:

Commit a7259df76702 ("memblock: make memblock_find_in_range method
private") invokes a kernel panic while running kmemleak on OF platforms
with nomaped regions:

Unable to handle kernel paging request at virtual address fff000021e00000
[...]
scan_block+0x64/0x170
scan_gray_list+0xe8/0x17c
kmemleak_scan+0x270/0x514
kmemleak_write+0x34c/0x4ac

The memory allocated from memblock is registered with kmemleak, but if
it is marked MEMBLOCK_NOMAP it won't have linear map entries so an
attempt to scan such areas will fault.

Ideally, memblock_mark_nomap() would inform kmemleak to ignore
MEMBLOCK_NOMAP memory, but it can be called before kmemleak interfaces
operating on physical addresses can use __va() conversion.

Make sure that functions that mark allocated memory as MEMBLOCK_NOMAP
take care of informing kmemleak to ignore such memory.

Link: https://lore.kernel.org/all/8ade5174-b143-d621-8c8e-dc6a1898c6fb@linaro.org
Link: https://lore.kernel.org/all/c30ff0a2-d196-c50d-22f0-bd50696b1205@quicinc.com
Fixes: a7259df76702 ("memblock: make memblock_find_in_range method private")
Reported-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Tested-by: Qian Cai <quic_qiancai@quicinc.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Mike Rapoport and committed by
Linus Torvalds
658aafc8 6c9a5455

+8
+3
drivers/acpi/tables.c
··· 21 21 #include <linux/earlycpio.h> 22 22 #include <linux/initrd.h> 23 23 #include <linux/security.h> 24 + #include <linux/kmemleak.h> 24 25 #include "internal.h" 25 26 26 27 #ifdef CONFIG_ACPI_CUSTOM_DSDT ··· 601 600 * works fine. 602 601 */ 603 602 arch_reserve_mem_area(acpi_tables_addr, all_tables_size); 603 + 604 + kmemleak_ignore_phys(acpi_tables_addr); 604 605 605 606 /* 606 607 * early_ioremap only can remap 256k one time. If we map all
+2
drivers/of/of_reserved_mem.c
··· 21 21 #include <linux/sort.h> 22 22 #include <linux/slab.h> 23 23 #include <linux/memblock.h> 24 + #include <linux/kmemleak.h> 24 25 25 26 #include "of_private.h" 26 27 ··· 47 46 err = memblock_mark_nomap(base, size); 48 47 if (err) 49 48 memblock_free(base, size); 49 + kmemleak_ignore_phys(base); 50 50 } 51 51 52 52 return err;
+3
mm/memblock.c
··· 932 932 * covered by the memory map. The struct page representing NOMAP memory 933 933 * frames in the memory map will be PageReserved() 934 934 * 935 + * Note: if the memory being marked %MEMBLOCK_NOMAP was allocated from 936 + * memblock, the caller must inform kmemleak to ignore that memory 937 + * 935 938 * Return: 0 on success, -errno on failure. 936 939 */ 937 940 int __init_memblock memblock_mark_nomap(phys_addr_t base, phys_addr_t size)