diff options
author | Daniel Kalmar <kalmard@homejinni.com> | 2011-05-13 08:38:04 -0400 |
---|---|---|
committer | Robert Richter <robert.richter@amd.com> | 2011-06-15 08:35:33 -0400 |
commit | 94ea09c6a8e6c5ffb59bb1d5ca10008d37544e1a (patch) | |
tree | 86fd0e4241cfaa9a3d44ce6da39e54a291684143 /arch/mips/kernel | |
parent | 2c53b436a30867eb6b47dd7bab23ba638d1fb0d2 (diff) |
MIPS: Add new unwind_stack variant
The unwind_stack_by_address variant supports unwinding based
on any kernel code address.
This symbol is also exported so it can be called from modules.
Signed-off-by: Daniel Kalmar <kalmard@homejinni.com>
Signed-off-by: Gergely Kis <gergely@homejinni.com>
Signed-off-by: Robert Richter <robert.richter@amd.com>
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/process.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index d2112d3cf115..c28fbe6107bc 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -373,18 +373,18 @@ unsigned long thread_saved_pc(struct task_struct *tsk) | |||
373 | 373 | ||
374 | 374 | ||
375 | #ifdef CONFIG_KALLSYMS | 375 | #ifdef CONFIG_KALLSYMS |
376 | /* used by show_backtrace() */ | 376 | /* generic stack unwinding function */ |
377 | unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, | 377 | unsigned long notrace unwind_stack_by_address(unsigned long stack_page, |
378 | unsigned long pc, unsigned long *ra) | 378 | unsigned long *sp, |
379 | unsigned long pc, | ||
380 | unsigned long *ra) | ||
379 | { | 381 | { |
380 | unsigned long stack_page; | ||
381 | struct mips_frame_info info; | 382 | struct mips_frame_info info; |
382 | unsigned long size, ofs; | 383 | unsigned long size, ofs; |
383 | int leaf; | 384 | int leaf; |
384 | extern void ret_from_irq(void); | 385 | extern void ret_from_irq(void); |
385 | extern void ret_from_exception(void); | 386 | extern void ret_from_exception(void); |
386 | 387 | ||
387 | stack_page = (unsigned long)task_stack_page(task); | ||
388 | if (!stack_page) | 388 | if (!stack_page) |
389 | return 0; | 389 | return 0; |
390 | 390 | ||
@@ -443,6 +443,15 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, | |||
443 | *ra = 0; | 443 | *ra = 0; |
444 | return __kernel_text_address(pc) ? pc : 0; | 444 | return __kernel_text_address(pc) ? pc : 0; |
445 | } | 445 | } |
446 | EXPORT_SYMBOL(unwind_stack_by_address); | ||
447 | |||
448 | /* used by show_backtrace() */ | ||
449 | unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, | ||
450 | unsigned long pc, unsigned long *ra) | ||
451 | { | ||
452 | unsigned long stack_page = (unsigned long)task_stack_page(task); | ||
453 | return unwind_stack_by_address(stack_page, sp, pc, ra); | ||
454 | } | ||
446 | #endif | 455 | #endif |
447 | 456 | ||
448 | /* | 457 | /* |