From 11578303fd04a8da36fddb5e6de44f026bf4d24c Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Wed, 17 Nov 2021 15:13:30 +0000 Subject: [PATCH] fix(rmmd): preserve x4-x7 as per SMCCCv1.1 The RMI command handling in RMMD did not preserve x4 to x7 when returning to NS caller. Although this is allowed for SMCCCv1.0, this is not correct as per v1.1. This fixes the same by differentiating the onward and backward path during SMC handling. This patch also fixes an issue with the backward path wherein the first argument was being truncated to 32 bits. Change-Id: Ibc85d574d5a2178a763975ddb32e456a12e7dc88 Signed-off-by: Soby Mathew --- services/std_svc/rmmd/rmmd_main.c | 34 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c index 7f85b636f..e9004c791 100644 --- a/services/std_svc/rmmd/rmmd_main.c +++ b/services/std_svc/rmmd/rmmd_main.c @@ -48,10 +48,6 @@ static entry_point_info_t *rmm_ep_info; * 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 @@ int rmmd_setup(void) /******************************************************************************* * 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 @@ static uint64_t rmmd_smc_forward(uint32_t smc_fid, uint32_t src_sec_state, 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 @@ uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, */ 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 @@ uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, 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: