aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/pci-gart_64.c2
-rw-r--r--arch/x86/kernel/process_64.c4
-rw-r--r--arch/x86/kernel/stacktrace.c2
-rw-r--r--arch/x86/kernel/traps_32.c8
-rw-r--r--arch/x86/kernel/traps_64.c39
-rw-r--r--arch/x86/mm/fault_64.c2
-rw-r--r--arch/x86/oprofile/backtrace.c2
-rw-r--r--include/asm-x86/kdebug.h5
-rw-r--r--include/asm-x86/stacktrace.h5
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 d2b46b489412..04ca5c5221d7 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)
167 iommu_leak_pages); 167 iommu_leak_pages);
168 for (i = 0; i < iommu_leak_pages; i += 2) { 168 for (i = 0; i < iommu_leak_pages; i += 2) {
169 printk(KERN_DEBUG "%lu: ", iommu_pages-i); 169 printk(KERN_DEBUG "%lu: ", iommu_pages-i);
170 printk_address((unsigned long) iommu_leak_tab[iommu_pages-i]); 170 printk_address((unsigned long) iommu_leak_tab[iommu_pages-i], 0);
171 printk(KERN_CONT "%c", (i+1)%2 == 0 ? '\n' : ' '); 171 printk(KERN_CONT "%c", (i+1)%2 == 0 ? '\n' : ' ');
172 } 172 }
173 printk(KERN_DEBUG "\n"); 173 printk(KERN_DEBUG "\n");
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index a0130eb2fa50..383760bfd283 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)
329 (int)strcspn(init_utsname()->version, " "), 329 (int)strcspn(init_utsname()->version, " "),
330 init_utsname()->version); 330 init_utsname()->version);
331 printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); 331 printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
332 printk_address(regs->ip); 332 printk_address(regs->ip, regs->bp);
333 printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->sp, 333 printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->sp,
334 regs->flags); 334 regs->flags);
335 printk("RAX: %016lx RBX: %016lx RCX: %016lx\n", 335 printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
@@ -377,7 +377,7 @@ void show_regs(struct pt_regs *regs)
377{ 377{
378 printk("CPU %d:", smp_processor_id()); 378 printk("CPU %d:", smp_processor_id());
379 __show_regs(regs); 379 __show_regs(regs);
380 show_trace(NULL, regs, (void *)(regs + 1)); 380 show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
381} 381}
382 382
383/* 383/*
diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
index c571edd11878..8c4e4f5bf040 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)
22 return -1; 22 return -1;
23} 23}
24 24
25static void save_stack_address(void *data, unsigned long addr) 25static void save_stack_address(void *data, unsigned long addr, int reliable)
26{ 26{
27 struct stack_trace *trace = (struct stack_trace *)data; 27 struct stack_trace *trace = (struct stack_trace *)data;
28 if (trace->skip > 0) { 28 if (trace->skip > 0) {
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index acc9af260fac..8ef8a9ddfec6 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,
126 126
127 addr = frame->return_address; 127 addr = frame->return_address;
128 if (__kernel_text_address(addr)) 128 if (__kernel_text_address(addr))
129 ops->address(data, addr); 129 ops->address(data, addr, 1);
130 /* 130 /*
131 * break out of recursive entries (such as 131 * break out of recursive entries (such as
132 * end_of_stack_stop_unwind_function). Also, 132 * end_of_stack_stop_unwind_function). Also,
@@ -145,7 +145,7 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
145 145
146 addr = *stack++; 146 addr = *stack++;
147 if (__kernel_text_address(addr)) 147 if (__kernel_text_address(addr))
148 ops->address(data, addr); 148 ops->address(data, addr, 1);
149 } 149 }
150#endif 150#endif
151 return bp; 151 return bp;
@@ -220,9 +220,11 @@ static int print_trace_stack(void *data, char *name)
220/* 220/*
221 * Print one address/symbol entries per line. 221 * Print one address/symbol entries per line.
222 */ 222 */
223static void print_trace_address(void *data, unsigned long addr) 223static void print_trace_address(void *data, unsigned long addr, int reliable)
224{ 224{
225 printk("%s [<%08lx>] ", (char *)data, addr); 225 printk("%s [<%08lx>] ", (char *)data, addr);
226 if (!reliable)
227 printk("? ");
226 print_symbol("%s\n", addr); 228 print_symbol("%s\n", addr);
227 touch_nmi_watchdog(); 229 touch_nmi_watchdog();
228} 230}
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index 37b07d08704b..62c4d8f46ee9 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)
99int kstack_depth_to_print = 12; 99int kstack_depth_to_print = 12;
100 100
101#ifdef CONFIG_KALLSYMS 101#ifdef CONFIG_KALLSYMS
102void printk_address(unsigned long address) 102void printk_address(unsigned long address, int reliable)
103{ 103{
104 unsigned long offset = 0, symsize; 104 unsigned long offset = 0, symsize;
105 const char *symname; 105 const char *symname;
106 char *modname; 106 char *modname;
107 char *delim = ":"; 107 char *delim = ":";
108 char namebuf[128]; 108 char namebuf[128];
109 char reliab[4] = "";;
109 110
110 symname = kallsyms_lookup(address, &symsize, &offset, 111 symname = kallsyms_lookup(address, &symsize, &offset,
111 &modname, namebuf); 112 &modname, namebuf);
@@ -113,13 +114,16 @@ void printk_address(unsigned long address)
113 printk(" [<%016lx>]\n", address); 114 printk(" [<%016lx>]\n", address);
114 return; 115 return;
115 } 116 }
117 if (!reliable)
118 strcpy(reliab, "? ");
119
116 if (!modname) 120 if (!modname)
117 modname = delim = ""; 121 modname = delim = "";
118 printk(" [<%016lx>] %s%s%s%s+0x%lx/0x%lx\n", 122 printk(" [<%016lx>] %s%s%s%s%s+0x%lx/0x%lx\n",
119 address, delim, modname, delim, symname, offset, symsize); 123 address, reliab, delim, modname, delim, symname, offset, symsize);
120} 124}
121#else 125#else
122void printk_address(unsigned long address) 126void printk_address(unsigned long address, int reliable)
123{ 127{
124 printk(" [<%016lx>]\n", address); 128 printk(" [<%016lx>]\n", address);
125} 129}
@@ -215,7 +219,7 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
215} 219}
216 220
217void dump_trace(struct task_struct *tsk, struct pt_regs *regs, 221void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
218 unsigned long *stack, 222 unsigned long *stack, unsigned long bp,
219 const struct stacktrace_ops *ops, void *data) 223 const struct stacktrace_ops *ops, void *data)
220{ 224{
221 const unsigned cpu = get_cpu(); 225 const unsigned cpu = get_cpu();
@@ -252,7 +256,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
252 * down the cause of the crash will be able to figure \ 256 * down the cause of the crash will be able to figure \
253 * out the call path that was taken. \ 257 * out the call path that was taken. \
254 */ \ 258 */ \
255 ops->address(data, addr); \ 259 ops->address(data, addr, 1); \
256 } \ 260 } \
257 } while (0) 261 } while (0)
258 262
@@ -331,10 +335,10 @@ static int print_trace_stack(void *data, char *name)
331 return 0; 335 return 0;
332} 336}
333 337
334static void print_trace_address(void *data, unsigned long addr) 338static void print_trace_address(void *data, unsigned long addr, int reliable)
335{ 339{
336 touch_nmi_watchdog(); 340 touch_nmi_watchdog();
337 printk_address(addr); 341 printk_address(addr, reliable);
338} 342}
339 343
340static const struct stacktrace_ops print_trace_ops = { 344static const struct stacktrace_ops print_trace_ops = {
@@ -345,15 +349,17 @@ static const struct stacktrace_ops print_trace_ops = {
345}; 349};
346 350
347void 351void
348show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack) 352show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack,
353 unsigned long bp)
349{ 354{
350 printk("\nCall Trace:\n"); 355 printk("\nCall Trace:\n");
351 dump_trace(tsk, regs, stack, &print_trace_ops, NULL); 356 dump_trace(tsk, regs, stack, bp, &print_trace_ops, NULL);
352 printk("\n"); 357 printk("\n");
353} 358}
354 359
355static void 360static void
356_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp) 361_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp,
362 unsigned long bp)
357{ 363{
358 unsigned long *stack; 364 unsigned long *stack;
359 int i; 365 int i;
@@ -387,12 +393,12 @@ _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp)
387 printk(" %016lx", *stack++); 393 printk(" %016lx", *stack++);
388 touch_nmi_watchdog(); 394 touch_nmi_watchdog();
389 } 395 }
390 show_trace(tsk, regs, sp); 396 show_trace(tsk, regs, sp, bp);
391} 397}
392 398
393void show_stack(struct task_struct *tsk, unsigned long * sp) 399void show_stack(struct task_struct *tsk, unsigned long * sp)
394{ 400{
395 _show_stack(tsk, NULL, sp); 401 _show_stack(tsk, NULL, sp, 0);
396} 402}
397 403
398/* 404/*
@@ -401,13 +407,14 @@ void show_stack(struct task_struct *tsk, unsigned long * sp)
401void dump_stack(void) 407void dump_stack(void)
402{ 408{
403 unsigned long dummy; 409 unsigned long dummy;
410 unsigned long bp = 0;
404 411
405 printk("Pid: %d, comm: %.20s %s %s %.*s\n", 412 printk("Pid: %d, comm: %.20s %s %s %.*s\n",
406 current->pid, current->comm, print_tainted(), 413 current->pid, current->comm, print_tainted(),
407 init_utsname()->release, 414 init_utsname()->release,
408 (int)strcspn(init_utsname()->version, " "), 415 (int)strcspn(init_utsname()->version, " "),
409 init_utsname()->version); 416 init_utsname()->version);
410 show_trace(NULL, NULL, &dummy); 417 show_trace(NULL, NULL, &dummy, bp);
411} 418}
412 419
413EXPORT_SYMBOL(dump_stack); 420EXPORT_SYMBOL(dump_stack);
@@ -432,7 +439,7 @@ void show_registers(struct pt_regs *regs)
432 */ 439 */
433 if (in_kernel) { 440 if (in_kernel) {
434 printk("Stack: "); 441 printk("Stack: ");
435 _show_stack(NULL, regs, (unsigned long*)sp); 442 _show_stack(NULL, regs, (unsigned long *)sp, regs->bp);
436 443
437 printk("\nCode: "); 444 printk("\nCode: ");
438 if (regs->ip < PAGE_OFFSET) 445 if (regs->ip < PAGE_OFFSET)
@@ -527,7 +534,7 @@ int __kprobes __die(const char * str, struct pt_regs * regs, long err)
527 add_taint(TAINT_DIE); 534 add_taint(TAINT_DIE);
528 /* Executive summary in case the oops scrolled away */ 535 /* Executive summary in case the oops scrolled away */
529 printk(KERN_ALERT "RIP "); 536 printk(KERN_ALERT "RIP ");
530 printk_address(regs->ip); 537 printk_address(regs->ip, regs->bp);
531 printk(" RSP <%016lx>\n", regs->sp); 538 printk(" RSP <%016lx>\n", regs->sp);
532 if (kexec_should_crash(current)) 539 if (kexec_should_crash(current))
533 crash_kexec(regs); 540 crash_kexec(regs);
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c
index e82832961d72..cf7e99895b91 100644
--- a/arch/x86/mm/fault_64.c
+++ b/arch/x86/mm/fault_64.c
@@ -578,7 +578,7 @@ no_context:
578 else 578 else
579 printk(KERN_ALERT "Unable to handle kernel paging request"); 579 printk(KERN_ALERT "Unable to handle kernel paging request");
580 printk(" at %016lx RIP: \n" KERN_ALERT, address); 580 printk(" at %016lx RIP: \n" KERN_ALERT, address);
581 printk_address(regs->ip); 581 printk_address(regs->ip, regs->bp);
582 dump_pagetable(address); 582 dump_pagetable(address);
583 tsk->thread.cr2 = address; 583 tsk->thread.cr2 = address;
584 tsk->thread.trap_no = 14; 584 tsk->thread.trap_no = 14;
diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c
index cc353a0b183e..671a7ecf11aa 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)
32 return 0; 32 return 0;
33} 33}
34 34
35static void backtrace_address(void *data, unsigned long addr) 35static void backtrace_address(void *data, unsigned long addr, int reliable)
36{ 36{
37 unsigned int *depth = data; 37 unsigned int *depth = data;
38 38
diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h
index e9f42d1ac38f..dd442a1632c0 100644
--- a/include/asm-x86/kdebug.h
+++ b/include/asm-x86/kdebug.h
@@ -22,12 +22,13 @@ enum die_val {
22 DIE_PAGE_FAULT, 22 DIE_PAGE_FAULT,
23}; 23};
24 24
25extern void printk_address(unsigned long address); 25extern void printk_address(unsigned long address, int reliable);
26extern void die(const char *,struct pt_regs *,long); 26extern void die(const char *,struct pt_regs *,long);
27extern int __must_check __die(const char *, struct pt_regs *, long); 27extern int __must_check __die(const char *, struct pt_regs *, long);
28extern void show_registers(struct pt_regs *regs); 28extern void show_registers(struct pt_regs *regs);
29extern void __show_registers(struct pt_regs *, int all); 29extern void __show_registers(struct pt_regs *, int all);
30extern void show_trace(struct task_struct *, struct pt_regs *, unsigned long *); 30extern void show_trace(struct task_struct *t, struct pt_regs *regs,
31 unsigned long *sp, unsigned long bp);
31extern void __show_regs(struct pt_regs *regs); 32extern void __show_regs(struct pt_regs *regs);
32extern void show_regs(struct pt_regs *regs); 33extern void show_regs(struct pt_regs *regs);
33extern void dump_pagetable(unsigned long); 34extern void dump_pagetable(unsigned long);
diff --git a/include/asm-x86/stacktrace.h b/include/asm-x86/stacktrace.h
index 70dd5bae3235..30f82526a8e2 100644
--- a/include/asm-x86/stacktrace.h
+++ b/include/asm-x86/stacktrace.h
@@ -9,12 +9,13 @@ struct stacktrace_ops {
9 void (*warning)(void *data, char *msg); 9 void (*warning)(void *data, char *msg);
10 /* msg must contain %s for the symbol */ 10 /* msg must contain %s for the symbol */
11 void (*warning_symbol)(void *data, char *msg, unsigned long symbol); 11 void (*warning_symbol)(void *data, char *msg, unsigned long symbol);
12 void (*address)(void *data, unsigned long address); 12 void (*address)(void *data, unsigned long address, int reliable);
13 /* On negative return stop dumping */ 13 /* On negative return stop dumping */
14 int (*stack)(void *data, char *name); 14 int (*stack)(void *data, char *name);
15}; 15};
16 16
17void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack, 17void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
18 unsigned long *stack, unsigned long bp,
18 const struct stacktrace_ops *ops, void *data); 19 const struct stacktrace_ops *ops, void *data);
19 20
20#endif 21#endif