mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-27 07:15:20 +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
|
#. 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.
|
#. 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
|
As part of SMC forwarding between the NS world and Realm world, EL3 allows x0-x7 to be passed
|
||||||
the NS Host and to maintain the confidentiality of the Realm World.
|
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
|
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
|
responsibility of RMM to ensure that these are appropriately saved if the
|
||||||
|
@ -506,6 +509,9 @@ Realm World makes use of them:
|
||||||
#. SME registers
|
#. SME registers
|
||||||
#. EL1/0 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
|
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
|
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
|
to clear SVE registers if they have been used in Realm World. The same applies
|
||||||
|
|
|
@ -242,10 +242,12 @@ int rmmd_setup(void)
|
||||||
* Forward SMC to the other security state
|
* Forward SMC to the other security state
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
static uint64_t rmmd_smc_forward(uint32_t src_sec_state,
|
static uint64_t rmmd_smc_forward(uint32_t src_sec_state,
|
||||||
uint32_t dst_sec_state, uint64_t x0,
|
uint32_t dst_sec_state, uint64_t x0,
|
||||||
uint64_t x1, uint64_t x2, uint64_t x3,
|
uint64_t x1, uint64_t x2, uint64_t x3,
|
||||||
uint64_t x4, void *handle)
|
uint64_t x4, void *handle)
|
||||||
{
|
{
|
||||||
|
cpu_context_t *ctx = cm_get_context(dst_sec_state);
|
||||||
|
|
||||||
/* Save incoming security state */
|
/* Save incoming security state */
|
||||||
cm_el1_sysregs_context_save(src_sec_state);
|
cm_el1_sysregs_context_save(src_sec_state);
|
||||||
cm_el2_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);
|
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
|
* being used as return args. Hence we differentiate the
|
||||||
* onward and backward path. Support upto 8 args in the
|
* onward and backward path. Support upto 8 args in the
|
||||||
* onward path and 4 args in return path.
|
* 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) {
|
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_X5),
|
||||||
SMC_GET_GP(handle, CTX_GPREG_X6),
|
SMC_GET_GP(handle, CTX_GPREG_X6),
|
||||||
SMC_GET_GP(handle, CTX_GPREG_X7));
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -276,8 +280,8 @@ static uint64_t rmmd_smc_forward(uint32_t src_sec_state,
|
||||||
* either forwarded to the other security state or handled by the RMM dispatcher
|
* either forwarded to the other security state or handled by the RMM dispatcher
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
|
uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
|
||||||
uint64_t x3, uint64_t x4, void *cookie,
|
uint64_t x3, uint64_t x4, void *cookie,
|
||||||
void *handle, uint64_t flags)
|
void *handle, uint64_t flags)
|
||||||
{
|
{
|
||||||
uint32_t src_sec_state;
|
uint32_t src_sec_state;
|
||||||
|
|
||||||
|
@ -311,10 +315,12 @@ uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (smc_fid) {
|
switch (smc_fid) {
|
||||||
case RMM_RMI_REQ_COMPLETE:
|
case RMM_RMI_REQ_COMPLETE: {
|
||||||
return rmmd_smc_forward(REALM, NON_SECURE, x1,
|
uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
|
||||||
x2, x3, x4, 0, handle);
|
|
||||||
|
|
||||||
|
return rmmd_smc_forward(REALM, NON_SECURE, x1,
|
||||||
|
x2, x3, x4, x5, handle);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
WARN("RMMD: Unsupported RMM call 0x%08x\n", smc_fid);
|
WARN("RMMD: Unsupported RMM call 0x%08x\n", smc_fid);
|
||||||
SMC_RET1(handle, SMC_UNK);
|
SMC_RET1(handle, SMC_UNK);
|
||||||
|
|
Loading…
Add table
Reference in a new issue