[RFC PATCH 8/8] arm64: efi: leave MMU and caches on when handing over to the core kernel

Ard Biesheuvel ardb at kernel.org
Fri Mar 4 09:56:57 PST 2022


Instead of cleaning the entire kernel image to the PoC and enter with
the MMU and caches disabled, leave them on and let the primary boot code
deal with this if we are executing at EL1.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kernel/efi-entry.S      | 20 ++++++++++----------
 drivers/firmware/efi/libstub/fdt.c |  6 ++++--
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S
index 61a87fa1c305..7eca829869b4 100644
--- a/arch/arm64/kernel/efi-entry.S
+++ b/arch/arm64/kernel/efi-entry.S
@@ -23,6 +23,10 @@ SYM_CODE_START(efi_enter_kernel)
 	add	x19, x0, x2		// relocated Image entrypoint
 	mov	x20, x1			// DTB address
 
+	mrs	x0, CurrentEL
+	cmp	x0, #CurrentEL_EL2
+	b.ne	1f
+
 	/*
 	 * Clean the copied Image to the PoC, and ensure it is not shadowed by
 	 * stale icache entries from before relocation.
@@ -41,29 +45,25 @@ SYM_CODE_START(efi_enter_kernel)
 	bl	dcache_clean_poc
 0:
 	/* Turn off Dcache and MMU */
-	mrs	x0, CurrentEL
-	cmp	x0, #CurrentEL_EL2
-	b.ne	1f
 	mrs	x0, sctlr_el2
 	bic	x0, x0, #1 << 0	// clear SCTLR.M
 	bic	x0, x0, #1 << 2	// clear SCTLR.C
 	pre_disable_mmu_workaround
 	msr	sctlr_el2, x0
 	isb
+	mov	x1, xzr
 	b	2f
 1:
-	mrs	x0, sctlr_el1
-	bic	x0, x0, #1 << 0	// clear SCTLR.M
-	bic	x0, x0, #1 << 2	// clear SCTLR.C
-	pre_disable_mmu_workaround
-	msr	sctlr_el1, x0
-	isb
+	ldr_l	x1, kaslr_seed
 2:
 	/* Jump to kernel entry point */
 	mov	x0, x20
-	mov	x1, xzr
 	mov	x2, xzr
 	mov	x3, xzr
 	br	x19
 3:
 SYM_CODE_END(efi_enter_kernel)
+
+	.section ".bss", "aw", %nobits
+	.align	3
+SYM_DATA(kaslr_seed, .quad 0x0)
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index fe567be0f118..ec34c29d311d 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -137,11 +137,13 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
 		goto fdt_set_fail;
 
 	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && !efi_nokaslr) {
+		extern u64 kaslr_seed;
 		efi_status_t efi_status;
 
-		efi_status = efi_get_random_bytes(sizeof(fdt_val64),
-						  (u8 *)&fdt_val64);
+		efi_status = efi_get_random_bytes(sizeof(kaslr_seed),
+						  (u8 *)&kaslr_seed);
 		if (efi_status == EFI_SUCCESS) {
+			fdt_val64 = cpu_to_fdt64(kaslr_seed);
 			status = fdt_setprop_var(fdt, node, "kaslr-seed", fdt_val64);
 			if (status)
 				goto fdt_set_fail;
-- 
2.30.2




More information about the linux-arm-kernel mailing list