diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h index 2d76a2e29f059f01d7fb8cfc285e0f1a0dbc13a4..9d082168c6722767d6a81f79467f8be65e85fc19 100644 --- a/arch/arm/include/asm/stacktrace.h +++ b/arch/arm/include/asm/stacktrace.h @@ -13,6 +13,7 @@ struct stackframe { unsigned long sp; unsigned long lr; unsigned long pc; + bool ex_frame; }; static __always_inline diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 2647e48c537e618ec631b077538b5f43485017ed..1b4cc298574aae5ffa00570b23eddef5f111f1bd 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -294,6 +294,7 @@ unsigned long get_wchan(struct task_struct *p) frame.lr = 0; /* recovered from the stack */ frame.pc = thread_saved_pc(p); stack_page = (unsigned long)task_stack_page(p); + frame.ex_frame = true; do { if (frame.sp < stack_page || frame.sp >= stack_page + THREAD_SIZE || diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index 82477499982591a09eb26c3890b0277570f825f5..1451893142b76fca52555c6d3fc23d275b953e44 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c @@ -73,6 +73,7 @@ int notrace unwind_frame(struct stackframe *frame) void notrace walk_stackframe(struct stackframe *frame, int (*fn)(struct stackframe *, void *), void *data) { + frame->ex_frame = true; while (1) { int ret; diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index 9d3a18c1b86c07e21f7c5489bf641d37fb016755..ca1f4809f9b665bf686318ba26af8ce93b89de45 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c @@ -35,6 +35,7 @@ #include #include #include +#include /* Dummy functions to avoid linker complaints */ void __aeabi_unwind_cpp_pr0(void) @@ -415,7 +416,7 @@ int unwind_frame(struct stackframe *frame) if (!kernel_text_address(frame->pc)) return -URC_FAILURE; - idx = unwind_find_idx(frame->pc); + idx = unwind_find_idx(frame->ex_frame ? frame->pc : frame->pc - 1); if (!idx) { pr_warn("unwind: Index not found %08lx\n", frame->pc); return -URC_FAILURE; @@ -478,6 +479,7 @@ int unwind_frame(struct stackframe *frame) frame->sp = ctrl.vrs[SP]; frame->lr = ctrl.vrs[LR]; frame->pc = ctrl.vrs[PC]; + frame->ex_frame = in_entry_text(frame->pc); return URC_OK; } @@ -513,6 +515,7 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk, frame.lr = 0; frame.pc = thread_saved_pc(tsk); } + frame.ex_frame = true; while (1) { int urc;