diff --git a/arch/riscv/core/stacktrace.c b/arch/riscv/core/stacktrace.c index ed0d4c1ba47..bc0063b3887 100644 --- a/arch/riscv/core/stacktrace.c +++ b/arch/riscv/core/stacktrace.c @@ -42,7 +42,7 @@ struct stackframe { LOG_ERR(" %2d: " SFP_FMT PR_REG " ra: " PR_REG, idx, sfp, ra) #endif -static bool in_stack_bound(uintptr_t addr) +static bool in_stack_bound(uintptr_t addr, const z_arch_esf_t *esf) { #ifdef CONFIG_THREAD_STACK_INFO uintptr_t start, end; @@ -54,8 +54,17 @@ static bool in_stack_bound(uintptr_t addr) start = (uintptr_t)K_KERNEL_STACK_BUFFER(z_interrupt_stacks[cpu_id]); end = start + CONFIG_ISR_STACK_SIZE; #ifdef CONFIG_USERSPACE - /* TODO: handle user threads */ -#endif + } else if (((esf->mstatus & MSTATUS_MPP) == PRV_U) && + ((_current->base.user_options & K_USER) != 0)) { + /* See: zephyr/include/zephyr/arch/riscv/arch.h */ + if (IS_ENABLED(CONFIG_PMP_POWER_OF_TWO_ALIGNMENT)) { + start = _current->arch.priv_stack_start - CONFIG_PRIVILEGED_STACK_SIZE; + end = _current->arch.priv_stack_start; + } else { + start = _current->stack_info.start - CONFIG_PRIVILEGED_STACK_SIZE; + end = _current->stack_info.start; + } +#endif /* CONFIG_USERSPACE */ } else { start = _current->stack_info.start; end = Z_STACK_PTR_ALIGN(_current->stack_info.start + _current->stack_info.size); @@ -64,6 +73,7 @@ static bool in_stack_bound(uintptr_t addr) return (addr >= start) && (addr < end); #else ARG_UNUSED(addr); + ARG_UNUSED(esf); return true; #endif /* CONFIG_THREAD_STACK_INFO */ } @@ -84,7 +94,7 @@ void z_riscv_unwind_stack(const z_arch_esf_t *esf) LOG_ERR("call trace:"); - for (int i = 0; (i < MAX_STACK_FRAMES) && (fp != 0U) && in_stack_bound(fp);) { + for (int i = 0; (i < MAX_STACK_FRAMES) && (fp != 0U) && in_stack_bound(fp, esf);) { frame = (struct stackframe *)fp - 1; ra = frame->ra; if (in_text_region(ra)) { @@ -113,8 +123,8 @@ void z_riscv_unwind_stack(const z_arch_esf_t *esf) LOG_ERR("call trace:"); - for (int i = 0; - (i < MAX_STACK_FRAMES) && ((uintptr_t)ksp != 0U) && in_stack_bound((uintptr_t)ksp); + for (int i = 0; (i < MAX_STACK_FRAMES) && ((uintptr_t)ksp != 0U) && + in_stack_bound((uintptr_t)ksp, esf); ksp++) { ra = *ksp; if (in_text_region(ra)) {