From: Justin Chadwell Date: Thu, 18 Jul 2019 13:25:33 +0000 (+0100) Subject: Enable MTE support in both secure and non-secure worlds X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=9dd94382bd23db0fa201b254dc3f1bebdfd627c2;p=project%2Fbcm63xx%2Fatf.git Enable MTE support in both secure and non-secure worlds This patch adds support for the new Memory Tagging Extension arriving in ARMv8.5. MTE support is now enabled by default on systems that support at EL0. To enable it at ELx for both the non-secure and the secure world, the compiler flag CTX_INCLUDE_MTE_REGS includes register saving and restoring when necessary in order to prevent register leakage between the worlds. Change-Id: I2d4ea993d6b11654ea0d4757d00ca20d23acf36c Signed-off-by: Justin Chadwell --- diff --git a/Makefile b/Makefile index 43ff8d2f..71a52b56 100644 --- a/Makefile +++ b/Makefile @@ -510,6 +510,14 @@ ifeq ($(ENABLE_BTI),1) $(info Branch Protection is an experimental feature) endif +ifeq ($(CTX_INCLUDE_MTE_REGS),1) + ifneq (${ARCH},aarch64) + $(error CTX_INCLUDE_MTE_REGS requires AArch64) + else + $(info CTX_INCLUDE_MTE_REGS is an experimental feature) + endif +endif + ################################################################################ # Process platform overrideable behaviour ################################################################################ @@ -631,6 +639,7 @@ $(eval $(call assert_boolean,CREATE_KEYS)) $(eval $(call assert_boolean,CTX_INCLUDE_AARCH32_REGS)) $(eval $(call assert_boolean,CTX_INCLUDE_FPREGS)) $(eval $(call assert_boolean,CTX_INCLUDE_PAUTH_REGS)) +$(eval $(call assert_boolean,CTX_INCLUDE_MTE_REGS)) $(eval $(call assert_boolean,DEBUG)) $(eval $(call assert_boolean,DYN_DISABLE_AUTH)) $(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING)) @@ -686,6 +695,7 @@ $(eval $(call add_define,CTX_INCLUDE_AARCH32_REGS)) $(eval $(call add_define,CTX_INCLUDE_FPREGS)) $(eval $(call add_define,CTX_INCLUDE_PAUTH_REGS)) $(eval $(call add_define,EL3_EXCEPTION_HANDLING)) +$(eval $(call add_define,CTX_INCLUDE_MTE_REGS)) $(eval $(call add_define,ENABLE_AMU)) $(eval $(call add_define,ENABLE_ASSERTIONS)) $(eval $(call add_define,ENABLE_BTI)) diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c index 30bf6ffc..0a817351 100644 --- a/bl32/tsp/tsp_main.c +++ b/bl32/tsp/tsp_main.c @@ -386,6 +386,14 @@ tsp_args_t *tsp_smc_handler(uint64_t func, */ tsp_get_magic(service_args); +#if CTX_INCLUDE_MTE_REGS + /* + * Write a dummy value to an MTE register, to simulate usage in the + * secure world + */ + write_gcr_el1(0x99); +#endif + /* Determine the function to perform based on the function ID */ switch (TSP_BARE_FID(func)) { case TSP_ADD: diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 5f84eced..dc6a8034 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -898,4 +898,12 @@ ******************************************************************************/ #define SSBS S3_3_C4_C2_6 +/******************************************************************************* + * Armv8.5 - Memory Tagging Extension Registers + ******************************************************************************/ +#define TFSRE0_EL1 S3_0_C5_C6_1 +#define TFSR_EL1 S3_0_C5_C6_0 +#define RGSR_EL1 S3_0_C1_C0_5 +#define GCR_EL1 S3_0_C1_C0_6 + #endif /* ARCH_H */ diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index c1737064..c60f2e8f 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -501,6 +501,12 @@ DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(apiakeyhi_el1, APIAKeyHi_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(apiakeylo_el1, APIAKeyLo_EL1) +/* Armv8.5 MTE Registers */ +DEFINE_RENAME_SYSREG_RW_FUNCS(tfsre0_el1, TFSRE0_EL1) +DEFINE_RENAME_SYSREG_RW_FUNCS(tfsr_el1, TFSR_EL1) +DEFINE_RENAME_SYSREG_RW_FUNCS(rgsr_el1, RGSR_EL1) +DEFINE_RENAME_SYSREG_RW_FUNCS(gcr_el1, GCR_EL1) + #define IS_IN_EL(x) \ (GET_EL(read_CurrentEl()) == MODE_EL##x) diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index 64fa8a9e..e90a6e7d 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -123,10 +123,22 @@ #define CTX_TIMER_SYSREGS_END CTX_AARCH32_END #endif /* NS_TIMER_SWITCH */ +#if CTX_INCLUDE_MTE_REGS +#define CTX_TFSRE0_EL1 (CTX_TIMER_SYSREGS_END + U(0x0)) +#define CTX_TFSR_EL1 (CTX_TIMER_SYSREGS_END + U(0x8)) +#define CTX_RGSR_EL1 (CTX_TIMER_SYSREGS_END + U(0x10)) +#define CTX_GCR_EL1 (CTX_TIMER_SYSREGS_END + U(0x18)) + +/* Align to the next 16 byte boundary */ +#define CTX_MTE_REGS_END (CTX_TIMER_SYSREGS_END + U(0x20)) +#else +#define CTX_MTE_REGS_END CTX_TIMER_SYSREGS_END +#endif /* CTX_INCLUDE_MTE_REGS */ + /* * End of system registers. */ -#define CTX_SYSREGS_END CTX_TIMER_SYSREGS_END +#define CTX_SYSREGS_END CTX_MTE_REGS_END /******************************************************************************* * Constants that allow assembler code to access members of and the 'fp_regs' diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 53dc02e6..37bb12c8 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -145,6 +145,17 @@ func el1_sysregs_context_save str x14, [x0, #CTX_CNTKCTL_EL1] #endif + /* Save MTE system registers if the build has instructed so */ +#if CTX_INCLUDE_MTE_REGS + mrs x15, TFSRE0_EL1 + mrs x16, TFSR_EL1 + stp x15, x16, [x0, #CTX_TFSRE0_EL1] + + mrs x9, RGSR_EL1 + mrs x10, GCR_EL1 + stp x9, x10, [x0, #CTX_RGSR_EL1] +#endif + ret endfunc el1_sysregs_context_save @@ -229,6 +240,16 @@ func el1_sysregs_context_restore ldr x14, [x0, #CTX_CNTKCTL_EL1] msr cntkctl_el1, x14 #endif + /* Restore MTE system registers if the build has instructed so */ +#if CTX_INCLUDE_MTE_REGS + ldp x11, x12, [x0, #CTX_TFSRE0_EL1] + msr TFSRE0_EL1, x11 + msr TFSR_EL1, x12 + + ldp x13, x14, [x0, #CTX_RGSR_EL1] + msr RGSR_EL1, x13 + msr GCR_EL1, x14 +#endif /* No explict ISB required here as ERET covers it */ ret diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index bd5b3aa6..446d9da9 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -137,17 +137,30 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) scr_el3 |= SCR_API_BIT | SCR_APK_BIT; #endif /* !CTX_INCLUDE_PAUTH_REGS */ - unsigned int mte = get_armv8_5_mte_support(); - /* - * Enable MTE support unilaterally for normal world if the CPU supports - * it. + * Enable MTE support. Support is enabled unilaterally for the normal + * world, and only for the secure world when CTX_INCLUDE_MTE_REGS is + * set. */ - if (mte != MTE_UNIMPLEMENTED) { - if (security_state == NON_SECURE) { - scr_el3 |= SCR_ATA_BIT; - } + unsigned int mte = get_armv8_5_mte_support(); +#if CTX_INCLUDE_MTE_REGS + assert(mte == MTE_IMPLEMENTED_ELX); + scr_el3 |= SCR_ATA_BIT; +#else + if (mte == MTE_IMPLEMENTED_EL0) { + /* + * Can enable MTE across both worlds as no MTE registers are + * used + */ + scr_el3 |= SCR_ATA_BIT; + } else if (mte == MTE_IMPLEMENTED_ELX && security_state == NON_SECURE) { + /* + * Can only enable MTE in Non-Secure world without register + * saving + */ + scr_el3 |= SCR_ATA_BIT; } +#endif #ifdef IMAGE_BL31 /* diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index f63e46f3..66c2af4c 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -214,6 +214,11 @@ ifeq (${ARCH},aarch32) override ENABLE_SPE_FOR_LOWER_ELS := 0 endif +# Include Memory Tagging Extension registers in cpu context. This must be set +# to 1 if the platform wants to use this feature in the Secure world and MTE is +# enabled at ELX. +CTX_INCLUDE_MTE_REGS := 0 + ENABLE_AMU := 0 # By default, enable Scalable Vector Extension if implemented for Non-secure