s390/kasan: add option for 4-level paging support
authorVasily Gorbik <gor@linux.ibm.com>
Sun, 19 Nov 2017 10:54:14 +0000 (11:54 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 9 Oct 2018 09:21:29 +0000 (11:21 +0200)
By default 3-level paging is used when the kernel is compiled with
kasan support. Add 4-level paging option to support systems with more
then 3TB of physical memory and to cover 4-level paging specific code
with kasan as well.

Reviewed-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/Kconfig
arch/s390/include/asm/kasan.h
arch/s390/kernel/setup.c
arch/s390/mm/kasan_init.c
lib/Kconfig.kasan

index 24586257c5cd74994f6df5d2491a84e5eb3ebea2..cc8313550493a47b15c76700e9fb35e94a28eb0d 100644 (file)
@@ -59,6 +59,7 @@ config ARCH_SUPPORTS_UPROBES
 config KASAN_SHADOW_OFFSET
        hex
        depends on KASAN
+       default 0x18000000000000 if KASAN_S390_4_LEVEL_PAGING
        default 0x30000000000
 
 config S390
index 8b9ae18430ad18928183c990b511c9ce880bf52d..70930fe5c4962bd4d09b3e6ea843b2fadd9803d4 100644 (file)
@@ -7,8 +7,13 @@
 #ifdef CONFIG_KASAN
 
 #define KASAN_SHADOW_SCALE_SHIFT 3
+#ifdef CONFIG_KASAN_S390_4_LEVEL_PAGING
+#define KASAN_SHADOW_SIZE                                                     \
+       (_AC(1, UL) << (_REGION1_SHIFT - KASAN_SHADOW_SCALE_SHIFT))
+#else
 #define KASAN_SHADOW_SIZE                                                     \
        (_AC(1, UL) << (_REGION2_SHIFT - KASAN_SHADOW_SCALE_SHIFT))
+#endif
 #define KASAN_SHADOW_OFFSET    _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
 #define KASAN_SHADOW_START     KASAN_SHADOW_OFFSET
 #define KASAN_SHADOW_END       (KASAN_SHADOW_START + KASAN_SHADOW_SIZE)
index d7548806d8875f482e258adbf5b2e350018593fc..4b2039f3e2f4c3dfd7fdd197febaf7a87aee5286 100644 (file)
@@ -535,7 +535,9 @@ static void __init setup_memory_end(void)
        /* Choose kernel address space layout: 3 or 4 levels. */
        vmalloc_size = VMALLOC_END ?: (128UL << 30) - MODULES_LEN;
        if (IS_ENABLED(CONFIG_KASAN)) {
-               vmax = _REGION2_SIZE; /* 3-level kernel page table */
+               vmax = IS_ENABLED(CONFIG_KASAN_S390_4_LEVEL_PAGING)
+                          ? _REGION1_SIZE
+                          : _REGION2_SIZE;
        } else {
                tmp = (memory_end ?: max_physmem_end) / PAGE_SIZE;
                tmp = tmp * (sizeof(struct page) + PAGE_SIZE);
index 40748afc43fa5e234915676496667563151d8bee..5129847018bab6ca7364b6df3e4361395e8b1cc0 100644 (file)
@@ -252,12 +252,23 @@ void __init kasan_early_init(void)
                pgt_prot &= ~_PAGE_NOEXEC;
        pte_z = __pte(__pa(kasan_zero_page) | pgt_prot);
 
-       /* 3 level paging */
-       BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PUD_SIZE));
-       BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PUD_SIZE));
-       crst_table_init((unsigned long *)early_pg_dir, _REGION3_ENTRY_EMPTY);
-       untracked_mem_end = vmax = _REGION2_SIZE;
-       asce_type = _ASCE_TYPE_REGION3;
+       if (IS_ENABLED(CONFIG_KASAN_S390_4_LEVEL_PAGING)) {
+               /* 4 level paging */
+               BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, P4D_SIZE));
+               BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, P4D_SIZE));
+               crst_table_init((unsigned long *)early_pg_dir,
+                               _REGION2_ENTRY_EMPTY);
+               untracked_mem_end = vmax = _REGION1_SIZE;
+               asce_type = _ASCE_TYPE_REGION2;
+       } else {
+               /* 3 level paging */
+               BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PUD_SIZE));
+               BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PUD_SIZE));
+               crst_table_init((unsigned long *)early_pg_dir,
+                               _REGION3_ENTRY_EMPTY);
+               untracked_mem_end = vmax = _REGION2_SIZE;
+               asce_type = _ASCE_TYPE_REGION3;
+       }
 
        /* init kasan zero shadow */
        crst_table_init((unsigned long *)kasan_zero_p4d, p4d_val(p4d_z));
index befb127507c0b1cb05f6f83b81464e99f4ac4fb0..d0bad1bd9a2b1ef148058dff17eb6375f019fb2a 100644 (file)
@@ -57,6 +57,15 @@ config KASAN_INLINE
 
 endchoice
 
+config KASAN_S390_4_LEVEL_PAGING
+       bool "KASan: use 4-level paging"
+       depends on KASAN && S390
+       help
+         Compiling the kernel with KASan disables automatic 3-level vs
+         4-level paging selection. 3-level paging is used by default (up
+         to 3TB of RAM with KASan enabled). This options allows to force
+         4-level paging instead.
+
 config TEST_KASAN
        tristate "Module for testing kasan for bug detection"
        depends on m && KASAN