From 15dd6f19da8ee4b20ba525e0a742d0df9e46e071 Mon Sep 17 00:00:00 2001 From: Nishant Sharma Date: Tue, 19 Apr 2022 10:16:48 +0100 Subject: [PATCH] feat(spm_mm): add support to save and restore fp regs Add the support to save Nwd's floating point registers before switching to SEL0 and then restore it after coming out of it. Emit a warning message if SPM_MM is built with CTX_INCLUDE_FPREGS == 0 There is no need to save FP registers of SEL0 because secure partitions run to completion. This change is used to prevent context corruption if secure partition enabled and Nwd decide to use floating point registers. Signed-off-by: Nishant Sharma Change-Id: I1eea16ea2311a4f00a806ea72c118752821b9abb --- services/std_svc/spm/spm_mm/spm_mm.mk | 3 +++ services/std_svc/spm/spm_mm/spm_mm_main.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/services/std_svc/spm/spm_mm/spm_mm.mk b/services/std_svc/spm/spm_mm/spm_mm.mk index 78ef0c9fb..f6691c372 100644 --- a/services/std_svc/spm/spm_mm/spm_mm.mk +++ b/services/std_svc/spm/spm_mm/spm_mm.mk @@ -16,6 +16,9 @@ endif ifeq (${ENABLE_SME_FOR_NS},1) $(error "Error: SPM_MM is not compatible with ENABLE_SME_FOR_NS") endif +ifeq (${CTX_INCLUDE_FPREGS},0) + $(warning "Warning: SPM_MM: CTX_INCLUDE_FPREGS is set to 0") +endif SPM_MM_SOURCES := $(addprefix services/std_svc/spm/spm_mm/, \ ${ARCH}/spm_mm_shim_exceptions.S \ diff --git a/services/std_svc/spm/spm_mm/spm_mm_main.c b/services/std_svc/spm/spm_mm/spm_mm_main.c index e71e65b18..8525cd27c 100644 --- a/services/std_svc/spm/spm_mm/spm_mm_main.c +++ b/services/std_svc/spm/spm_mm/spm_mm_main.c @@ -190,6 +190,14 @@ uint64_t spm_mm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3) uint64_t rc; sp_context_t *sp_ptr = &sp_ctx; +#if CTX_INCLUDE_FPREGS + /* + * SP runs to completion, no need to restore FP registers of secure context. + * Save FP registers only for non secure context. + */ + fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE))); +#endif + /* Wait until the Secure Partition is idle and set it to busy. */ sp_state_wait_switch(sp_ptr, SP_STATE_IDLE, SP_STATE_BUSY); @@ -208,6 +216,14 @@ uint64_t spm_mm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3) assert(sp_ptr->state == SP_STATE_BUSY); sp_state_set(sp_ptr, SP_STATE_IDLE); +#if CTX_INCLUDE_FPREGS + /* + * SP runs to completion, no need to save FP registers of secure context. + * Restore only non secure world FP registers. + */ + fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE))); +#endif + return rc; }