diff --git a/core/arch/arm/include/kernel/thread_arch.h b/core/arch/arm/include/kernel/thread_arch.h index c43ceceefc7..2beadf458c7 100644 --- a/core/arch/arm/include/kernel/thread_arch.h +++ b/core/arch/arm/include/kernel/thread_arch.h @@ -394,8 +394,6 @@ static inline void thread_user_clear_vfp(struct user_mode_ctx *uctx __unused) * @returns stack pointer */ vaddr_t thread_get_saved_thread_sp(void); - -uint64_t thread_get_spsr_from_pstate(void); #endif /*ARM64*/ /* diff --git a/core/arch/arm/kernel/abort.c b/core/arch/arm/kernel/abort.c index b482c684449..a0a431afa82 100644 --- a/core/arch/arm/kernel/abort.c +++ b/core/arch/arm/kernel/abort.c @@ -358,6 +358,8 @@ static void handle_user_mode_panic(struct abort_info *ai) static void handle_user_mode_panic(struct abort_info *ai) { struct thread_ctx *tc __maybe_unused = NULL; + uint32_t daif = 0; + uint32_t pan_bit = 0; /* * It was a user exception, stop user execution and return @@ -368,7 +370,6 @@ static void handle_user_mode_panic(struct abort_info *ai) ai->regs->x2 = 0xdeadbeef; ai->regs->elr = (vaddr_t)thread_unwind_user_mode; ai->regs->sp_el0 = thread_get_saved_thread_sp(); - ai->regs->spsr = thread_get_spsr_from_pstate(); #if defined(CFG_CORE_PAUTH) /* @@ -379,6 +380,13 @@ static void handle_user_mode_panic(struct abort_info *ai) ai->regs->apiakey_hi = tc->keys.apia_hi; ai->regs->apiakey_lo = tc->keys.apia_lo; #endif + + /* Unless PAN is supported the PAN bit in SPSR is RES0 */ + pan_bit = ai->regs->spsr & SPSR_64_PAN; + daif = (ai->regs->spsr >> SPSR_32_AIF_SHIFT) & SPSR_32_AIF_MASK; + /* XXX what about DAIF_D? */ + ai->regs->spsr = SPSR_64(SPSR_64_MODE_EL1, SPSR_64_MODE_SP_EL0, daif) | + pan_bit; } #endif /*ARM64*/ diff --git a/core/arch/arm/kernel/thread.c b/core/arch/arm/kernel/thread.c index bb2d26f2a27..735c3bb9339 100644 --- a/core/arch/arm/kernel/thread.c +++ b/core/arch/arm/kernel/thread.c @@ -412,7 +412,7 @@ void thread_resume_from_rpc(uint32_t thread_id, uint32_t a0, uint32_t a1, } #ifdef ARM64 -uint64_t thread_get_spsr_from_pstate(void) +static uint64_t spsr_from_pstate(void) { uint64_t spsr = SPSR_64(SPSR_64_MODE_EL1, SPSR_64_MODE_SP_EL0, 0); @@ -426,7 +426,7 @@ uint64_t thread_get_spsr_from_pstate(void) void __thread_rpc(uint32_t rv[THREAD_RPC_NUM_ARGS]) { - thread_rpc_spsr(rv, thread_get_spsr_from_pstate()); + thread_rpc_spsr(rv, spsr_from_pstate()); } vaddr_t thread_get_saved_thread_sp(void) @@ -1089,7 +1089,7 @@ static void setup_unwind_user_mode(struct thread_scall_regs *regs) #endif #ifdef ARM64 regs->elr = (uintptr_t)thread_unwind_user_mode; - regs->spsr = thread_get_spsr_from_pstate(); + regs->spsr = spsr_from_pstate(); /* * Regs is the value of stack pointer before calling the SVC * handler. By the addition matches for the reserved space at the