diff options
Diffstat (limited to 'arch/arm/kernel/process.c')
-rw-r--r-- | arch/arm/kernel/process.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index d3ea6fa89521..af377c73d90b 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -34,6 +34,7 @@ #include <asm/processor.h> #include <asm/system.h> #include <asm/thread_notify.h> +#include <asm/stacktrace.h> #include <asm/mach/time.h> static const char *processor_modes[] = { @@ -372,23 +373,21 @@ EXPORT_SYMBOL(kernel_thread); unsigned long get_wchan(struct task_struct *p) { - unsigned long fp, lr; - unsigned long stack_start, stack_end; + struct stackframe frame; int count = 0; if (!p || p == current || p->state == TASK_RUNNING) return 0; - stack_start = (unsigned long)end_of_stack(p); - stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE; - - fp = thread_saved_fp(p); + frame.fp = thread_saved_fp(p); + frame.sp = thread_saved_sp(p); + frame.lr = 0; /* recovered from the stack */ + frame.pc = thread_saved_pc(p); do { - if (fp < stack_start || fp > stack_end) + int ret = unwind_frame(&frame); + if (ret < 0) return 0; - lr = ((unsigned long *)fp)[-1]; - if (!in_sched_functions(lr)) - return lr; - fp = *(unsigned long *) (fp - 12); + if (!in_sched_functions(frame.pc)) + return frame.pc; } while (count ++ < 16); return 0; } |