Merge "refactor(cm): reset the cptr_el3 before perworld context setup" into integration
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 47d91de..235b2cf 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -341,9 +341,9 @@
/*******************************************************************************
* Registers initialised in a per-world context.
******************************************************************************/
-#define CTX_CPTR_EL3 U(0x0)
-#define CTX_ZCR_EL3 U(0x8)
-#define CTX_GLOBAL_EL3STATE_END U(0x10)
+#define CTX_CPTR_EL3 U(0x0)
+#define CTX_ZCR_EL3 U(0x8)
+#define CTX_PERWORLD_EL3STATE_END U(0x10)
#ifndef __ASSEMBLER__
diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h
index b2bdaf5..f631125 100644
--- a/include/lib/el3_runtime/context_mgmt.h
+++ b/include/lib/el3_runtime/context_mgmt.h
@@ -40,7 +40,9 @@
#if IMAGE_BL31
void cm_manage_extensions_el3(void);
void manage_extensions_nonsecure_per_world(void);
+void cm_el3_arch_init_per_world(per_world_context_t *per_world_ctx);
#endif
+
#if CTX_INCLUDE_EL2_REGS
void cm_el2_sysregs_context_save(uint32_t security_state);
void cm_el2_sysregs_context_restore(uint32_t security_state);
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 631094f..18bdca8 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -581,7 +581,7 @@
.macro get_per_world_context _reg:req
ldr x10, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
get_security_state x9, x10
- mov_imm x10, (CTX_GLOBAL_EL3STATE_END - CTX_CPTR_EL3)
+ mov_imm x10, (CTX_PERWORLD_EL3STATE_END - CTX_CPTR_EL3)
mul x9, x9, x10
adrp x10, per_world_context
add x10, x10, :lo12:per_world_context
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index fdd1388..a0212c6 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -600,6 +600,28 @@
}
#endif /* IMAGE_BL31 */
+/******************************************************************************
+ * Function to initialise the registers with the RESET values in the context
+ * memory, which are maintained per world.
+ ******************************************************************************/
+#if IMAGE_BL31
+void cm_el3_arch_init_per_world(per_world_context_t *per_world_ctx)
+{
+ /*
+ * Initialise CPTR_EL3, setting all fields rather than relying on hw.
+ *
+ * CPTR_EL3.TFP: Set to zero so that accesses to the V- or Z- registers
+ * by Advanced SIMD, floating-point or SVE instructions (if
+ * implemented) do not trap to EL3.
+ *
+ * CPTR_EL3.TCPAC: Set to zero so that accesses to CPACR_EL1,
+ * CPTR_EL2,CPACR, or HCPTR do not trap to EL3.
+ */
+ uint64_t cptr_el3 = CPTR_EL3_RESET_VAL & ~(TCPAC_BIT | TFP_BIT);
+ per_world_ctx->ctx_cptr_el3 = cptr_el3;
+}
+#endif /* IMAGE_BL31 */
+
/*******************************************************************************
* Initialise per_world_context for Non-Secure world.
* This function enables the architecture extensions, which have same value
@@ -608,6 +630,8 @@
#if IMAGE_BL31
void manage_extensions_nonsecure_per_world(void)
{
+ cm_el3_arch_init_per_world(&per_world_context[CPU_CONTEXT_NS]);
+
if (is_feat_sme_supported()) {
sme_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
}
@@ -631,10 +655,11 @@
* This function enables the architecture extensions, which have same value
* across the cores for the secure world.
******************************************************************************/
-
static void manage_extensions_secure_per_world(void)
{
#if IMAGE_BL31
+ cm_el3_arch_init_per_world(&per_world_context[CPU_CONTEXT_SECURE]);
+
if (is_feat_sme_supported()) {
if (ENABLE_SME_FOR_SWD) {
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 8b78b13..4ea074f 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -134,6 +134,8 @@
static void manage_extensions_realm_per_world(void)
{
+ cm_el3_arch_init_per_world(&per_world_context[CPU_CONTEXT_REALM]);
+
if (is_feat_sve_supported()) {
/*
* Enable SVE and FPU in realm context when it is enabled for NS.