fix(rmmd): return X4 output value

Return values contained in 'smc_result' structure
are shifted down by one register:
X1 written by RMM is returned to NS in X0 and
X5 is returned in X4.

Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com>
Change-Id: I92907ac3ff3bac8554643ae7c198a4a758c38cb3
This commit is contained in:
AlexeiFedorov 2022-09-23 16:57:28 +01:00 committed by Soby Mathew
parent aef9b0da2a
commit 8e51cccaef
2 changed files with 29 additions and 17 deletions

View file

@ -494,8 +494,11 @@ EL3 must maintain a separate register context for the following:
#. General purpose registers (x0-x30) and ``sp_el0``, ``sp_el2`` stack pointers
#. EL2 system register context for all enabled features by EL3. These include system registers with the ``_EL2`` prefix. The EL2 physical and virtual timer registers must not be included in this.
It is the responsibility of EL3 that the above registers will not be leaked to
the NS Host and to maintain the confidentiality of the Realm World.
As part of SMC forwarding between the NS world and Realm world, EL3 allows x0-x7 to be passed
as arguments to Realm and x0-x4 to be used for return arguments back to Non Secure.
As per SMCCCv1.2, x4 must be preserved if not being used as return argument by the SMC function
and it is the responsibility of RMM to preserve this or use this as a return argument.
EL3 will always copy x0-x4 from Realm context to NS Context.
EL3 will not save some registers as mentioned in the below list. It is the
responsibility of RMM to ensure that these are appropriately saved if the
@ -506,6 +509,9 @@ Realm World makes use of them:
#. SME registers
#. EL1/0 registers
It is the responsibility of EL3 that any other registers other than the ones mentioned above
will not be leaked to the NS Host and to maintain the confidentiality of the Realm World.
SMCCC v1.3 allows NS world to specify whether SVE context is in use. In this
case, RMM could choose to not save the incoming SVE context but must ensure
to clear SVE registers if they have been used in Realm World. The same applies

View file

@ -246,6 +246,8 @@ static uint64_t rmmd_smc_forward(uint32_t src_sec_state,
uint64_t x1, uint64_t x2, uint64_t x3,
uint64_t x4, void *handle)
{
cpu_context_t *ctx = cm_get_context(dst_sec_state);
/* Save incoming security state */
cm_el1_sysregs_context_save(src_sec_state);
cm_el2_sysregs_context_save(src_sec_state);
@ -256,19 +258,21 @@ static uint64_t rmmd_smc_forward(uint32_t src_sec_state,
cm_set_next_eret_context(dst_sec_state);
/*
* As per SMCCCv1.1, we need to preserve x4 to x7 unless
* As per SMCCCv1.2, 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.
* Register x4 will be preserved by RMM in case it is not
* used in return path.
*/
if (src_sec_state == NON_SECURE) {
SMC_RET8(cm_get_context(dst_sec_state), x0, x1, x2, x3, x4,
SMC_RET8(ctx, 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);
}
SMC_RET5(ctx, x0, x1, x2, x3, x4);
}
/*******************************************************************************
@ -311,10 +315,12 @@ uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
}
switch (smc_fid) {
case RMM_RMI_REQ_COMPLETE:
return rmmd_smc_forward(REALM, NON_SECURE, x1,
x2, x3, x4, 0, handle);
case RMM_RMI_REQ_COMPLETE: {
uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
return rmmd_smc_forward(REALM, NON_SECURE, x1,
x2, x3, x4, x5, handle);
}
default:
WARN("RMMD: Unsupported RMM call 0x%08x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);