diff options
author | Vasily Gorbik <gor@linux.ibm.com> | 2018-09-13 10:59:25 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-10-09 11:21:33 +0200 |
commit | 296352397db68313a189e65a3513960a2c844632 (patch) | |
tree | cdfed6ca3d9b7b38656cf207f19f7c2e9df7a650 /arch | |
parent | 19733fe8721b8d91b799c91082ebb9c139ca6710 (diff) |
s390/kasan: avoid kasan crash with standby memory defined
Kasan early memory allocator simply chops off memory blocks from the
end of the physical memory. Reuse mem_detect info to identify actual
online memory end rather than using max_physmem_end. This allows to run
the kernel with kasan enabled and standby memory defined.
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/mm/kasan_init.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/arch/s390/mm/kasan_init.c b/arch/s390/mm/kasan_init.c index 5129847018ba..6b0574340f7f 100644 --- a/arch/s390/mm/kasan_init.c +++ b/arch/s390/mm/kasan_init.c @@ -5,6 +5,7 @@ #include <asm/pgalloc.h> #include <asm/pgtable.h> #include <asm/kasan.h> +#include <asm/mem_detect.h> #include <asm/processor.h> #include <asm/sclp.h> #include <asm/facility.h> @@ -233,6 +234,18 @@ static void __init kasan_early_detect_facilities(void) } } +static unsigned long __init get_mem_detect_end(void) +{ + unsigned long start; + unsigned long end; + + if (mem_detect.count) { + __get_mem_detect_block(mem_detect.count - 1, &start, &end); + return end; + } + return 0; +} + void __init kasan_early_init(void) { unsigned long untracked_mem_end; @@ -252,6 +265,11 @@ void __init kasan_early_init(void) pgt_prot &= ~_PAGE_NOEXEC; pte_z = __pte(__pa(kasan_zero_page) | pgt_prot); + memsize = get_mem_detect_end(); + if (!memsize) + kasan_early_panic("cannot detect physical memory size\n"); + memsize = min(memsize, KASAN_SHADOW_START); + if (IS_ENABLED(CONFIG_KASAN_S390_4_LEVEL_PAGING)) { /* 4 level paging */ BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, P4D_SIZE)); @@ -276,7 +294,6 @@ void __init kasan_early_init(void) crst_table_init((unsigned long *)kasan_zero_pmd, pmd_val(pmd_z)); memset64((u64 *)kasan_zero_pte, pte_val(pte_z), PTRS_PER_PTE); - memsize = min(max_physmem_end, KASAN_SHADOW_START); shadow_alloc_size = memsize >> KASAN_SHADOW_SCALE_SHIFT; pgalloc_low = round_up((unsigned long)_end, _SEGMENT_SIZE); if (IS_ENABLED(CONFIG_BLK_DEV_INITRD)) { |