perf(spmd): omit sel1 context save if sel2 present

The SPMC at S-EL2 manages S-EL1 execution contexts for SPs. The
currently running SP vCPU state is always saved when the SPMC exits to
SPMD. A fresh vCPU context is always restored when the SPMC is entered
from the SPMD and a SP resumed. For performance optimization reasons
this permits omitting the saving/restoring of the S-EL1 context from
within the EL3 SPMD on entering/exiting the SPMC. The S-EL2 SPMC and
NS-EL1 context save/restore remain done in the SPMD.

Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Change-Id: I66413ed5983913791ff5c9fc03c590ee65c6ccd7
This commit is contained in:
Olivier Deprez 2021-05-21 18:00:04 +02:00
parent 183725b39d
commit 678ce2237c
1 changed files with 14 additions and 4 deletions

View File

@ -108,9 +108,10 @@ uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx)
cm_set_context(&(spmc_ctx->cpu_ctx), SECURE);
/* Restore the context assigned above */
cm_el1_sysregs_context_restore(SECURE);
#if SPMD_SPM_AT_SEL2
cm_el2_sysregs_context_restore(SECURE);
#else
cm_el1_sysregs_context_restore(SECURE);
#endif
cm_set_next_eret_context(SECURE);
@ -118,9 +119,10 @@ uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx)
rc = spmd_spm_core_enter(&spmc_ctx->c_rt_ctx);
/* Save secure state */
cm_el1_sysregs_context_save(SECURE);
#if SPMD_SPM_AT_SEL2
cm_el2_sysregs_context_save(SECURE);
#else
cm_el1_sysregs_context_save(SECURE);
#endif
return rc;
@ -346,15 +348,23 @@ static uint64_t spmd_smc_forward(uint32_t smc_fid,
unsigned int secure_state_out = (!secure_origin) ? SECURE : NON_SECURE;
/* Save incoming security state */
cm_el1_sysregs_context_save(secure_state_in);
#if SPMD_SPM_AT_SEL2
if (secure_state_in == NON_SECURE) {
cm_el1_sysregs_context_save(secure_state_in);
}
cm_el2_sysregs_context_save(secure_state_in);
#else
cm_el1_sysregs_context_save(secure_state_in);
#endif
/* Restore outgoing security state */
cm_el1_sysregs_context_restore(secure_state_out);
#if SPMD_SPM_AT_SEL2
if (secure_state_out == NON_SECURE) {
cm_el1_sysregs_context_restore(secure_state_out);
}
cm_el2_sysregs_context_restore(secure_state_out);
#else
cm_el1_sysregs_context_restore(secure_state_out);
#endif
cm_set_next_eret_context(secure_state_out);