summaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorVasily Gorbik <gor@linux.ibm.com>2018-09-13 10:59:25 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-10-09 11:21:33 +0200
commit296352397db68313a189e65a3513960a2c844632 (patch)
treecdfed6ca3d9b7b38656cf207f19f7c2e9df7a650 /arch/s390
parents390/head: avoid doubling early boot stack size under KASAN (diff)
downloadlinux-296352397db68313a189e65a3513960a2c844632.tar.xz
linux-296352397db68313a189e65a3513960a2c844632.zip
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/s390')
-rw-r--r--arch/s390/mm/kasan_init.c19
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)) {