feat(el3-spmc): use spmd_smc_switch_state after secure interrupt

Switch the state back to non-secure after a secure interrupt
using spmd_smc_switch_state with FFA_NORMAL_WORLD_RESUME
to reduce the number of control flow paths for world switches.
Fixes an issue where FP registers were not correctly restored
after secure interrupts.

Upstreamed from https://r.android.com/3345999, tested on Trusty.

Change-Id: I3ce33f7657c13b999969ebb8957d5d4b6c3aa634
Signed-off-by: Andrei Homescu <ahomescu@google.com>
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
index c6ec30c..51fba58 100644
--- a/services/std_svc/spm/el3_spmc/spmc_main.c
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -610,19 +610,14 @@
 
 	/* Resume normal world if a secure interrupt was handled. */
 	if (sp->ec[idx].rt_model == RT_MODEL_INTR) {
-		/* FFA_MSG_WAIT can only be called from the secure world. */
-		unsigned int secure_state_in = SECURE;
-		unsigned int secure_state_out = NON_SECURE;
-
-		cm_el1_sysregs_context_save(secure_state_in);
-		cm_el1_sysregs_context_restore(secure_state_out);
-		cm_set_next_eret_context(secure_state_out);
-
 		if (sp->runtime_el == S_EL0) {
 			spin_unlock(&sp->rt_state_lock);
 		}
 
-		SMC_RET0(cm_get_context(secure_state_out));
+		return spmd_smc_switch_state(FFA_NORMAL_WORLD_RESUME, secure_origin,
+					     FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+					     FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+					     handle, flags);
 	}
 
 	/* Protect the runtime state of a S-EL0 SP with a lock. */
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 3953b24..4d82991 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -715,6 +715,10 @@
 	cm_set_next_eret_context(secure_state_out);
 
 	ctx_out = cm_get_context(secure_state_out);
+	if (smc_fid == FFA_NORMAL_WORLD_RESUME) {
+		SMC_RET0(ctx_out);
+	}
+
 #if SPMD_SPM_AT_SEL2
 	/*
 	 * If SPMC is at SEL2, save additional registers x8-x17, which may