arch: riscv: stacktrace: handle user threads
Handle user threads stack bound validation in `in_stack_bound()` to get more accurate traces. If `CONFIG_PMP_POWER_OF_TWO_ALIGNMENT` is enabled: ``` +------------+ <- thread.arch.priv_stack_start | Guard | } Z_RISCV_STACK_GUARD_SIZE +------------+ | Priv Stack | } CONFIG_PRIVILEGED_STACK_SIZE +------------+ <- thread.arch.priv_stack_start + CONFIG_PRIVILEGED_STACK_SIZE + Z_RISCV_STACK_GUARD_SIZE ``` otherwise: ``` +------------+ <- thread.stack_obj | Guard | } Z_RISCV_STACK_GUARD_SIZE +------------+ | Priv Stack | } CONFIG_PRIVILEGED_STACK_SIZE +------------+ <- thread.stack_info.start | Thread | | stack | | | +............| | TLS | } thread.stack_info.delta +------------+ <- thread.stack_info.start + thread.stack_info.size ``` See: zephyr/include/zephyr/arch/riscv/arch.h Signed-off-by: Yong Cong Sin <ycsin@meta.com>
This commit is contained in:
parent
602c993799
commit
6e8d979336
1 changed files with 16 additions and 6 deletions
|
@ -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)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue