riscv: pmp: enable stackguard without multithreading
Without multithreading only two stacks present: ISR and main. As any stack they also could overflow, so it make sense to add stack guard for them also. Remove stack guard dependency on multithreading and mark `Z_RISCV_STACK_GUARD_SIZE` bytes at the beginning of stack as read-only region with PMP entry. Signed-off-by: Volodymyr Fialko <vfialko@marvell.com>
This commit is contained in:
parent
2253a26c10
commit
9eee2eaee6
4 changed files with 32 additions and 4 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue