diff options
Diffstat (limited to 'arch/arm/kernel/process.c')
-rw-r--r-- | arch/arm/kernel/process.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 94f6b05f9e24..92f7b15dd221 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -404,6 +404,7 @@ EXPORT_SYMBOL(dump_fpu); | |||
404 | unsigned long get_wchan(struct task_struct *p) | 404 | unsigned long get_wchan(struct task_struct *p) |
405 | { | 405 | { |
406 | struct stackframe frame; | 406 | struct stackframe frame; |
407 | unsigned long stack_page; | ||
407 | int count = 0; | 408 | int count = 0; |
408 | if (!p || p == current || p->state == TASK_RUNNING) | 409 | if (!p || p == current || p->state == TASK_RUNNING) |
409 | return 0; | 410 | return 0; |
@@ -412,9 +413,11 @@ unsigned long get_wchan(struct task_struct *p) | |||
412 | frame.sp = thread_saved_sp(p); | 413 | frame.sp = thread_saved_sp(p); |
413 | frame.lr = 0; /* recovered from the stack */ | 414 | frame.lr = 0; /* recovered from the stack */ |
414 | frame.pc = thread_saved_pc(p); | 415 | frame.pc = thread_saved_pc(p); |
416 | stack_page = (unsigned long)task_stack_page(p); | ||
415 | do { | 417 | do { |
416 | int ret = unwind_frame(&frame); | 418 | if (frame.sp < stack_page || |
417 | if (ret < 0) | 419 | frame.sp >= stack_page + THREAD_SIZE || |
420 | unwind_frame(&frame) < 0) | ||
418 | return 0; | 421 | return 0; |
419 | if (!in_sched_functions(frame.pc)) | 422 | if (!in_sched_functions(frame.pc)) |
420 | return frame.pc; | 423 | return frame.pc; |