From 678ce2237c67fbf20b080ee561358134bad1e18a Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Fri, 21 May 2021 18:00:04 +0200 Subject: [PATCH] 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 Change-Id: I66413ed5983913791ff5c9fc03c590ee65c6ccd7 --- services/std_svc/spmd/spmd_main.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 06039f007..e18d94cff 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -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);