Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ config RISCV_PMP
select THREAD_LOCAL_STORAGE if USERSPACE
select ARCH_MEM_DOMAIN_SUPPORTS_ISOLATED_STACKS
select MEM_DOMAIN_ISOLATED_STACKS
select PMP_KERNEL_MODE_DYNAMIC if MEM_ATTR
help
MCU implements Physical Memory Protection.

Expand Down Expand Up @@ -414,6 +415,7 @@ endif #RISCV_PMP
config PMP_STACK_GUARD
def_bool y
depends on HW_STACK_PROTECTION
select PMP_KERNEL_MODE_DYNAMIC if MULTITHREADING

config PMP_STACK_GUARD_MIN_SIZE
int "Stack Guard area size"
Expand All @@ -430,6 +432,12 @@ config PMP_STACK_GUARD_MIN_SIZE
wiggle room to accommodate the eventual overflow exception
stack usage.

config PMP_KERNEL_MODE_DYNAMIC
bool
help
Enable this to dynamically reconfigure and activate PMP entries for
Machine mode when switching between kernel (ISR, syscall) and threads.

# Implement the null pointer detection using the Physical Memory Protection
# (PMP) Unit.
config NULL_POINTER_EXCEPTION_DETECTION_PMP
Expand Down
4 changes: 2 additions & 2 deletions arch/riscv/core/fatal.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,12 @@ void z_riscv_fault(struct arch_esf *esf)
unsigned int reason = K_ERR_CPU_EXCEPTION;

if (bad_stack_pointer(esf)) {
#ifdef CONFIG_PMP_STACK_GUARD
#if defined(CONFIG_PMP_STACK_GUARD) && defined(CONFIG_MULTITHREADING)
/*
* Remove the thread's PMP setting to prevent triggering a stack
* overflow error again due to the previous configuration.
*/
z_riscv_pmp_stackguard_disable();
z_riscv_pmp_kernelmode_disable();
#endif /* CONFIG_PMP_STACK_GUARD */
reason = K_ERR_STACK_CHK_FAIL;
}
Expand Down
26 changes: 13 additions & 13 deletions arch/riscv/core/isr.S
Original file line number Diff line number Diff line change
Expand Up @@ -368,19 +368,19 @@ no_fp: /* increment _current->arch.exception_depth */
li t1, RISCV_EXC_ECALLU
beq t0, t1, is_user_syscall

#if defined(CONFIG_PMP_STACK_GUARD) && defined(CONFIG_MULTITHREADING)
#ifdef CONFIG_PMP_KERNEL_MODE_DYNAMIC
/*
* Determine if we come from user space. If so, reconfigure the PMP for
* kernel mode stack guard.
* kernel mode configuration.
*/
csrr t0, mstatus
li t1, MSTATUS_MPP
and t0, t0, t1
bnez t0, 1f
lr a0, ___cpu_t_current_OFFSET(s0)
call z_riscv_pmp_stackguard_enable
call z_riscv_pmp_kernelmode_enable
1:
#endif /* CONFIG_PMP_STACK_GUARD */
#endif /* CONFIG_PMP_KERNEL_MODE_DYNAMIC */

#endif /* CONFIG_USERSPACE */

Expand Down Expand Up @@ -422,7 +422,7 @@ is_kernel_syscall:
addi t0, t0, 4
sr t0, __struct_arch_esf_mepc_OFFSET(sp)

#if defined(CONFIG_PMP_STACK_GUARD) && defined(CONFIG_MULTITHREADING)
#ifdef CONFIG_PMP_KERNEL_MODE_DYNAMIC
/* Re-activate PMP for m-mode */
li t1, MSTATUS_MPP
csrc mstatus, t1
Expand Down Expand Up @@ -515,13 +515,13 @@ do_irq_offload:
#ifdef CONFIG_USERSPACE
is_user_syscall:

#if defined(CONFIG_PMP_STACK_GUARD) && defined(CONFIG_MULTITHREADING)
#ifdef CONFIG_PMP_KERNEL_MODE_DYNAMIC
/*
* We came from userspace and need to reconfigure the
* PMP for kernel mode stack guard.
* PMP for kernel mode configuration.
*/
lr a0, ___cpu_t_current_OFFSET(s0)
call z_riscv_pmp_stackguard_enable
call z_riscv_pmp_kernelmode_enable
#endif

/* It is safe to re-enable IRQs now */
Expand Down Expand Up @@ -585,18 +585,18 @@ valid_syscall_id:

is_interrupt:

#if defined(CONFIG_PMP_STACK_GUARD) && defined(CONFIG_MULTITHREADING)
#ifdef CONFIG_PMP_KERNEL_MODE_DYNAMIC
#ifdef CONFIG_USERSPACE
/*
* If we came from userspace then we need to reconfigure the
* PMP for kernel mode stack guard.
* PMP for kernel mode configuration.
*/
lr t0, __struct_arch_esf_mstatus_OFFSET(sp)
li t1, MSTATUS_MPP
and t0, t0, t1
bnez t0, 1f
lr a0, ___cpu_t_current_OFFSET(s0)
call z_riscv_pmp_stackguard_enable
call z_riscv_pmp_kernelmode_enable
j 2f
#endif /* CONFIG_USERSPACE */
1: /* Re-activate PMP for m-mode */
Expand Down Expand Up @@ -769,8 +769,8 @@ fp_trap_exit:
and t0, t2, t1
bnez t0, 1f

#if defined(CONFIG_PMP_STACK_GUARD) && defined(CONFIG_MULTITHREADING)
/* Remove kernel stack guard and Reconfigure PMP for user mode */
#ifdef CONFIG_PMP_KERNEL_MODE_DYNAMIC
/* Remove kernel mode configuration and Reconfigure PMP for user mode */
lr a0, ___cpu_t_current_OFFSET(s0)
call z_riscv_pmp_usermode_enable
#endif
Expand Down
Loading