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
|
config PMP_STACK_GUARD
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on MULTITHREADING
|
|
||||||
depends on HW_STACK_PROTECTION
|
depends on HW_STACK_PROTECTION
|
||||||
|
|
||||||
config PMP_STACK_GUARD_MIN_SIZE
|
config PMP_STACK_GUARD_MIN_SIZE
|
||||||
|
|
|
@ -172,11 +172,21 @@ static bool bad_stack_pointer(struct arch_esf *esf)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_USERSPACE */
|
#endif /* CONFIG_USERSPACE */
|
||||||
|
|
||||||
|
#if CONFIG_MULTITHREADING
|
||||||
if (sp >= _current->stack_info.start - K_KERNEL_STACK_RESERVED &&
|
if (sp >= _current->stack_info.start - K_KERNEL_STACK_RESERVED &&
|
||||||
sp < _current->stack_info.start - K_KERNEL_STACK_RESERVED
|
sp < _current->stack_info.start - K_KERNEL_STACK_RESERVED
|
||||||
+ Z_RISCV_STACK_GUARD_SIZE) {
|
+ Z_RISCV_STACK_GUARD_SIZE) {
|
||||||
return true;
|
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 */
|
#endif /* CONFIG_PMP_STACK_GUARD */
|
||||||
|
|
||||||
#ifdef CONFIG_USERSPACE
|
#ifdef CONFIG_USERSPACE
|
||||||
|
|
|
@ -348,8 +348,8 @@ static unsigned int global_pmp_end_index;
|
||||||
*/
|
*/
|
||||||
void z_riscv_pmp_init(void)
|
void z_riscv_pmp_init(void)
|
||||||
{
|
{
|
||||||
unsigned long pmp_addr[5];
|
unsigned long pmp_addr[CONFIG_PMP_SLOTS];
|
||||||
unsigned long pmp_cfg[2];
|
unsigned long pmp_cfg[CONFIG_PMP_SLOTS / PMPCFG_STRIDE];
|
||||||
unsigned int index = 0;
|
unsigned int index = 0;
|
||||||
|
|
||||||
/* The read-only area is always there for every mode */
|
/* The read-only area is always there for every mode */
|
||||||
|
@ -370,6 +370,7 @@ void z_riscv_pmp_init(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PMP_STACK_GUARD
|
#ifdef CONFIG_PMP_STACK_GUARD
|
||||||
|
#ifdef CONFIG_MULTITHREADING
|
||||||
/*
|
/*
|
||||||
* Set the stack guard for this CPU's IRQ stack by making the bottom
|
* 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
|
* 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 */
|
/* And forget about that last entry as we won't need it later */
|
||||||
index--;
|
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
|
#else
|
||||||
/* Write those entries to PMP regs. */
|
/* Write those entries to PMP regs. */
|
||||||
write_pmp_entries(0, index, true, pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr));
|
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
|
#endif
|
||||||
|
|
||||||
__ASSERT(index <= PMPCFG_STRIDE, "provision for one global word only");
|
|
||||||
global_pmp_cfg[0] = pmp_cfg[0];
|
global_pmp_cfg[0] = pmp_cfg[0];
|
||||||
global_pmp_last_addr = pmp_addr[index - 1];
|
global_pmp_last_addr = pmp_addr[index - 1];
|
||||||
global_pmp_end_index = index;
|
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_PMP_STACK_GUARD
|
||||||
|
|
||||||
|
#ifdef CONFIG_MULTITHREADING
|
||||||
/**
|
/**
|
||||||
* @brief Prepare the PMP stackguard content for given thread.
|
* @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);
|
csr_set(mstatus, MSTATUS_MPRV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_MULTITHREADING */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remove PMP stackguard content to actual PMP registers
|
* @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 */
|
#endif /* CONFIG_MULTITHREADING */
|
||||||
K_KERNEL_PINNED_STACK_ARRAY_DECLARE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS,
|
K_KERNEL_PINNED_STACK_ARRAY_DECLARE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS,
|
||||||
CONFIG_ISR_STACK_SIZE);
|
CONFIG_ISR_STACK_SIZE);
|
||||||
|
K_THREAD_STACK_DECLARE(z_main_stack, CONFIG_MAIN_STACK_SIZE);
|
||||||
|
|
||||||
#ifdef CONFIG_GEN_PRIV_STACKS
|
#ifdef CONFIG_GEN_PRIV_STACKS
|
||||||
extern uint8_t *z_priv_stack_find(k_thread_stack_t *stack);
|
extern uint8_t *z_priv_stack_find(k_thread_stack_t *stack);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue