Commit 314a43d0 authored by Jason Yan's avatar Jason Yan Committed by GUO Zihua
Browse files

powerpc/fsl_booke/64: implement KASLR for fsl_booke64

maillist inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8OHAZ
CVE: NA

Reference: https://patchwork.ozlabs.org/project/linuxppc-dev/patch/20200330022023.3691-4-yanaijie@huawei.com/



-------------------------------------------------

The implementation for Freescale BookE64 is similar as BookE32. One
difference is that Freescale BookE64 set up a TLB mapping of 1G during
booting. Another difference is that ppc64 needs the kernel to be
64K-aligned. So we can randomize the kernel in this 1G mapping and make
it 64K-aligned. This can save some code to creat another TLB map at
early boot. The disadvantage is that we only have about 1G/64K = 16384
slots to put the kernel in.

To support secondary cpu boot up, a variable __kaslr_offset was added in
first_256B section. This can help secondary cpu get the kaslr offset
before the 1:1 mapping has been setup.

Signed-off-by: default avatarJason Yan <yanaijie@huawei.com>
Cc: Scott Wood <oss@buserror.net>
Cc: Diana Craciun <diana.craciun@nxp.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Kees Cook <keescook@chromium.org>
Signed-off-by: default avatarCui GaoSheng <cuigaosheng1@huawei.com>
Signed-off-by: default avatarGUO Zihua <guozihua@huawei.com>
parent 005684e6
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -660,14 +660,15 @@ config RELOCATABLE

config RANDOMIZE_BASE
	bool "Randomize the address of the kernel image"
	depends on PPC_85xx && FLATMEM
	depends on PPC_E500 && FLATMEM
	depends on RELOCATABLE
	default n
	help
	  Randomizes the virtual address at which the kernel image is
	  loaded, as a security feature that deters exploit attempts
	  relying on knowledge of the location of kernel internals.

	  If unsure, say Y.
	  If unsure, say N.

config RELOCATABLE_TEST
	bool "Test relocatable kernel"
+10 −0
Original line number Diff line number Diff line
@@ -1249,6 +1249,7 @@ skpinv: addi r6,r6,1 /* Increment */
1:	mflr	r6
	addi	r6,r6,(2f - 1b)
	tovirt(r6,r6)
	add	r6,r6,r19
	lis	r7,MSR_KERNEL@h
	ori	r7,r7,MSR_KERNEL@l
	mtspr	SPRN_SRR0,r6
@@ -1271,6 +1272,7 @@ skpinv: addi r6,r6,1 /* Increment */

	/* We translate LR and return */
	tovirt(r8,r8)
	add	r8,r8,r19
	mtlr	r8
	blr

@@ -1403,6 +1405,7 @@ a2_tlbinit_code_end:
 */
_GLOBAL(start_initialization_book3e)
	mflr	r28
	li	r19, 0

	/* First, we need to setup some initial TLBs to map the kernel
	 * text, data and bss at PAGE_OFFSET. We don't have a real mode
@@ -1445,6 +1448,12 @@ _GLOBAL(book3e_secondary_core_init)
	cmplwi	r4,0
	bne	2f

	li	r19, 0
#ifdef CONFIG_RANDOMIZE_BASE
	LOAD_REG_ADDR_PIC(r19, __kaslr_offset)
	ld	r19,0(r19)
	rlwinm  r19,r19,0,0,5
#endif
	/* Setup TLB for this core */
	bl	initial_tlb_book3e

@@ -1477,6 +1486,7 @@ _GLOBAL(book3e_secondary_core_init)
	lis	r3,PAGE_OFFSET@highest
	sldi	r3,r3,32
	or	r28,r28,r3
	add	r28,r28,r19
1:	mtlr	r28
	blr

+6 −0
Original line number Diff line number Diff line
@@ -116,6 +116,12 @@ __secondary_hold_acknowledge:
	.8byte	0x0

#ifdef CONFIG_RELOCATABLE
#ifdef CONFIG_RANDOMIZE_BASE
	.globl	__kaslr_offset
__kaslr_offset:
	.8byte	0x0
#endif

	/* This flag is set to 1 by a loader if the kernel should run
	 * at the loaded address instead of the linked address.  This
	 * is used by kexec-tools to keep the kdump kernel in the
+3 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@
#include <asm/early_ioremap.h>
#include <asm/pgalloc.h>

#include <mm/mmu_decl.h>
#include "setup.h"

int spinning_secondaries;
@@ -380,6 +381,8 @@ void __init early_setup(unsigned long dt_ptr)
	/* Enable early debugging if any specified (see udbg.h) */
	udbg_early_init();

	kaslr_early_init(__va(dt_ptr), 0);

	udbg_printf(" -> %s(), dt_ptr: 0x%lx\n", __func__, dt_ptr);

	/*
+12 −10
Original line number Diff line number Diff line
@@ -119,23 +119,17 @@ extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx,
extern void adjust_total_lowmem(void);
extern int switch_to_as1(void);
extern void restore_to_as0(int esel, int offset, void *dt_ptr, int bootcpu);
void create_kaslr_tlb_entry(int entry, unsigned long virt, phys_addr_t phys);
void relocate_init(u64 dt_ptr, phys_addr_t start);
extern int is_second_reloc;
#endif
void create_kaslr_tlb_entry(int entry, unsigned long virt, phys_addr_t phys);
extern int is_second_reloc;
extern unsigned long __kaslr_offset;
extern unsigned int __run_at_load;

void reloc_kernel_entry(void *fdt, long addr);
extern void loadcam_entry(unsigned int index);
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 {
	u32	MAS0;
	u32	MAS1;
@@ -149,6 +143,14 @@ struct tlbcam {
extern struct tlbcam TLBCAM[NUM_TLBCAMS];
#endif

#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

#if defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_8xx)
/* 6xx have BATS */
/* PPC_85xx have TLBCAM */
Loading