]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
feat(gcs): support guarded control stack
authorMark Brown <broonie@kernel.org>
Tue, 14 Mar 2023 21:33:04 +0000 (21:33 +0000)
committerMark Brown <broonie@kernel.org>
Tue, 18 Apr 2023 11:36:52 +0000 (12:36 +0100)
Arm v9.4 introduces support for Guarded Control Stack, providing
mitigations against some forms of RPO attacks and an efficient mechanism
for obtaining the current call stack without requiring a full stack
unwind. Enable access to this feature for EL2 and below, context
switching the newly added EL2 registers as appropriate.

Change the FVP platform to default to handling this as a dynamic option
so the right decision can be made by the code at runtime.

Signed-off-by: Mark Brown <broonie@kernel.org>
Change-Id: I691aa7c22e3547bb3abe98d96993baf18c5f0e7b

Makefile
changelog.yaml
common/feat_detect.c
docs/getting_started/build-options.rst
include/arch/aarch64/arch.h
include/arch/aarch64/arch_features.h
include/arch/aarch64/arch_helpers.h
include/lib/el3_runtime/aarch64/context.h
lib/el3_runtime/aarch64/context_mgmt.c
make_helpers/defaults.mk
plat/arm/board/fvp/platform.mk

index 98e448faba8f954812b12641153a403de13be5a5..5306ddfe5e4df5bc7cd3d21eca4f126a2d3ca80b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1189,6 +1189,7 @@ $(eval $(call assert_numerics,\
         ENABLE_FEAT_S1PIE \
         ENABLE_FEAT_S2POE \
         ENABLE_FEAT_S1POE \
+        ENABLE_FEAT_GCS \
         ENABLE_FEAT_VHE \
         ENABLE_MPAM_FOR_LOWER_ELS \
         ENABLE_RME \
@@ -1329,6 +1330,7 @@ $(eval $(call add_defines,\
         ENABLE_FEAT_S1PIE \
         ENABLE_FEAT_S2POE \
         ENABLE_FEAT_S1POE \
+        ENABLE_FEAT_GCS \
         FEATURE_DETECTION \
         TWED_DELAY \
         ENABLE_FEAT_TWED \
index a514abd80020746abc537e843197aab957151dcf..2f51ce031a7b085bee544b73287a83a2214fbdb0 100644 (file)
@@ -104,6 +104,9 @@ subsections:
       - title: CPU feature / ID register handling in general
         scope: cpufeat
 
+      - title: Guarded Control Stack (FEAT_GCS)
+        scope: gcs
+
       - title: Support for the `HCRX_EL2` register (FEAT_HCX)
         scope: hcx
 
index 1582b9dcbcd7cd58ab23177d2ce4253acf9d2eb9..98b420a33da8d66b32076c442ad43a79270b5b7d 100644 (file)
@@ -228,6 +228,10 @@ void detect_arch_features(void)
        /* v9.2 features */
        check_feature(ENABLE_SME_FOR_NS, read_feat_sme_id_field(),
                      "SME", 1, 2);
+
+       /* v9.4 features */
+       check_feature(ENABLE_FEAT_GCS, read_feat_gcs_id_field(), "GCS", 1, 1);
+
        read_feat_rme();
 
        if (tainted) {
index 03be7862e32daf7286e4ccc96f97a86a86374616..d2f463fab88f336fbe0c454cb9db7a5be6a86aaa 100644 (file)
@@ -374,6 +374,12 @@ Common build options
    can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
    mechanism. Default value is ``0``.
 
+-  ``ENABLE_FEAT_GCS``: Numeric value to set the bit SCR_EL3.GCSEn in EL3 to
+   allow use of Guarded Control Stack from EL2 as well as adding the GCS
+   registers to the EL2 context save/restore operations. This flag can take
+   the values 0 to 2, to align  with the ``FEATURE_DETECTION`` mechanism.
+   Default value is ``0``.
+
 -  ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
    support in GCC for TF-A. This option is currently only supported for
    AArch64. Default is 0.
index 89f4b40bd1f817a9f4b0222b118d1914b8beb075..9e061bfb40adc2baf2f75877882abcda6ae97947 100644 (file)
 #define ID_AA64MMFR3_EL1_TCRX_MASK             ULL(0xf)
 
 /* ID_AA64PFR1_EL1 definitions */
+#define ID_AA64PFR1_EL1_GCS_SHIFT      U(44)
+#define ID_AA64PFR1_EL1_GCS_MASK       ULL(0xf)
+
 #define ID_AA64PFR1_EL1_SSBS_SHIFT     U(4)
 #define ID_AA64PFR1_EL1_SSBS_MASK      ULL(0xf)
 
 #define SCR_PIEN_BIT           (UL(1) << 45)
 #define SCR_TCR2EN_BIT         (UL(1) << 43)
 #define SCR_TRNDR_BIT          (UL(1) << 40)
+#define SCR_GCSEn_BIT          (UL(1) << 39)
 #define SCR_HXEn_BIT           (UL(1) << 38)
 #define SCR_ENTP2_SHIFT                U(41)
 #define SCR_ENTP2_BIT          (UL(1) << SCR_ENTP2_SHIFT)
 #define POR_EL2                        S3_4_C10_C2_4
 #define S2PIR_EL2              S3_4_C10_C2_5
 
+/*******************************************************************************
+ * FEAT_GCS - Guarded Control Stack Registers
+ ******************************************************************************/
+#define GCSCR_EL2              S3_4_C2_C5_0
+#define GCSPR_EL2              S3_4_C2_C5_1
+
 /*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
  ******************************************************************************/
index 840b117a0955da6c02e6035e8f8c4d81c6180426..16f4fb996e89c40975edfb1d7a8336ca9059565f 100644 (file)
@@ -316,6 +316,24 @@ static inline bool is_feat_sxpie_supported(void)
        return is_feat_s1pie_supported() || is_feat_s2pie_supported();
 }
 
+static unsigned int read_feat_gcs_id_field(void)
+{
+       return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_GCS);
+}
+
+static inline bool is_feat_gcs_supported(void)
+{
+       if (ENABLE_FEAT_GCS == FEAT_STATE_DISABLED) {
+               return false;
+       }
+
+       if (ENABLE_FEAT_GCS == FEAT_STATE_ALWAYS) {
+               return true;
+       }
+
+       return read_feat_gcs_id_field() != 0U;
+}
+
 /*******************************************************************************
  * Functions to identify the presence of the Activity Monitors Extension
  ******************************************************************************/
index f877f5bc8c90b4f2e532f6343d7eee2bfa9e41a0..1b4bc1113071d109620c7ccacc59686c0c34ad3e 100644 (file)
@@ -613,6 +613,10 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(s2pir_el2, S2PIR_EL2)
 /* FEAT_SxPOE Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(por_el2, POR_EL2)
 
+/* FEAT_GCS Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcscr_el2, GCSCR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el2, GCSPR_EL2)
+
 /* DynamIQ Shared Unit power management */
 DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
 
index a8e6d8ad22d623fda6ce5af2f9a729d0a4eb3d1e..dd2b83681a2db6b18de73d32f6dd93365f852a84 100644 (file)
 #define CTX_PIRE0_EL2           U(0x1e8)
 #define CTX_PIR_EL2             U(0x1f0)
 #define CTX_S2PIR_EL2          U(0x1f8)
+#define CTX_GCSCR_EL2           U(0x200)
+#define CTX_GCSPR_EL2           U(0x208)
 
 /* Align to the next 16 byte boundary */
-#define CTX_EL2_SYSREGS_END    U(0x200)
+#define CTX_EL2_SYSREGS_END    U(0x210)
 
 #endif /* CTX_INCLUDE_EL2_REGS */
 
index c411b73abbda31a543d4e8ac53b519f860fb3fa0..e38b34dcd12ae8a566c619b9006f7f8ca3f050be 100644 (file)
@@ -375,6 +375,13 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e
                scr_el3 |= SCR_PIEN_BIT;
        }
 
+       /*
+        * SCR_EL3.GCSEn: Enable GCS registers for AArch64 if present.
+        */
+       if ((is_feat_gcs_supported()) && (GET_RW(ep->spsr) == MODE_RW_64)) {
+               scr_el3 |= SCR_GCSEn_BIT;
+       }
+
        /*
         * CPTR_EL3 was initialized out of reset, copy that value to the
         * context register.
@@ -1039,6 +1046,10 @@ void cm_el2_sysregs_context_save(uint32_t security_state)
                if (is_feat_sxpoe_supported()) {
                        write_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2, read_por_el2());
                }
+               if (is_feat_gcs_supported()) {
+                       write_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2, read_gcspr_el2());
+                       write_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2, read_gcscr_el2());
+               }
        }
 }
 
@@ -1116,6 +1127,10 @@ void cm_el2_sysregs_context_restore(uint32_t security_state)
                if (is_feat_sxpoe_supported()) {
                        write_por_el2(read_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2));
                }
+               if (is_feat_gcs_supported()) {
+                       write_gcscr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2));
+                       write_gcspr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2));
+               }
        }
 }
 #endif /* CTX_INCLUDE_EL2_REGS */
index 808a058b2e646fad0c1b20efb4a4e8dd7bb794aa..34a9bc6b9f12e36ac9e887157e2cb81142947b14 100644 (file)
@@ -188,6 +188,9 @@ ENABLE_FEAT_S2POE           := 0
 # Flag to enable access to Stage 1 Permission Overlay (FEAT_S1POE)
 ENABLE_FEAT_S1POE              := 0
 
+# Flag to enable access to Guarded Control Stack (FEAT_GCS)
+ENABLE_FEAT_GCS                        := 0
+
 # By default BL31 encryption disabled
 ENCRYPT_BL31                   := 0
 
index 3fb323bd40254bb9be54c842bec52af4e69fe2ba..e81f1eb6580c9d3e3c2d5ccbe68d06dd15c20b6c 100644 (file)
@@ -49,6 +49,7 @@ ifneq (${SPD}, tspd)
        ENABLE_MPAM_FOR_LOWER_ELS       := 2
        ENABLE_FEAT_RNG                 := 2
        ENABLE_FEAT_TWED                := 2
+       ENABLE_FEAT_GCS                 := 2
 ifeq (${ARCH},aarch64)
 ifeq (${SPM_MM}, 0)
 ifeq (${ENABLE_RME}, 0)