feat(spmd): pass SMCCCv1.3 SVE hint to lower EL

A normal world caller can emit an SMC with the SVE hint bit set such
that the callee can perform an optimization by omitting to save/restore
the SVE context. Update the SPMD to pass this information to the SPMC
when set by the caller in the SMC flags parameter.
For now, restrict this behavior to the SPMC living at S-EL2.

Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Change-Id: Icf46eb8a391dd3ddd2ee6aff8581a2f1c8a1c274
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 5d19868..49d7058 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -667,11 +667,22 @@
 			       uint64_t x2,
 			       uint64_t x3,
 			       uint64_t x4,
-			       void *handle)
+			       void *handle,
+			       uint64_t flags)
 {
 	unsigned int secure_state_in = (secure_origin) ? SECURE : NON_SECURE;
 	unsigned int secure_state_out = (!secure_origin) ? SECURE : NON_SECURE;
 
+#if SPMD_SPM_AT_SEL2
+	if ((secure_state_out == SECURE) && (is_sve_hint_set(flags) == true)) {
+		/*
+		 * Set the SVE hint bit in x0 and pass to the lower secure EL,
+		 * if it was set by the caller.
+		 */
+		smc_fid |= (FUNCID_SVE_HINT_MASK << FUNCID_SVE_HINT_SHIFT);
+	}
+#endif
+
 	/* Save incoming security state */
 #if SPMD_SPM_AT_SEL2
 	if (secure_state_in == NON_SECURE) {
@@ -746,8 +757,9 @@
 		return spmc_smc_handler(smc_fid, secure_origin, x1, x2, x3, x4,
 					cookie, handle, flags);
 	}
+
 	return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2, x3, x4,
-				     handle);
+				     handle, flags);
 
 }