Enable MTE support in both secure and non-secure worlds
authorJustin Chadwell <justin.chadwell@arm.com>
Thu, 18 Jul 2019 13:25:33 +0000 (14:25 +0100)
committerJustin Chadwell <justin.chadwell@arm.com>
Mon, 9 Sep 2019 15:23:33 +0000 (16:23 +0100)
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 <justin.chadwell@arm.com>
Makefile
bl32/tsp/tsp_main.c
include/arch/aarch64/arch.h
include/arch/aarch64/arch_helpers.h
include/lib/el3_runtime/aarch64/context.h
lib/el3_runtime/aarch64/context.S
lib/el3_runtime/aarch64/context_mgmt.c
make_helpers/defaults.mk

index 43ff8d2ffd0a5124170a35931bc882d0dc046f77..71a52b56a3cf06512914e60fd5f8ee37e59933ea 100644 (file)
--- 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))
index 30bf6ffc8da66e7fca6d181fb9eb2fd4dd295944..0a817351c1fa3682ad94129fb3fbe3b68c40bf83 100644 (file)
@@ -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:
index 5f84ecede52ecf48722455f3c0d7c5137ff15722..dc6a803403d56386c97f7bc9c30e4bc3646b5ca1 100644 (file)
  ******************************************************************************/
 #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 */
index c17370647d35773fbee7f880cacc1ca1e79e0dee..c60f2e8f7f2b35ab3db5e32077f6772a5f35896c 100644 (file)
@@ -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)
 
index 64fa8a9ea4dbc41ec96f09c9277fe0e7e44e5950..e90a6e7d2e674ffa90e1448ed92fa39176077a73 100644 (file)
 #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'
index 53dc02e64e2ad269e13d1e85dfede308f1ff70bd..37bb12c80420c2ba7d43734a8ef3bdc7adcc9bfe 100644 (file)
@@ -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
index bd5b3aa6c5de8de0045b1ff385aa8508809b5f0c..446d9da92597cd7a2b6b6b2f46434ddc0290a826 100644 (file)
@@ -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
        /*
index f63e46f39f1f3f31832c7e08873dfb869d59147f..66c2af4c3e0ab61620683baf8d07decd9bf372c6 100644 (file)
@@ -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