diff options
Diffstat (limited to 'arch/x86_64/kernel/traps.c')
-rw-r--r-- | arch/x86_64/kernel/traps.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 14052f089814..b1249774d1e8 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -107,7 +107,11 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) } static int kstack_depth_to_print = 12; +#ifdef CONFIG_STACK_UNWIND static int call_trace = 1; +#else +#define call_trace (-1) +#endif #ifdef CONFIG_KALLSYMS # include <linux/kallsyms.h> @@ -174,7 +178,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, break; #endif default: - end = per_cpu(init_tss, cpu).ist[k]; + end = per_cpu(orig_ist, cpu).ist[k]; break; } /* @@ -274,21 +278,21 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s if (unwind_init_blocked(&info, tsk) == 0) unw_ret = show_trace_unwind(&info, NULL); } - if (unw_ret > 0 && !arch_unw_user_mode(&info)) { -#ifdef CONFIG_STACK_UNWIND - unsigned long rip = info.regs.rip; - print_symbol("DWARF2 unwinder stuck at %s\n", rip); - if (call_trace == 1) { - printk("Leftover inexact backtrace:\n"); - stack = (unsigned long *)info.regs.rsp; - } else if (call_trace > 1) + if (unw_ret > 0) { + if (call_trace == 1 && !arch_unw_user_mode(&info)) { + print_symbol("DWARF2 unwinder stuck at %s\n", + UNW_PC(&info)); + if ((long)UNW_SP(&info) < 0) { + printk("Leftover inexact backtrace:\n"); + stack = (unsigned long *)UNW_SP(&info); + } else + printk("Full inexact backtrace again:\n"); + } else if (call_trace >= 1) return; else printk("Full inexact backtrace again:\n"); -#else + } else printk("Inexact backtrace:\n"); -#endif - } } /* @@ -1120,6 +1124,7 @@ static int __init kstack_setup(char *s) } __setup("kstack=", kstack_setup); +#ifdef CONFIG_STACK_UNWIND static int __init call_trace_setup(char *s) { if (strcmp(s, "old") == 0) @@ -1133,3 +1138,4 @@ static int __init call_trace_setup(char *s) return 1; } __setup("call_trace=", call_trace_setup); +#endif |