From 6c09af9f8b36cdfa1dc4d5052f7e4792f63fa88a Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Fri, 9 Jul 2021 11:37:10 -0500 Subject: feat(rme): run BL2 in root world when FEAT_RME is enabled This patch enables BL2 to run in root world (EL3) which is needed as per the security model of RME-enabled systems. Using the existing BL2_AT_EL3 TF-A build option is not convenient because that option assumes TF-A BL1 doesn't exist, which is not the case for RME-enabled systems. For the purposes of RME, we use a normal BL1 image but we also want to run BL2 in EL3 as normally as possible, therefore rather than use the special bl2_entrypoint function in bl2_el3_entrypoint.S, we use a new bl2_entrypoint function (in bl2_rme_entrypoint.S) which doesn't need reset or mailbox initialization code seen in the el3_entrypoint_common macro. The patch also cleans up bl2_el3_entrypoint.S, moving the bl2_run_next_image function to its own file to avoid duplicating code. Signed-off-by: Zelalem Aweke Change-Id: I99821b4cd550cadcb701f4c0c4dc36da81c7ef55 --- bl2/aarch32/bl2_el3_entrypoint.S | 37 +--------------------- bl2/aarch32/bl2_run_next_image.S | 46 +++++++++++++++++++++++++++ bl2/aarch64/bl2_el3_entrypoint.S | 37 +--------------------- bl2/aarch64/bl2_rme_entrypoint.S | 67 ++++++++++++++++++++++++++++++++++++++++ bl2/aarch64/bl2_run_next_image.S | 45 +++++++++++++++++++++++++++ bl2/bl2.ld.S | 6 +++- bl2/bl2.mk | 15 +++++++-- bl2/bl2_main.c | 31 +++++++++---------- 8 files changed, 193 insertions(+), 91 deletions(-) create mode 100644 bl2/aarch32/bl2_run_next_image.S create mode 100644 bl2/aarch64/bl2_rme_entrypoint.S create mode 100644 bl2/aarch64/bl2_run_next_image.S (limited to 'bl2') diff --git a/bl2/aarch32/bl2_el3_entrypoint.S b/bl2/aarch32/bl2_el3_entrypoint.S index 7e855516d..40154aad6 100644 --- a/bl2/aarch32/bl2_el3_entrypoint.S +++ b/bl2/aarch32/bl2_el3_entrypoint.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,7 +10,6 @@ #include .globl bl2_entrypoint - .globl bl2_run_next_image func bl2_entrypoint @@ -56,37 +55,3 @@ func bl2_entrypoint no_ret plat_panic_handler endfunc bl2_entrypoint - -func bl2_run_next_image - mov r8,r0 - - /* - * MMU needs to be disabled because both BL2 and BL32 execute - * in PL1, and therefore share the same address space. - * BL32 will initialize the address space according to its - * own requirement. - */ - bl disable_mmu_icache_secure - stcopr r0, TLBIALL - dsb sy - isb - mov r0, r8 - bl bl2_el3_plat_prepare_exit - - /* - * Extract PC and SPSR based on struct `entry_point_info_t` - * and load it in LR and SPSR registers respectively. - */ - ldr lr, [r8, #ENTRY_POINT_INFO_PC_OFFSET] - ldr r1, [r8, #(ENTRY_POINT_INFO_PC_OFFSET + 4)] - msr spsr_xc, r1 - - /* Some BL32 stages expect lr_svc to provide the BL33 entry address */ - cps #MODE32_svc - ldr lr, [r8, #ENTRY_POINT_INFO_LR_SVC_OFFSET] - cps #MODE32_mon - - add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET - ldm r8, {r0, r1, r2, r3} - exception_return -endfunc bl2_run_next_image diff --git a/bl2/aarch32/bl2_run_next_image.S b/bl2/aarch32/bl2_run_next_image.S new file mode 100644 index 000000000..0b3554edc --- /dev/null +++ b/bl2/aarch32/bl2_run_next_image.S @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + .globl bl2_run_next_image + + +func bl2_run_next_image + mov r8,r0 + + /* + * MMU needs to be disabled because both BL2 and BL32 execute + * in PL1, and therefore share the same address space. + * BL32 will initialize the address space according to its + * own requirement. + */ + bl disable_mmu_icache_secure + stcopr r0, TLBIALL + dsb sy + isb + mov r0, r8 + bl bl2_el3_plat_prepare_exit + + /* + * Extract PC and SPSR based on struct `entry_point_info_t` + * and load it in LR and SPSR registers respectively. + */ + ldr lr, [r8, #ENTRY_POINT_INFO_PC_OFFSET] + ldr r1, [r8, #(ENTRY_POINT_INFO_PC_OFFSET + 4)] + msr spsr_xc, r1 + + /* Some BL32 stages expect lr_svc to provide the BL33 entry address */ + cps #MODE32_svc + ldr lr, [r8, #ENTRY_POINT_INFO_LR_SVC_OFFSET] + cps #MODE32_mon + + add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET + ldm r8, {r0, r1, r2, r3} + exception_return +endfunc bl2_run_next_image diff --git a/bl2/aarch64/bl2_el3_entrypoint.S b/bl2/aarch64/bl2_el3_entrypoint.S index 4eab39cd3..45bac7da1 100644 --- a/bl2/aarch64/bl2_el3_entrypoint.S +++ b/bl2/aarch64/bl2_el3_entrypoint.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,8 +12,6 @@ #include .globl bl2_entrypoint - .globl bl2_el3_run_image - .globl bl2_run_next_image #if BL2_IN_XIP_MEM #define FIXUP_SIZE 0 @@ -72,36 +70,3 @@ func bl2_entrypoint */ no_ret plat_panic_handler endfunc bl2_entrypoint - -func bl2_run_next_image - mov x20,x0 - /* --------------------------------------------- - * MMU needs to be disabled because both BL2 and BL31 execute - * in EL3, and therefore share the same address space. - * BL31 will initialize the address space according to its - * own requirement. - * --------------------------------------------- - */ - bl disable_mmu_icache_el3 - tlbi alle3 - bl bl2_el3_plat_prepare_exit - -#if ENABLE_PAUTH - /* --------------------------------------------- - * Disable pointer authentication before jumping - * to next boot image. - * --------------------------------------------- - */ - bl pauth_disable_el3 -#endif /* ENABLE_PAUTH */ - - ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET] - msr elr_el3, x0 - msr spsr_el3, x1 - - ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)] - ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)] - ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)] - ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)] - exception_return -endfunc bl2_run_next_image diff --git a/bl2/aarch64/bl2_rme_entrypoint.S b/bl2/aarch64/bl2_rme_entrypoint.S new file mode 100644 index 000000000..076e3267d --- /dev/null +++ b/bl2/aarch64/bl2_rme_entrypoint.S @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + + .globl bl2_entrypoint + + +func bl2_entrypoint + /* Save arguments x0-x3 from previous Boot loader */ + mov x20, x0 + mov x21, x1 + mov x22, x2 + mov x23, x3 + + el3_entrypoint_common \ + _init_sctlr=0 \ + _warm_boot_mailbox=0 \ + _secondary_cold_boot=0 \ + _init_memory=0 \ + _init_c_runtime=1 \ + _exception_vectors=bl2_el3_exceptions \ + _pie_fixup_size=0 + + /* --------------------------------------------- + * Restore parameters of boot rom + * --------------------------------------------- + */ + mov x0, x20 + mov x1, x21 + mov x2, x22 + mov x3, x23 + + /* --------------------------------------------- + * Perform BL2 setup + * --------------------------------------------- + */ + bl bl2_setup + +#if ENABLE_PAUTH + /* --------------------------------------------- + * Program APIAKey_EL1 and enable pointer authentication. + * --------------------------------------------- + */ + bl pauth_init_enable_el3 +#endif /* ENABLE_PAUTH */ + + /* --------------------------------------------- + * Jump to main function. + * --------------------------------------------- + */ + bl bl2_main + + /* --------------------------------------------- + * Should never reach this point. + * --------------------------------------------- + */ + no_ret plat_panic_handler +endfunc bl2_entrypoint diff --git a/bl2/aarch64/bl2_run_next_image.S b/bl2/aarch64/bl2_run_next_image.S new file mode 100644 index 000000000..f0a8be87a --- /dev/null +++ b/bl2/aarch64/bl2_run_next_image.S @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + .globl bl2_run_next_image + + +func bl2_run_next_image + mov x20,x0 + /* --------------------------------------------- + * MMU needs to be disabled because both BL2 and BL31 execute + * in EL3, and therefore share the same address space. + * BL31 will initialize the address space according to its + * own requirement. + * --------------------------------------------- + */ + bl disable_mmu_icache_el3 + tlbi alle3 + bl bl2_el3_plat_prepare_exit + +#if ENABLE_PAUTH + /* --------------------------------------------- + * Disable pointer authentication before jumping + * to next boot image. + * --------------------------------------------- + */ + bl pauth_disable_el3 +#endif /* ENABLE_PAUTH */ + + ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET] + msr elr_el3, x0 + msr spsr_el3, x1 + + ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)] + ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)] + ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)] + ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)] + exception_return +endfunc bl2_run_next_image diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S index 37849c312..d332ec069 100644 --- a/bl2/bl2.ld.S +++ b/bl2/bl2.ld.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,7 +25,11 @@ SECTIONS #if SEPARATE_CODE_AND_RODATA .text . : { __TEXT_START__ = .; +#if ENABLE_RME + *bl2_rme_entrypoint.o(.text*) +#else /* ENABLE_RME */ *bl2_entrypoint.o(.text*) +#endif /* ENABLE_RME */ *(SORT_BY_ALIGNMENT(.text*)) *(.vectors) . = ALIGN(PAGE_SIZE); diff --git a/bl2/bl2.mk b/bl2/bl2.mk index 735e7e04f..54c73f506 100644 --- a/bl2/bl2.mk +++ b/bl2/bl2.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -15,13 +15,24 @@ ifeq (${ARCH},aarch64) BL2_SOURCES += common/aarch64/early_exceptions.S endif -ifeq (${BL2_AT_EL3},0) +ifeq (${ENABLE_RME},1) +# Using RME, run BL2 at EL3 +BL2_SOURCES += bl2/${ARCH}/bl2_rme_entrypoint.S \ + bl2/${ARCH}/bl2_el3_exceptions.S \ + bl2/${ARCH}/bl2_run_next_image.S \ + +BL2_LINKERFILE := bl2/bl2.ld.S + +else ifeq (${BL2_AT_EL3},0) +# Normal operation, no RME, no BL2 at EL3 BL2_SOURCES += bl2/${ARCH}/bl2_entrypoint.S BL2_LINKERFILE := bl2/bl2.ld.S else +# BL2 at EL3, no RME BL2_SOURCES += bl2/${ARCH}/bl2_el3_entrypoint.S \ bl2/${ARCH}/bl2_el3_exceptions.S \ + bl2/${ARCH}/bl2_run_next_image.S \ lib/cpus/${ARCH}/cpu_helpers.S \ lib/cpus/errata_report.c diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c index d2de1350d..197c057e1 100644 --- a/bl2/bl2_main.c +++ b/bl2/bl2_main.c @@ -29,18 +29,18 @@ #define NEXT_IMAGE "BL32" #endif -#if !BL2_AT_EL3 +#if BL2_AT_EL3 /******************************************************************************* - * Setup function for BL2. + * Setup function for BL2 when BL2_AT_EL3=1 ******************************************************************************/ -void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, - u_register_t arg3) +void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, + u_register_t arg3) { /* Perform early platform-specific setup */ - bl2_early_platform_setup2(arg0, arg1, arg2, arg3); + bl2_el3_early_platform_setup(arg0, arg1, arg2, arg3); /* Perform late platform-specific setup */ - bl2_plat_arch_setup(); + bl2_el3_plat_arch_setup(); #if CTX_INCLUDE_PAUTH_REGS /* @@ -50,19 +50,18 @@ void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, assert(is_armv8_3_pauth_present()); #endif /* CTX_INCLUDE_PAUTH_REGS */ } - -#else /* if BL2_AT_EL3 */ +#else /* BL2_AT_EL3 */ /******************************************************************************* - * Setup function for BL2 when BL2_AT_EL3=1. + * Setup function for BL2 when BL2_AT_EL3=0 ******************************************************************************/ -void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, - u_register_t arg3) +void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, + u_register_t arg3) { /* Perform early platform-specific setup */ - bl2_el3_early_platform_setup(arg0, arg1, arg2, arg3); + bl2_early_platform_setup2(arg0, arg1, arg2, arg3); /* Perform late platform-specific setup */ - bl2_el3_plat_arch_setup(); + bl2_plat_arch_setup(); #if CTX_INCLUDE_PAUTH_REGS /* @@ -115,7 +114,7 @@ void bl2_main(void) measured_boot_finish(); #endif /* MEASURED_BOOT */ -#if !BL2_AT_EL3 +#if !BL2_AT_EL3 && !ENABLE_RME #ifndef __aarch64__ /* * For AArch32 state BL1 and BL2 share the MMU setup. @@ -140,7 +139,7 @@ void bl2_main(void) * be passed to next BL image as an argument. */ smc(BL1_SMC_RUN_IMAGE, (unsigned long)next_bl_ep_info, 0, 0, 0, 0, 0, 0); -#else /* if BL2_AT_EL3 */ +#else /* if BL2_AT_EL3 || ENABLE_RME */ NOTICE("BL2: Booting " NEXT_IMAGE "\n"); print_entry_point_info(next_bl_ep_info); console_flush(); @@ -153,5 +152,5 @@ void bl2_main(void) #endif /* ENABLE_PAUTH */ bl2_run_next_image(next_bl_ep_info); -#endif /* BL2_AT_EL3 */ +#endif /* BL2_AT_EL3 && ENABLE_RME */ } -- cgit v1.2.3