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.