diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 8f426d09d3f..7314a1923e2 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -337,7 +337,6 @@ endif #RISCV_PMP config PMP_STACK_GUARD def_bool y - depends on MULTITHREADING depends on HW_STACK_PROTECTION config PMP_STACK_GUARD_MIN_SIZE diff --git a/arch/riscv/core/fatal.c b/arch/riscv/core/fatal.c index d5cbd2f4dc1..879ffab9a80 100644 --- a/arch/riscv/core/fatal.c +++ b/arch/riscv/core/fatal.c @@ -172,11 +172,21 @@ static bool bad_stack_pointer(struct arch_esf *esf) } #endif /* CONFIG_USERSPACE */ +#if CONFIG_MULTITHREADING if (sp >= _current->stack_info.start - K_KERNEL_STACK_RESERVED && sp < _current->stack_info.start - K_KERNEL_STACK_RESERVED + Z_RISCV_STACK_GUARD_SIZE) { return true; } +#else + uintptr_t isr_stack = (uintptr_t)z_interrupt_stacks; + uintptr_t main_stack = (uintptr_t)z_main_stack; + + if ((sp >= isr_stack && sp < isr_stack + Z_RISCV_STACK_GUARD_SIZE) || + (sp >= main_stack && sp < main_stack + Z_RISCV_STACK_GUARD_SIZE)) { + return true; + } +#endif /* CONFIG_MULTITHREADING */ #endif /* CONFIG_PMP_STACK_GUARD */ #ifdef CONFIG_USERSPACE diff --git a/arch/riscv/core/pmp.c b/arch/riscv/core/pmp.c index e41eb8d4bb0..e29c8abd76d 100644 --- a/arch/riscv/core/pmp.c +++ b/arch/riscv/core/pmp.c @@ -348,8 +348,8 @@ static unsigned int global_pmp_end_index; */ void z_riscv_pmp_init(void) { - unsigned long pmp_addr[5]; - unsigned long pmp_cfg[2]; + unsigned long pmp_addr[CONFIG_PMP_SLOTS]; + unsigned long pmp_cfg[CONFIG_PMP_SLOTS / PMPCFG_STRIDE]; unsigned int index = 0; /* The read-only area is always there for every mode */ @@ -370,6 +370,7 @@ void z_riscv_pmp_init(void) #endif #ifdef CONFIG_PMP_STACK_GUARD +#ifdef CONFIG_MULTITHREADING /* * Set the stack guard for this CPU's IRQ stack by making the bottom * addresses inaccessible. This will never change so we do it here @@ -396,6 +397,21 @@ void z_riscv_pmp_init(void) /* And forget about that last entry as we won't need it later */ index--; +#else + /* Without multithreading setup stack guards for IRQ and main stacks */ + set_pmp_entry(&index, PMP_NONE | PMP_L, + (uintptr_t)z_interrupt_stacks, + Z_RISCV_STACK_GUARD_SIZE, + pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr)); + + set_pmp_entry(&index, PMP_NONE | PMP_L, + (uintptr_t)z_main_stack, + Z_RISCV_STACK_GUARD_SIZE, + pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr)); + + /* Write those entries to PMP regs. */ + write_pmp_entries(0, index, true, pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr)); +#endif /* CONFIG_MULTITHREADING */ #else /* Write those entries to PMP regs. */ write_pmp_entries(0, index, true, pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr)); @@ -419,7 +435,6 @@ void z_riscv_pmp_init(void) } #endif - __ASSERT(index <= PMPCFG_STRIDE, "provision for one global word only"); global_pmp_cfg[0] = pmp_cfg[0]; global_pmp_last_addr = pmp_addr[index - 1]; global_pmp_end_index = index; @@ -454,6 +469,7 @@ static inline unsigned int z_riscv_pmp_thread_init(unsigned long *pmp_addr, #ifdef CONFIG_PMP_STACK_GUARD +#ifdef CONFIG_MULTITHREADING /** * @brief Prepare the PMP stackguard content for given thread. * @@ -511,6 +527,8 @@ void z_riscv_pmp_stackguard_enable(struct k_thread *thread) csr_set(mstatus, MSTATUS_MPRV); } +#endif /* CONFIG_MULTITHREADING */ + /** * @brief Remove PMP stackguard content to actual PMP registers */ diff --git a/kernel/include/kernel_internal.h b/kernel/include/kernel_internal.h index bb9ee4b01f1..94f90ce9462 100644 --- a/kernel/include/kernel_internal.h +++ b/kernel/include/kernel_internal.h @@ -152,6 +152,7 @@ extern struct k_thread z_idle_threads[CONFIG_MP_MAX_NUM_CPUS]; #endif /* CONFIG_MULTITHREADING */ K_KERNEL_PINNED_STACK_ARRAY_DECLARE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS, CONFIG_ISR_STACK_SIZE); +K_THREAD_STACK_DECLARE(z_main_stack, CONFIG_MAIN_STACK_SIZE); #ifdef CONFIG_GEN_PRIV_STACKS extern uint8_t *z_priv_stack_find(k_thread_stack_t *stack);