summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoyan Karatotev <boyan.karatotev@arm.com>2023-05-23 12:04:00 +0100
committerJayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>2023-10-05 17:44:49 +0100
commit5e8cc7278659820bcd64c243cbd89c131462314c (patch)
tree9f308e387d6b837ed9395ac27821f655a8fd6ae7
parentf0c96a2e35cc1f154e00a842ddab2958fc903a71 (diff)
fix(cm): make ICC_SRE_EL2 fixup generic to all worlds
For ICC_SRE_EL2.SRE the Arm ARM specifies that "If software changes this bit from 1 to 0, the results are UNPREDICTABLE". However, the indiscriminate zeroing of the EL2 context does just that for Secure and Realm worlds. Make this fixup generic to avoid the problem. Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com> Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com> Change-Id: Iee21ace17faf10eae52a046e6dfafc5141fa7f85
-rw-r--r--lib/el3_runtime/aarch64/context_mgmt.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 8b688fdeb..3507de8ac 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -270,15 +270,6 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *
write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_SCTLR_EL2,
sctlr_el2);
- /*
- * Program the ICC_SRE_EL2 to make sure the correct bits are set
- * when restoring NS context.
- */
- u_register_t icc_sre_el2 = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT |
- ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT;
- write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_ICC_SRE_EL2,
- icc_sre_el2);
-
if (is_feat_hcx_supported()) {
/*
* Initialize register HCRX_EL2 with its init value.
@@ -331,6 +322,24 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e
zeromem(ctx, sizeof(*ctx));
/*
+ * The lower-EL context is zeroed so that no stale values leak to a world.
+ * It is assumed that an all-zero lower-EL context is good enough for it
+ * to boot correctly. However, there are very few registers where this
+ * is not true and some values need to be recreated.
+ */
+#if CTX_INCLUDE_EL2_REGS
+ el2_sysregs_t *el2_ctx = get_el2_sysregs_ctx(ctx);
+
+ /*
+ * These bits are set in the gicv3 driver. Losing them (especially the
+ * SRE bit) is problematic for all worlds. Henceforth recreate them.
+ */
+ u_register_t icc_sre_el2 = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT |
+ ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT;
+ write_ctx_reg(el2_ctx, CTX_ICC_SRE_EL2, icc_sre_el2);
+#endif /* CTX_INCLUDE_EL2_REGS */
+
+ /*
* SCR_EL3 was initialised during reset sequence in macro
* el3_arch_init_common. This code modifies the SCR_EL3 fields that
* affect the next EL.