diff options
-rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/process_64.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/stacktrace.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/traps_32.c | 8 | ||||
-rw-r--r-- | arch/x86/kernel/traps_64.c | 39 | ||||
-rw-r--r-- | arch/x86/mm/fault_64.c | 2 | ||||
-rw-r--r-- | arch/x86/oprofile/backtrace.c | 2 | ||||
-rw-r--r-- | include/asm-x86/kdebug.h | 5 | ||||
-rw-r--r-- | include/asm-x86/stacktrace.h | 5 |
9 files changed, 40 insertions, 29 deletions
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index d2b46b48941..04ca5c5221d 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -167,7 +167,7 @@ static void dump_leak(void) iommu_leak_pages); for (i = 0; i < iommu_leak_pages; i += 2) { printk(KERN_DEBUG "%lu: ", iommu_pages-i); - printk_address((unsigned long) iommu_leak_tab[iommu_pages-i]); + printk_address((unsigned long) iommu_leak_tab[iommu_pages-i], 0); printk(KERN_CONT "%c", (i+1)%2 == 0 ? '\n' : ' '); } printk(KERN_DEBUG "\n"); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index a0130eb2fa5..383760bfd28 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -329,7 +329,7 @@ void __show_regs(struct pt_regs * regs) (int)strcspn(init_utsname()->version, " "), init_utsname()->version); printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); - printk_address(regs->ip); + printk_address(regs->ip, regs->bp); printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->sp, regs->flags); printk("RAX: %016lx RBX: %016lx RCX: %016lx\n", @@ -377,7 +377,7 @@ void show_regs(struct pt_regs *regs) { printk("CPU %d:", smp_processor_id()); __show_regs(regs); - show_trace(NULL, regs, (void *)(regs + 1)); + show_trace(NULL, regs, (void *)(regs + 1), regs->bp); } /* diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c index c571edd1187..8c4e4f5bf04 100644 --- a/arch/x86/kernel/stacktrace.c +++ b/arch/x86/kernel/stacktrace.c @@ -22,7 +22,7 @@ static int save_stack_stack(void *data, char *name) return -1; } -static void save_stack_address(void *data, unsigned long addr) +static void save_stack_address(void *data, unsigned long addr, int reliable) { struct stack_trace *trace = (struct stack_trace *)data; if (trace->skip > 0) { diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index acc9af260fa..8ef8a9ddfec 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c @@ -126,7 +126,7 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, addr = frame->return_address; if (__kernel_text_address(addr)) - ops->address(data, addr); + ops->address(data, addr, 1); /* * break out of recursive entries (such as * end_of_stack_stop_unwind_function). Also, @@ -145,7 +145,7 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, addr = *stack++; if (__kernel_text_address(addr)) - ops->address(data, addr); + ops->address(data, addr, 1); } #endif return bp; @@ -220,9 +220,11 @@ static int print_trace_stack(void *data, char *name) /* * Print one address/symbol entries per line. */ -static void print_trace_address(void *data, unsigned long addr) +static void print_trace_address(void *data, unsigned long addr, int reliable) { printk("%s [<%08lx>] ", (char *)data, addr); + if (!reliable) + printk("? "); print_symbol("%s\n", addr); touch_nmi_watchdog(); } diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 37b07d08704..62c4d8f46ee 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c @@ -99,13 +99,14 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) int kstack_depth_to_print = 12; #ifdef CONFIG_KALLSYMS -void printk_address(unsigned long address) +void printk_address(unsigned long address, int reliable) { unsigned long offset = 0, symsize; const char *symname; char *modname; char *delim = ":"; char namebuf[128]; + char reliab[4] = "";; symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); @@ -113,13 +114,16 @@ void printk_address(unsigned long address) printk(" [<%016lx>]\n", address); return; } + if (!reliable) + strcpy(reliab, "? "); + if (!modname) modname = delim = ""; - printk(" [<%016lx>] %s%s%s%s+0x%lx/0x%lx\n", - address, delim, modname, delim, symname, offset, symsize); + printk(" [<%016lx>] %s%s%s%s%s+0x%lx/0x%lx\n", + address, reliab, delim, modname, delim, symname, offset, symsize); } #else -void printk_address(unsigned long address) +void printk_address(unsigned long address, int reliable) { printk(" [<%016lx>]\n", address); } @@ -215,7 +219,7 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) } void dump_trace(struct task_struct *tsk, struct pt_regs *regs, - unsigned long *stack, + unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data) { const unsigned cpu = get_cpu(); @@ -252,7 +256,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, * down the cause of the crash will be able to figure \ * out the call path that was taken. \ */ \ - ops->address(data, addr); \ + ops->address(data, addr, 1); \ } \ } while (0) @@ -331,10 +335,10 @@ static int print_trace_stack(void *data, char *name) return 0; } -static void print_trace_address(void *data, unsigned long addr) +static void print_trace_address(void *data, unsigned long addr, int reliable) { touch_nmi_watchdog(); - printk_address(addr); + printk_address(addr, reliable); } static const struct stacktrace_ops print_trace_ops = { @@ -345,15 +349,17 @@ static const struct stacktrace_ops print_trace_ops = { }; void -show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack) +show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack, + unsigned long bp) { printk("\nCall Trace:\n"); - dump_trace(tsk, regs, stack, &print_trace_ops, NULL); + dump_trace(tsk, regs, stack, bp, &print_trace_ops, NULL); printk("\n"); } static void -_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp) +_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp, + unsigned long bp) { unsigned long *stack; int i; @@ -387,12 +393,12 @@ _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp) printk(" %016lx", *stack++); touch_nmi_watchdog(); } - show_trace(tsk, regs, sp); + show_trace(tsk, regs, sp, bp); } void show_stack(struct task_struct *tsk, unsigned long * sp) { - _show_stack(tsk, NULL, sp); + _show_stack(tsk, NULL, sp, 0); } /* @@ -401,13 +407,14 @@ void show_stack(struct task_struct *tsk, unsigned long * sp) void dump_stack(void) { unsigned long dummy; + unsigned long bp = 0; printk("Pid: %d, comm: %.20s %s %s %.*s\n", current->pid, current->comm, print_tainted(), init_utsname()->release, (int)strcspn(init_utsname()->version, " "), init_utsname()->version); - show_trace(NULL, NULL, &dummy); + show_trace(NULL, NULL, &dummy, bp); } EXPORT_SYMBOL(dump_stack); @@ -432,7 +439,7 @@ void show_registers(struct pt_regs *regs) */ if (in_kernel) { printk("Stack: "); - _show_stack(NULL, regs, (unsigned long*)sp); + _show_stack(NULL, regs, (unsigned long *)sp, regs->bp); printk("\nCode: "); if (regs->ip < PAGE_OFFSET) @@ -527,7 +534,7 @@ int __kprobes __die(const char * str, struct pt_regs * regs, long err) add_taint(TAINT_DIE); /* Executive summary in case the oops scrolled away */ printk(KERN_ALERT "RIP "); - printk_address(regs->ip); + printk_address(regs->ip, regs->bp); printk(" RSP <%016lx>\n", regs->sp); if (kexec_should_crash(current)) crash_kexec(regs); diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c index e82832961d7..cf7e99895b9 100644 --- a/arch/x86/mm/fault_64.c +++ b/arch/x86/mm/fault_64.c @@ -578,7 +578,7 @@ no_context: else printk(KERN_ALERT "Unable to handle kernel paging request"); printk(" at %016lx RIP: \n" KERN_ALERT, address); - printk_address(regs->ip); + printk_address(regs->ip, regs->bp); dump_pagetable(address); tsk->thread.cr2 = address; tsk->thread.trap_no = 14; diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c index cc353a0b183..671a7ecf11a 100644 --- a/arch/x86/oprofile/backtrace.c +++ b/arch/x86/oprofile/backtrace.c @@ -32,7 +32,7 @@ static int backtrace_stack(void *data, char *name) return 0; } -static void backtrace_address(void *data, unsigned long addr) +static void backtrace_address(void *data, unsigned long addr, int reliable) { unsigned int *depth = data; diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h index e9f42d1ac38..dd442a1632c 100644 --- a/include/asm-x86/kdebug.h +++ b/include/asm-x86/kdebug.h @@ -22,12 +22,13 @@ enum die_val { DIE_PAGE_FAULT, }; -extern void printk_address(unsigned long address); +extern void printk_address(unsigned long address, int reliable); extern void die(const char *,struct pt_regs *,long); extern int __must_check __die(const char *, struct pt_regs *, long); extern void show_registers(struct pt_regs *regs); extern void __show_registers(struct pt_regs *, int all); -extern void show_trace(struct task_struct *, struct pt_regs *, unsigned long *); +extern void show_trace(struct task_struct *t, struct pt_regs *regs, + unsigned long *sp, unsigned long bp); extern void __show_regs(struct pt_regs *regs); extern void show_regs(struct pt_regs *regs); extern void dump_pagetable(unsigned long); diff --git a/include/asm-x86/stacktrace.h b/include/asm-x86/stacktrace.h index 70dd5bae323..30f82526a8e 100644 --- a/include/asm-x86/stacktrace.h +++ b/include/asm-x86/stacktrace.h @@ -9,12 +9,13 @@ struct stacktrace_ops { void (*warning)(void *data, char *msg); /* msg must contain %s for the symbol */ void (*warning_symbol)(void *data, char *msg, unsigned long symbol); - void (*address)(void *data, unsigned long address); + void (*address)(void *data, unsigned long address, int reliable); /* On negative return stop dumping */ int (*stack)(void *data, char *name); }; -void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack, +void dump_trace(struct task_struct *tsk, struct pt_regs *regs, + unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data); #endif |