Merge "fix(rmmd): preserve x4-x7 as per SMCCCv1.1" into integration
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 7f85b63..e9004c7 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -48,10 +48,6 @@
* Static function declaration.
******************************************************************************/
static int32_t rmm_init(void);
-static uint64_t rmmd_smc_forward(uint32_t smc_fid, uint32_t src_sec_state,
- uint32_t dst_sec_state, uint64_t x1,
- uint64_t x2, uint64_t x3, uint64_t x4,
- void *handle);
/*******************************************************************************
* This function takes an RMM context pointer and performs a synchronous entry
@@ -191,10 +187,10 @@
/*******************************************************************************
* Forward SMC to the other security state
******************************************************************************/
-static uint64_t rmmd_smc_forward(uint32_t smc_fid, uint32_t src_sec_state,
- uint32_t dst_sec_state, uint64_t x1,
- uint64_t x2, uint64_t x3, uint64_t x4,
- void *handle)
+static uint64_t rmmd_smc_forward(uint32_t src_sec_state,
+ uint32_t dst_sec_state, uint64_t x0,
+ uint64_t x1, uint64_t x2, uint64_t x3,
+ uint64_t x4, void *handle)
{
/* Save incoming security state */
cm_el1_sysregs_context_save(src_sec_state);
@@ -205,10 +201,20 @@
cm_el2_sysregs_context_restore(dst_sec_state);
cm_set_next_eret_context(dst_sec_state);
- SMC_RET8(cm_get_context(dst_sec_state), smc_fid, x1, x2, x3, x4,
- SMC_GET_GP(handle, CTX_GPREG_X5),
- SMC_GET_GP(handle, CTX_GPREG_X6),
- SMC_GET_GP(handle, CTX_GPREG_X7));
+ /*
+ * As per SMCCCv1.1, we need to preserve x4 to x7 unless
+ * being used as return args. Hence we differentiate the
+ * onward and backward path. Support upto 8 args in the
+ * onward path and 4 args in return path.
+ */
+ if (src_sec_state == NON_SECURE) {
+ SMC_RET8(cm_get_context(dst_sec_state), x0, x1, x2, x3, x4,
+ SMC_GET_GP(handle, CTX_GPREG_X5),
+ SMC_GET_GP(handle, CTX_GPREG_X6),
+ SMC_GET_GP(handle, CTX_GPREG_X7));
+ } else {
+ SMC_RET4(cm_get_context(dst_sec_state), x0, x1, x2, x3);
+ }
}
/*******************************************************************************
@@ -237,7 +243,7 @@
*/
if (src_sec_state == SMC_FROM_NON_SECURE) {
VERBOSE("RMM: RMI call from non-secure world.\n");
- return rmmd_smc_forward(smc_fid, NON_SECURE, REALM,
+ return rmmd_smc_forward(NON_SECURE, REALM, smc_fid,
x1, x2, x3, x4, handle);
}
@@ -250,7 +256,7 @@
rmmd_rmm_sync_exit(x1);
}
- return rmmd_smc_forward(x1, REALM, NON_SECURE,
+ return rmmd_smc_forward(REALM, NON_SECURE, x1,
x2, x3, x4, 0, handle);
default: