MIPS: Add new unwind_stack variant
authorDaniel Kalmar <kalmard@homejinni.com>
Fri, 13 May 2011 12:38:04 +0000 (08:38 -0400)
committerRobert Richter <robert.richter@amd.com>
Wed, 15 Jun 2011 12:35:33 +0000 (14:35 +0200)
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>
arch/mips/include/asm/stacktrace.h
arch/mips/kernel/process.c

index 0bf8281..780ee2c 100644 (file)
@@ -7,6 +7,10 @@
 extern int raw_show_trace;
 extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
                                  unsigned long pc, unsigned long *ra);
+extern unsigned long unwind_stack_by_address(unsigned long stack_page,
+                                            unsigned long *sp,
+                                            unsigned long pc,
+                                            unsigned long *ra);
 #else
 #define raw_show_trace 1
 static inline unsigned long unwind_stack(struct task_struct *task,
index d2112d3..c28fbe6 100644 (file)
@@ -373,18 +373,18 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
 
 
 #ifdef CONFIG_KALLSYMS
-/* used by show_backtrace() */
-unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
-                          unsigned long pc, unsigned long *ra)
+/* generic stack unwinding function */
+unsigned long notrace unwind_stack_by_address(unsigned long stack_page,
+                                             unsigned long *sp,
+                                             unsigned long pc,
+                                             unsigned long *ra)
 {
-       unsigned long stack_page;
        struct mips_frame_info info;
        unsigned long size, ofs;
        int leaf;
        extern void ret_from_irq(void);
        extern void ret_from_exception(void);
 
-       stack_page = (unsigned long)task_stack_page(task);
        if (!stack_page)
                return 0;
 
@@ -443,6 +443,15 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
        *ra = 0;
        return __kernel_text_address(pc) ? pc : 0;
 }
+EXPORT_SYMBOL(unwind_stack_by_address);
+
+/* used by show_backtrace() */
+unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
+                          unsigned long pc, unsigned long *ra)
+{
+       unsigned long stack_page = (unsigned long)task_stack_page(task);
+       return unwind_stack_by_address(stack_page, sp, pc, ra);
+}
 #endif
 
 /*