Skip to content

Commit

Permalink
memblock: exclude MEMBLOCK_NOMAP regions from kmemleak
Browse files Browse the repository at this point in the history
Vladimir Zapolskiy reports:

Commit a7259df ("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/[email protected]
Link: https://lore.kernel.org/all/[email protected]
Fixes: a7259df ("memblock: make memblock_find_in_range method private")
Reported-by: Vladimir Zapolskiy <[email protected]>
Signed-off-by: Mike Rapoport <[email protected]>
Reviewed-by: Catalin Marinas <[email protected]>
Tested-by: Vladimir Zapolskiy <[email protected]>
Tested-by: Qian Cai <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
rppt authored and torvalds committed Oct 22, 2021
1 parent 6c9a545 commit 658aafc
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 0 deletions.
3 changes: 3 additions & 0 deletions drivers/acpi/tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/earlycpio.h>
#include <linux/initrd.h>
#include <linux/security.h>
#include <linux/kmemleak.h>
#include "internal.h"

#ifdef CONFIG_ACPI_CUSTOM_DSDT
Expand Down Expand Up @@ -601,6 +602,8 @@ void __init acpi_table_upgrade(void)
*/
arch_reserve_mem_area(acpi_tables_addr, all_tables_size);

kmemleak_ignore_phys(acpi_tables_addr);

/*
* early_ioremap only can remap 256k one time. If we map all
* tables one time, we will hit the limit. Need to map chunks
Expand Down
2 changes: 2 additions & 0 deletions drivers/of/of_reserved_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/sort.h>
#include <linux/slab.h>
#include <linux/memblock.h>
#include <linux/kmemleak.h>

#include "of_private.h"

Expand All @@ -46,6 +47,7 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
err = memblock_mark_nomap(base, size);
if (err)
memblock_free(base, size);
kmemleak_ignore_phys(base);
}

return err;
Expand Down
3 changes: 3 additions & 0 deletions mm/memblock.c
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,9 @@ int __init_memblock memblock_mark_mirror(phys_addr_t base, phys_addr_t size)
* covered by the memory map. The struct page representing NOMAP memory
* frames in the memory map will be PageReserved()
*
* Note: if the memory being marked %MEMBLOCK_NOMAP was allocated from
* memblock, the caller must inform kmemleak to ignore that memory
*
* Return: 0 on success, -errno on failure.
*/
int __init_memblock memblock_mark_nomap(phys_addr_t base, phys_addr_t size)
Expand Down

0 comments on commit 658aafc

Please sign in to comment.