feat(el3-spmc): support simd context management upon world switch
This patch performs necessary simd context management operations for
context switch from NWd to SWD and vice versa.
Change-Id: Ife01fffc4e2a7f3deb9b6273424161c225fdbbfb
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
diff --git a/Makefile b/Makefile
index f7737e3..64bccbc 100644
--- a/Makefile
+++ b/Makefile
@@ -457,6 +457,9 @@
ifeq ($(SPMC_AT_EL3),1)
$(error SPM cannot be enabled in both S-EL2 and EL3.)
endif
+ ifeq ($(CTX_INCLUDE_SVE_REGS),1)
+ $(error SVE context management not needed with Hafnium SPMC.)
+ endif
endif
ifeq ($(findstring optee_sp,$(ARM_SPMC_MANIFEST_DTS)),optee_sp)
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index e3d7fbd..0a246f3 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -215,6 +215,14 @@
cm_el2_sysregs_context_save(NON_SECURE);
#else
cm_el1_sysregs_context_save(NON_SECURE);
+
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+ /*
+ * The hint bit denoting absence of SVE live state is effectively false
+ * in this scenario where execution was trapped to EL3 due to FIQ.
+ */
+ simd_ctx_save(NON_SECURE, false);
+#endif
#endif
/* Convey the event to the SPMC through the FFA_INTERRUPT interface. */
@@ -230,7 +238,14 @@
/* Mark current core as handling a secure interrupt. */
ctx->secure_interrupt_ongoing = true;
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+ simd_ctx_restore(SECURE);
+#endif
rc = spmd_spm_core_sync_entry(ctx);
+
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+ simd_ctx_save(SECURE, false);
+#endif
if (rc != 0ULL) {
ERROR("%s failed (%" PRId64 ") on CPU%u\n", __func__, rc, plat_my_core_pos());
}
@@ -241,6 +256,10 @@
cm_el2_sysregs_context_restore(NON_SECURE);
#else
cm_el1_sysregs_context_restore(NON_SECURE);
+
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+ simd_ctx_restore(NON_SECURE);
+#endif
#endif
cm_set_next_eret_context(NON_SECURE);
@@ -678,6 +697,10 @@
cm_el2_sysregs_context_save(secure_state_in);
#else
cm_el1_sysregs_context_save(secure_state_in);
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+ /* Forward the hint bit denoting the absence of SVE live state. */
+ simd_ctx_save(secure_state_in, (!secure_origin && (is_sve_hint_set(flags) == true)));
+#endif
#endif
/* Restore outgoing security state */
@@ -685,6 +708,9 @@
cm_el2_sysregs_context_restore(secure_state_out);
#else
cm_el1_sysregs_context_restore(secure_state_out);
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+ simd_ctx_restore(secure_state_out);
+#endif
#endif
cm_set_next_eret_context(secure_state_out);