arch: riscv: fix sp of supervisor thread in _Fault function.

Although CONFIG_USERSPACE is enabled, there are supervisor threads who
don't have privileged stack using exception handler. Only let user
threads to switch to privileged stack in exception handler.

Signed-off-by: Jim Shu <cwshu@andestech.com>
This commit is contained in:
Jim Shu 2021-07-18 02:07:48 +08:00 committed by Carles Cufí
commit fd1e5aebc0

View file

@ -423,17 +423,26 @@ is_priv_sp:
addi a0, sp, 0 addi a0, sp, 0
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
la ra, no_reschedule_from_fault /* Check if we are in user thread */
WAS_NOT_USER(t0, t1)
bnez t0, supervisor_fault
user_fault:
/* Fault at user mode */
la ra, no_reschedule_user_fault
/* Switch to privilege stack */ /* Switch to privilege stack */
la t0, _kernel la t0, _kernel
RV_OP_LOADREG t1, _kernel_offset_to_current(t0) RV_OP_LOADREG t1, _kernel_offset_to_current(t0)
RV_OP_LOADREG t0, _thread_offset_to_priv_stack_start(t1) RV_OP_LOADREG t0, _thread_offset_to_priv_stack_start(t1)
RV_OP_STOREREG sp, _thread_offset_to_user_sp(t1) /* Update user SP */ RV_OP_STOREREG sp, _thread_offset_to_user_sp(t1) /* Update user SP */
addi sp, t0, CONFIG_PRIVILEGED_STACK_SIZE addi sp, t0, CONFIG_PRIVILEGED_STACK_SIZE
#else tail _Fault
la ra, no_reschedule
#endif /* CONFIG_USERSPACE */
supervisor_fault:
#endif /* CONFIG_USERSPACE */
/* Fault at supervisor mode */
la ra, no_reschedule
tail _Fault tail _Fault
is_kernel_syscall: is_kernel_syscall:
@ -599,18 +608,18 @@ valid_syscall_id:
return_from_syscall: return_from_syscall:
/* /*
* Retrieve a0 (returned value) from privilege stack * Retrieve a0 (return value) from privilege stack
* (or IRQ stack if stack guard is enabled). * (or IRQ stack if stack guard is enabled).
*/ */
RV_OP_LOADREG a0, __z_arch_esf_t_a0_OFFSET(sp) RV_OP_LOADREG a0, __z_arch_esf_t_a0_OFFSET(sp)
no_reschedule_from_fault: no_reschedule_user_fault:
/* Restore User SP */ /* Restore user stack */
la t0, _kernel la t0, _kernel
RV_OP_LOADREG t1, _kernel_offset_to_current(t0) RV_OP_LOADREG t1, _kernel_offset_to_current(t0)
RV_OP_LOADREG sp, _thread_offset_to_user_sp(t1) RV_OP_LOADREG sp, _thread_offset_to_user_sp(t1)
/* Update a0 (return value) */ /* Update a0 (return value) to user stack. */
RV_OP_STOREREG a0, __z_arch_esf_t_a0_OFFSET(sp) RV_OP_STOREREG a0, __z_arch_esf_t_a0_OFFSET(sp)
#ifdef CONFIG_PMP_STACK_GUARD #ifdef CONFIG_PMP_STACK_GUARD