From 03fafc0b66ed8fe20dd15a119354e9515f0311e3 Mon Sep 17 00:00:00 2001 From: Arvind Ram Prakash Date: Tue, 20 Feb 2024 11:35:27 -0600 Subject: [PATCH] refactor(sdei): use common create_spsr() in SDEI library The current SPSR updation code as part of the SDEI interrupt handler code is outdated. This patch replaces the legacy code with a call to an up-to-date create_spsr() Change-Id: I1f5fdd41dd14f4b09601310fe881fa3783d7f505 Signed-off-by: Arvind Ram Prakash --- bl31/bl31_traps.c | 2 +- include/bl31/sync_handle.h | 2 + services/std_svc/sdei/sdei_intr_mgmt.c | 57 ++------------------------ 3 files changed, 6 insertions(+), 55 deletions(-) diff --git a/bl31/bl31_traps.c b/bl31/bl31_traps.c index d14a91e0a..f1b1fa6ed 100644 --- a/bl31/bl31_traps.c +++ b/bl31/bl31_traps.c @@ -97,7 +97,7 @@ static u_register_t get_elr_el3(u_register_t spsr_el3, u_register_t vbar, unsign * NOTE: This piece of code must be reviewed every release to ensure that * we keep up with new ARCH features which introduces a new SPSR bit. */ -static u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el) +u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el) { u_register_t new_spsr = 0; u_register_t sctlr; diff --git a/include/bl31/sync_handle.h b/include/bl31/sync_handle.h index ae61f3177..394252b7b 100644 --- a/include/bl31/sync_handle.h +++ b/include/bl31/sync_handle.h @@ -58,6 +58,8 @@ int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx); /* Handler for injecting UNDEF exception to lower EL */ void inject_undef64(cpu_context_t *ctx); +u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el); + /* Prototypes for system register emulation handlers provided by platforms. */ int plat_handle_impdef_trap(uint64_t esr_el3, cpu_context_t *ctx); int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx); diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c index 72bc33f22..c58adba50 100644 --- a/services/std_svc/sdei/sdei_intr_mgmt.c +++ b/services/std_svc/sdei/sdei_intr_mgmt.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -237,9 +238,7 @@ static cpu_context_t *restore_and_resume_ns_context(void) /* * Prepare for ERET: * - Set the ELR to the registered handler address - * - Set the SPSR register as described in the SDEI documentation and - * the AArch64.TakeException() pseudocode function in - * ARM DDI 0487F.c page J1-7635 + * - Set the SPSR register by calling the common create_spsr() function */ static void sdei_set_elr_spsr(sdei_entry_t *se, sdei_dispatch_context_t *disp_ctx) @@ -250,57 +249,7 @@ static void sdei_set_elr_spsr(sdei_entry_t *se, sdei_dispatch_context_t *disp_ct u_register_t interrupted_pstate = disp_ctx->spsr_el3; - /* Check the SPAN bit in the client el SCTLR */ - u_register_t client_el_sctlr; - - if (client_el == MODE_EL2) { - client_el_sctlr = read_sctlr_el2(); - } else { - client_el_sctlr = read_sctlr_el1(); - } - - /* - * Check whether to force the PAN bit or use the value in the - * interrupted EL according to the check described in - * TakeException. Since the client can only be Non-Secure - * EL2 or El1 some of the conditions in ElIsInHost() we know - * will always be True. - * When the client_el is EL2 we know that there will be a SPAN - * bit in SCTLR_EL2 as we have already checked for the condition - * HCR_EL2.E2H = 1 and HCR_EL2.TGE = 1 - */ - u_register_t hcr_el2 = read_hcr(); - bool el_is_in_host = (read_feat_vhe_id_field() != 0U) && - (hcr_el2 & HCR_TGE_BIT) && - (hcr_el2 & HCR_E2H_BIT); - - if (is_feat_pan_supported() && - ((client_el == MODE_EL1) || - (client_el == MODE_EL2 && el_is_in_host)) && - ((client_el_sctlr & SCTLR_SPAN_BIT) == 0U)) { - sdei_spsr |= SPSR_PAN_BIT; - } else { - sdei_spsr |= (interrupted_pstate & SPSR_PAN_BIT); - } - - /* If SSBS is implemented, take the value from the client el SCTLR */ - u_register_t ssbs_enabled = (read_id_aa64pfr1_el1() - >> ID_AA64PFR1_EL1_SSBS_SHIFT) - & ID_AA64PFR1_EL1_SSBS_MASK; - if (ssbs_enabled != SSBS_UNAVAILABLE) { - u_register_t ssbs_bit = ((client_el_sctlr & SCTLR_DSSBS_BIT) - >> SCTLR_DSSBS_SHIFT) - << SPSR_SSBS_SHIFT_AARCH64; - sdei_spsr |= ssbs_bit; - } - - /* If MTE is implemented in the client el set the TCO bit */ - if (is_feat_mte_supported()) { - sdei_spsr |= SPSR_TCO_BIT_AARCH64; - } - - /* Take the DIT field from the pstate of the interrupted el */ - sdei_spsr |= (interrupted_pstate & SPSR_DIT_BIT); + sdei_spsr = create_spsr(interrupted_pstate, client_el); cm_set_elr_spsr_el3(NON_SECURE, (uintptr_t) se->ep, sdei_spsr); }