summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--changelog.yaml3
-rw-r--r--common/feat_detect.c4
-rw-r--r--docs/getting_started/build-options.rst6
-rw-r--r--include/arch/aarch64/arch.h10
-rw-r--r--include/arch/aarch64/arch_features.h18
-rw-r--r--include/arch/aarch64/arch_helpers.h4
-rw-r--r--include/lib/el3_runtime/aarch64/context.h4
-rw-r--r--lib/el3_runtime/aarch64/context_mgmt.c15
-rw-r--r--make_helpers/defaults.mk3
-rw-r--r--plat/arm/board/fvp/platform.mk1
11 files changed, 69 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 98e448fab..5306ddfe5 100644
--- 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 \
diff --git a/changelog.yaml b/changelog.yaml
index a514abd80..2f51ce031 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -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
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 1582b9dcb..98b420a33 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -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) {
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 03be7862e..d2f463fab 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -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.
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 89f4b40bd..9e061bfb4 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -371,6 +371,9 @@
#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)
@@ -527,6 +530,7 @@
#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)
@@ -1351,6 +1355,12 @@
#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
******************************************************************************/
#define CLUSTERPWRDN_EL1 S3_0_c15_c3_6
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 840b117a0..16f4fb996 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -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
******************************************************************************/
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index f877f5bc8..1b4bc1113 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -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)
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index a8e6d8ad2..dd2b83681 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -234,9 +234,11 @@
#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 */
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index c411b73ab..e38b34dcd 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -376,6 +376,13 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e
}
/*
+ * 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 */
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 808a058b2..34a9bc6b9 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -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
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 3fb323bd4..e81f1eb65 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -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)