mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-27 15:24:54 +00:00
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:
parent
aef9b0da2a
commit
8e51cccaef
2 changed files with 29 additions and 17 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue