Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Daniel Kalmar and committed by
Robert Richter
94ea09c6 2c53b436

+18 -5
+4
arch/mips/include/asm/stacktrace.h
··· 7 7 extern int raw_show_trace; 8 8 extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, 9 9 unsigned long pc, unsigned long *ra); 10 + extern unsigned long unwind_stack_by_address(unsigned long stack_page, 11 + unsigned long *sp, 12 + unsigned long pc, 13 + unsigned long *ra); 10 14 #else 11 15 #define raw_show_trace 1 12 16 static inline unsigned long unwind_stack(struct task_struct *task,
+14 -5
arch/mips/kernel/process.c
··· 373 373 374 374 375 375 #ifdef CONFIG_KALLSYMS 376 - /* used by show_backtrace() */ 377 - unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, 378 - unsigned long pc, unsigned long *ra) 376 + /* generic stack unwinding function */ 377 + unsigned long notrace unwind_stack_by_address(unsigned long stack_page, 378 + unsigned long *sp, 379 + unsigned long pc, 380 + unsigned long *ra) 379 381 { 380 - unsigned long stack_page; 381 382 struct mips_frame_info info; 382 383 unsigned long size, ofs; 383 384 int leaf; 384 385 extern void ret_from_irq(void); 385 386 extern void ret_from_exception(void); 386 387 387 - stack_page = (unsigned long)task_stack_page(task); 388 388 if (!stack_page) 389 389 return 0; 390 390 ··· 442 442 *sp += info.frame_size; 443 443 *ra = 0; 444 444 return __kernel_text_address(pc) ? pc : 0; 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); 445 454 } 446 455 #endif 447 456