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:
parent
3f16fdefbf
commit
fd1e5aebc0
1 changed files with 17 additions and 8 deletions
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue