summaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorVasily Gorbik <gor@linux.ibm.com>2017-11-20 12:56:10 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-10-09 11:21:29 +0200
commit135ff163939294f5573927ca890699ed619c0031 (patch)
tree9f2db851306f6dfdc58dc2249677507e560feeef /arch/s390
parent5e785963298b7923e28817d20868882fbefc863c (diff)
downloadlinux-135ff163939294f5573927ca890699ed619c0031.tar.bz2
s390/kasan: free early identity mapping structures
Kasan initialization code is changed to populate persistent shadow first, save allocator position into pgalloc_freeable and proceed with early identity mapping creation. This way early identity mapping paging structures could be freed at once after switching to swapper_pg_dir when early identity mapping is not needed anymore. 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>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/kasan.h2
-rw-r--r--arch/s390/mm/init.c1
-rw-r--r--arch/s390/mm/kasan_init.c12
3 files changed, 13 insertions, 2 deletions
diff --git a/arch/s390/include/asm/kasan.h b/arch/s390/include/asm/kasan.h
index 892f4585c663..8b9ae18430ad 100644
--- a/arch/s390/include/asm/kasan.h
+++ b/arch/s390/include/asm/kasan.h
@@ -15,9 +15,11 @@
extern void kasan_early_init(void);
extern void kasan_copy_shadow(pgd_t *dst);
+extern void kasan_free_early_identity(void);
#else
static inline void kasan_early_init(void) { }
static inline void kasan_copy_shadow(pgd_t *dst) { }
+static inline void kasan_free_early_identity(void) { }
#endif
#endif
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 50ebda9b3d0c..92d7a153e72a 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -109,6 +109,7 @@ void __init paging_init(void)
psw_bits(psw).dat = 1;
psw_bits(psw).as = PSW_BITS_AS_HOME;
__load_psw_mask(psw.mask);
+ kasan_free_early_identity();
sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
diff --git a/arch/s390/mm/kasan_init.c b/arch/s390/mm/kasan_init.c
index e4697900e884..40748afc43fa 100644
--- a/arch/s390/mm/kasan_init.c
+++ b/arch/s390/mm/kasan_init.c
@@ -15,6 +15,7 @@ static unsigned long segment_pos __initdata;
static unsigned long segment_low __initdata;
static unsigned long pgalloc_pos __initdata;
static unsigned long pgalloc_low __initdata;
+static unsigned long pgalloc_freeable __initdata;
static bool has_edat __initdata;
static bool has_nx __initdata;
@@ -298,14 +299,16 @@ void __init kasan_early_init(void)
* | 2Gb | \| unmapped | allocated per module
* +-----------------+ +- shadow end ---+
*/
- /* populate identity mapping */
- kasan_early_vmemmap_populate(0, memsize, POPULATE_ONE2ONE);
/* populate kasan shadow (for identity mapping and zero page mapping) */
kasan_early_vmemmap_populate(__sha(0), __sha(memsize), POPULATE_MAP);
if (IS_ENABLED(CONFIG_MODULES))
untracked_mem_end = vmax - MODULES_LEN;
kasan_early_vmemmap_populate(__sha(memsize), __sha(untracked_mem_end),
POPULATE_ZERO_SHADOW);
+ /* memory allocated for identity mapping structs will be freed later */
+ pgalloc_freeable = pgalloc_pos;
+ /* populate identity mapping */
+ kasan_early_vmemmap_populate(0, memsize, POPULATE_ONE2ONE);
kasan_set_pgd(early_pg_dir, asce_type);
kasan_enable_dat();
/* enable kasan */
@@ -345,3 +348,8 @@ void __init kasan_copy_shadow(pgd_t *pg_dir)
memcpy(pu_dir_dst, pu_dir_src,
(KASAN_SHADOW_SIZE >> PUD_SHIFT) * sizeof(pud_t));
}
+
+void __init kasan_free_early_identity(void)
+{
+ memblock_free(pgalloc_pos, pgalloc_freeable - pgalloc_pos);
+}