The original kernel still exists in the memory, clear it now. Signed-off-by: Jason Yan <yanaijie@xxxxxxxxxx> Cc: Diana Craciun <diana.craciun@xxxxxxx> Cc: Michael Ellerman <mpe@xxxxxxxxxxxxxx> Cc: Christophe Leroy <christophe.leroy@xxxxxx> Cc: Benjamin Herrenschmidt <benh@xxxxxxxxxxxxxxxxxxx> Cc: Paul Mackerras <paulus@xxxxxxxxx> Cc: Nicholas Piggin <npiggin@xxxxxxxxx> Cc: Kees Cook <keescook@xxxxxxxxxxxx> Reviewed-by: Christophe Leroy <christophe.leroy@xxxxxx> Reviewed-by: Diana Craciun <diana.craciun@xxxxxxx> Tested-by: Diana Craciun <diana.craciun@xxxxxxx> --- arch/powerpc/mm/mmu_decl.h | 2 ++ arch/powerpc/mm/nohash/fsl_booke.c | 1 + arch/powerpc/mm/nohash/kaslr_booke.c | 11 +++++++++++ 3 files changed, 14 insertions(+) diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index a3a4937c0496..565731475a07 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -151,8 +151,10 @@ extern void loadcam_multi(int first_idx, int num, int tmp_idx); #ifdef CONFIG_RANDOMIZE_BASE void kaslr_early_init(void *dt_ptr, phys_addr_t size); +void kaslr_late_init(void); #else static inline void kaslr_early_init(void *dt_ptr, phys_addr_t size) {} +static inline void kaslr_late_init(void) {} #endif struct tlbcam { diff --git a/arch/powerpc/mm/nohash/fsl_booke.c b/arch/powerpc/mm/nohash/fsl_booke.c index 2dc27cf88add..b4eb06ceb189 100644 --- a/arch/powerpc/mm/nohash/fsl_booke.c +++ b/arch/powerpc/mm/nohash/fsl_booke.c @@ -269,6 +269,7 @@ notrace void __init relocate_init(u64 dt_ptr, phys_addr_t start) kernstart_addr = start; if (is_second_reloc) { virt_phys_offset = PAGE_OFFSET - memstart_addr; + kaslr_late_init(); return; } diff --git a/arch/powerpc/mm/nohash/kaslr_booke.c b/arch/powerpc/mm/nohash/kaslr_booke.c index 7b238fc2c8a9..aa1b60c782e7 100644 --- a/arch/powerpc/mm/nohash/kaslr_booke.c +++ b/arch/powerpc/mm/nohash/kaslr_booke.c @@ -381,3 +381,14 @@ notrace void __init kaslr_early_init(void *dt_ptr, phys_addr_t size) reloc_kernel_entry(dt_ptr, kernstart_virt_addr); } + +void __init kaslr_late_init(void) +{ + /* If randomized, clear the original kernel */ + if (kernstart_virt_addr != KERNELBASE) { + unsigned long kernel_sz; + + kernel_sz = (unsigned long)_end - kernstart_virt_addr; + memzero_explicit((void *)KERNELBASE, kernel_sz); + } +} -- 2.17.2