Skip to content

Commit

Permalink
[review] core: arm64: preserve PSTATE.PAN when making SPSR
Browse files Browse the repository at this point in the history
Revert back to the old way of fabricating an SPSR, but preserve the PAN
bit in the saved SPSR.

Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
  • Loading branch information
jenswi-linaro committed Jul 20, 2023
1 parent 23719d1 commit 009804d
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 6 deletions.
2 changes: 0 additions & 2 deletions core/arch/arm/include/kernel/thread_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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*/

/*
Expand Down
10 changes: 9 additions & 1 deletion core/arch/arm/kernel/abort.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
/*
Expand All @@ -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*/

Expand Down
6 changes: 3 additions & 3 deletions core/arch/arm/kernel/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 009804d

Please sign in to comment.