From 47ad7b9bbeaac34e43d9dc8db796f1f68194b9ad Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Fri, 8 May 2015 10:27:35 -0400 Subject: tile: improve stack backtrace This commit fixes a number of issues with the tile backtrace code. - Don't try to identify userspace shared object or executable paths if we are doing a backtrace from an interrupt; it's not legal, and also unlikely to be interesting. Likewise, don't try to do it for other address spaces, since d_path() assumes it is being called in "current" context. - Move "in_backtrace" from thread_struct to thread_info. This way we can access it even if our stack thread_info has been clobbered, which makes backtracing more robust. - Avoid using "current" directly when testing for is_sigreturn(). Since "current" may be corrupt, we're better off using kbt->task explicitly to look up the vdso_base for the current task. Conveniently, this simplifies the internal APIs (we only need one is_sigreturn() function now). - Avoid bogus "Odd fault" warning when pc/sp/ex1 are all zero, as is true for kernel threads above the last frame. - Hook into Tejun Heo's dump_stack() framework in lib/dump_stack.c. - Write last entry in save_stack_trace() as ULONG_MAX, not zero, since ftrace (at least) relies on finding that marker. - Implement save_stack_trace_regs() and save_strack_trace_user(), and set CONFIG_USER_STACKTRACE_SUPPORT. Signed-off-by: Chris Metcalf --- arch/tile/kernel/process.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'arch/tile/kernel/process.c') diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index 96ea75e04582..a45213781ad0 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c @@ -546,33 +546,43 @@ void exit_thread(void) #endif } -void show_regs(struct pt_regs *regs) +void tile_show_regs(struct pt_regs *regs) { - struct task_struct *tsk = validate_current(); int i; - - if (tsk != &corrupt_current) - show_regs_print_info(KERN_ERR); #ifdef __tilegx__ for (i = 0; i < 17; i++) - pr_err(" r%-2d: " REGFMT " r%-2d: " REGFMT " r%-2d: " REGFMT "\n", + pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT" r%-2d: "REGFMT"\n", i, regs->regs[i], i+18, regs->regs[i+18], i+36, regs->regs[i+36]); - pr_err(" r17: " REGFMT " r35: " REGFMT " tp : " REGFMT "\n", + pr_err(" r17: "REGFMT" r35: "REGFMT" tp : "REGFMT"\n", regs->regs[17], regs->regs[35], regs->tp); - pr_err(" sp : " REGFMT " lr : " REGFMT "\n", regs->sp, regs->lr); + pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr); #else for (i = 0; i < 13; i++) - pr_err(" r%-2d: " REGFMT " r%-2d: " REGFMT " r%-2d: " REGFMT " r%-2d: " REGFMT "\n", + pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT + " r%-2d: "REGFMT" r%-2d: "REGFMT"\n", i, regs->regs[i], i+14, regs->regs[i+14], i+27, regs->regs[i+27], i+40, regs->regs[i+40]); - pr_err(" r13: " REGFMT " tp : " REGFMT " sp : " REGFMT " lr : " REGFMT "\n", + pr_err(" r13: "REGFMT" tp : "REGFMT" sp : "REGFMT" lr : "REGFMT"\n", regs->regs[13], regs->tp, regs->sp, regs->lr); #endif - pr_err(" pc : " REGFMT " ex1: %ld faultnum: %ld\n", - regs->pc, regs->ex1, regs->faultnum); + pr_err(" pc : "REGFMT" ex1: %ld faultnum: %ld flags:%s%s%s%s\n", + regs->pc, regs->ex1, regs->faultnum, + is_compat_task() ? " compat" : "", + (regs->flags & PT_FLAGS_DISABLE_IRQ) ? " noirq" : "", + !(regs->flags & PT_FLAGS_CALLER_SAVES) ? " nocallersave" : "", + (regs->flags & PT_FLAGS_RESTORE_REGS) ? " restoreregs" : ""); +} + +void show_regs(struct pt_regs *regs) +{ + struct KBacktraceIterator kbt; + + show_regs_print_info(KERN_DEFAULT); + tile_show_regs(regs); - dump_stack_regs(regs); + KBacktraceIterator_init(&kbt, NULL, regs); + tile_show_stack(&kbt); } /* To ensure stack dump on tiles occurs one by one. */ -- cgit v1.2.3