diff options
author | Boyan Karatotev <boyan.karatotev@arm.com> | 2023-05-23 12:04:00 +0100 |
---|---|---|
committer | Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com> | 2023-10-05 17:44:49 +0100 |
commit | 5e8cc7278659820bcd64c243cbd89c131462314c (patch) | |
tree | 9f308e387d6b837ed9395ac27821f655a8fd6ae7 | |
parent | f0c96a2e35cc1f154e00a842ddab2958fc903a71 (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.c | 27 |
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. |