diff options
-rw-r--r-- | arch/x86/include/asm/kdebug.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/stacktrace.h | 6 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/dumpstack.c | 14 | ||||
-rw-r--r-- | arch/x86/kernel/dumpstack_32.c | 15 | ||||
-rw-r--r-- | arch/x86/kernel/dumpstack_64.c | 14 | ||||
-rw-r--r-- | arch/x86/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/stacktrace.c | 6 | ||||
-rw-r--r-- | arch/x86/oprofile/backtrace.c | 2 |
9 files changed, 33 insertions, 30 deletions
diff --git a/arch/x86/include/asm/kdebug.h b/arch/x86/include/asm/kdebug.h index 518bbbb9ee59..fe2cc6e105fa 100644 --- a/arch/x86/include/asm/kdebug.h +++ b/arch/x86/include/asm/kdebug.h | |||
@@ -26,7 +26,7 @@ extern void die(const char *, struct pt_regs *,long); | |||
26 | extern int __must_check __die(const char *, struct pt_regs *, long); | 26 | extern int __must_check __die(const char *, struct pt_regs *, long); |
27 | extern void show_registers(struct pt_regs *regs); | 27 | extern void show_registers(struct pt_regs *regs); |
28 | extern void show_trace(struct task_struct *t, struct pt_regs *regs, | 28 | extern void show_trace(struct task_struct *t, struct pt_regs *regs, |
29 | unsigned long *sp); | 29 | unsigned long *sp, unsigned long bp); |
30 | extern void __show_regs(struct pt_regs *regs, int all); | 30 | extern void __show_regs(struct pt_regs *regs, int all); |
31 | extern void show_regs(struct pt_regs *regs); | 31 | extern void show_regs(struct pt_regs *regs); |
32 | extern unsigned long oops_begin(void); | 32 | extern unsigned long oops_begin(void); |
diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h index 52b5c7ed3608..d7e89c83645d 100644 --- a/arch/x86/include/asm/stacktrace.h +++ b/arch/x86/include/asm/stacktrace.h | |||
@@ -47,7 +47,7 @@ struct stacktrace_ops { | |||
47 | }; | 47 | }; |
48 | 48 | ||
49 | void dump_trace(struct task_struct *tsk, struct pt_regs *regs, | 49 | void dump_trace(struct task_struct *tsk, struct pt_regs *regs, |
50 | unsigned long *stack, | 50 | unsigned long *stack, unsigned long bp, |
51 | const struct stacktrace_ops *ops, void *data); | 51 | const struct stacktrace_ops *ops, void *data); |
52 | 52 | ||
53 | #ifdef CONFIG_X86_32 | 53 | #ifdef CONFIG_X86_32 |
@@ -86,11 +86,11 @@ stack_frame(struct task_struct *task, struct pt_regs *regs) | |||
86 | 86 | ||
87 | extern void | 87 | extern void |
88 | show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | 88 | show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, |
89 | unsigned long *stack, char *log_lvl); | 89 | unsigned long *stack, unsigned long bp, char *log_lvl); |
90 | 90 | ||
91 | extern void | 91 | extern void |
92 | show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | 92 | show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, |
93 | unsigned long *sp, char *log_lvl); | 93 | unsigned long *sp, unsigned long bp, char *log_lvl); |
94 | 94 | ||
95 | extern unsigned int code_bytes; | 95 | extern unsigned int code_bytes; |
96 | 96 | ||
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 279bc9de1cc7..30612764cd3b 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -1792,7 +1792,7 @@ perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) | |||
1792 | 1792 | ||
1793 | perf_callchain_store(entry, regs->ip); | 1793 | perf_callchain_store(entry, regs->ip); |
1794 | 1794 | ||
1795 | dump_trace(NULL, regs, NULL, &backtrace_ops, entry); | 1795 | dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry); |
1796 | } | 1796 | } |
1797 | 1797 | ||
1798 | #ifdef CONFIG_COMPAT | 1798 | #ifdef CONFIG_COMPAT |
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 220a1c11cfde..999e2793590b 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c | |||
@@ -175,21 +175,21 @@ static const struct stacktrace_ops print_trace_ops = { | |||
175 | 175 | ||
176 | void | 176 | void |
177 | show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | 177 | show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, |
178 | unsigned long *stack, char *log_lvl) | 178 | unsigned long *stack, unsigned long bp, char *log_lvl) |
179 | { | 179 | { |
180 | printk("%sCall Trace:\n", log_lvl); | 180 | printk("%sCall Trace:\n", log_lvl); |
181 | dump_trace(task, regs, stack, &print_trace_ops, log_lvl); | 181 | dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl); |
182 | } | 182 | } |
183 | 183 | ||
184 | void show_trace(struct task_struct *task, struct pt_regs *regs, | 184 | void show_trace(struct task_struct *task, struct pt_regs *regs, |
185 | unsigned long *stack) | 185 | unsigned long *stack, unsigned long bp) |
186 | { | 186 | { |
187 | show_trace_log_lvl(task, regs, stack, ""); | 187 | show_trace_log_lvl(task, regs, stack, bp, ""); |
188 | } | 188 | } |
189 | 189 | ||
190 | void show_stack(struct task_struct *task, unsigned long *sp) | 190 | void show_stack(struct task_struct *task, unsigned long *sp) |
191 | { | 191 | { |
192 | show_stack_log_lvl(task, NULL, sp, ""); | 192 | show_stack_log_lvl(task, NULL, sp, 0, ""); |
193 | } | 193 | } |
194 | 194 | ||
195 | /* | 195 | /* |
@@ -197,14 +197,16 @@ void show_stack(struct task_struct *task, unsigned long *sp) | |||
197 | */ | 197 | */ |
198 | void dump_stack(void) | 198 | void dump_stack(void) |
199 | { | 199 | { |
200 | unsigned long bp; | ||
200 | unsigned long stack; | 201 | unsigned long stack; |
201 | 202 | ||
203 | bp = stack_frame(current, NULL); | ||
202 | printk("Pid: %d, comm: %.20s %s %s %.*s\n", | 204 | printk("Pid: %d, comm: %.20s %s %s %.*s\n", |
203 | current->pid, current->comm, print_tainted(), | 205 | current->pid, current->comm, print_tainted(), |
204 | init_utsname()->release, | 206 | init_utsname()->release, |
205 | (int)strcspn(init_utsname()->version, " "), | 207 | (int)strcspn(init_utsname()->version, " "), |
206 | init_utsname()->version); | 208 | init_utsname()->version); |
207 | show_trace(NULL, NULL, &stack); | 209 | show_trace(NULL, NULL, &stack, bp); |
208 | } | 210 | } |
209 | EXPORT_SYMBOL(dump_stack); | 211 | EXPORT_SYMBOL(dump_stack); |
210 | 212 | ||
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index 74cc1eda384b..3b97a80ce329 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
@@ -17,12 +17,11 @@ | |||
17 | #include <asm/stacktrace.h> | 17 | #include <asm/stacktrace.h> |
18 | 18 | ||
19 | 19 | ||
20 | void dump_trace(struct task_struct *task, | 20 | void dump_trace(struct task_struct *task, struct pt_regs *regs, |
21 | struct pt_regs *regs, unsigned long *stack, | 21 | unsigned long *stack, unsigned long bp, |
22 | const struct stacktrace_ops *ops, void *data) | 22 | const struct stacktrace_ops *ops, void *data) |
23 | { | 23 | { |
24 | int graph = 0; | 24 | int graph = 0; |
25 | unsigned long bp; | ||
26 | 25 | ||
27 | if (!task) | 26 | if (!task) |
28 | task = current; | 27 | task = current; |
@@ -35,7 +34,9 @@ void dump_trace(struct task_struct *task, | |||
35 | stack = (unsigned long *)task->thread.sp; | 34 | stack = (unsigned long *)task->thread.sp; |
36 | } | 35 | } |
37 | 36 | ||
38 | bp = stack_frame(task, regs); | 37 | if (!bp) |
38 | bp = stack_frame(task, regs); | ||
39 | |||
39 | for (;;) { | 40 | for (;;) { |
40 | struct thread_info *context; | 41 | struct thread_info *context; |
41 | 42 | ||
@@ -55,7 +56,7 @@ EXPORT_SYMBOL(dump_trace); | |||
55 | 56 | ||
56 | void | 57 | void |
57 | show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | 58 | show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, |
58 | unsigned long *sp, char *log_lvl) | 59 | unsigned long *sp, unsigned long bp, char *log_lvl) |
59 | { | 60 | { |
60 | unsigned long *stack; | 61 | unsigned long *stack; |
61 | int i; | 62 | int i; |
@@ -77,7 +78,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
77 | touch_nmi_watchdog(); | 78 | touch_nmi_watchdog(); |
78 | } | 79 | } |
79 | printk(KERN_CONT "\n"); | 80 | printk(KERN_CONT "\n"); |
80 | show_trace_log_lvl(task, regs, sp, log_lvl); | 81 | show_trace_log_lvl(task, regs, sp, bp, log_lvl); |
81 | } | 82 | } |
82 | 83 | ||
83 | 84 | ||
@@ -102,7 +103,7 @@ void show_registers(struct pt_regs *regs) | |||
102 | u8 *ip; | 103 | u8 *ip; |
103 | 104 | ||
104 | printk(KERN_EMERG "Stack:\n"); | 105 | printk(KERN_EMERG "Stack:\n"); |
105 | show_stack_log_lvl(NULL, regs, ®s->sp, KERN_EMERG); | 106 | show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG); |
106 | 107 | ||
107 | printk(KERN_EMERG "Code: "); | 108 | printk(KERN_EMERG "Code: "); |
108 | 109 | ||
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index a6b6fcf7f0ae..e71c98d3c0d2 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
@@ -139,8 +139,8 @@ fixup_bp_irq_link(unsigned long bp, unsigned long *stack, | |||
139 | * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack | 139 | * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack |
140 | */ | 140 | */ |
141 | 141 | ||
142 | void dump_trace(struct task_struct *task, | 142 | void dump_trace(struct task_struct *task, struct pt_regs *regs, |
143 | struct pt_regs *regs, unsigned long *stack, | 143 | unsigned long *stack, unsigned long bp, |
144 | const struct stacktrace_ops *ops, void *data) | 144 | const struct stacktrace_ops *ops, void *data) |
145 | { | 145 | { |
146 | const unsigned cpu = get_cpu(); | 146 | const unsigned cpu = get_cpu(); |
@@ -150,7 +150,6 @@ void dump_trace(struct task_struct *task, | |||
150 | struct thread_info *tinfo; | 150 | struct thread_info *tinfo; |
151 | int graph = 0; | 151 | int graph = 0; |
152 | unsigned long dummy; | 152 | unsigned long dummy; |
153 | unsigned long bp; | ||
154 | 153 | ||
155 | if (!task) | 154 | if (!task) |
156 | task = current; | 155 | task = current; |
@@ -161,7 +160,8 @@ void dump_trace(struct task_struct *task, | |||
161 | stack = (unsigned long *)task->thread.sp; | 160 | stack = (unsigned long *)task->thread.sp; |
162 | } | 161 | } |
163 | 162 | ||
164 | bp = stack_frame(task, regs); | 163 | if (!bp) |
164 | bp = stack_frame(task, regs); | ||
165 | /* | 165 | /* |
166 | * Print function call entries in all stacks, starting at the | 166 | * Print function call entries in all stacks, starting at the |
167 | * current stack address. If the stacks consist of nested | 167 | * current stack address. If the stacks consist of nested |
@@ -225,7 +225,7 @@ EXPORT_SYMBOL(dump_trace); | |||
225 | 225 | ||
226 | void | 226 | void |
227 | show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | 227 | show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, |
228 | unsigned long *sp, char *log_lvl) | 228 | unsigned long *sp, unsigned long bp, char *log_lvl) |
229 | { | 229 | { |
230 | unsigned long *irq_stack_end; | 230 | unsigned long *irq_stack_end; |
231 | unsigned long *irq_stack; | 231 | unsigned long *irq_stack; |
@@ -269,7 +269,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
269 | preempt_enable(); | 269 | preempt_enable(); |
270 | 270 | ||
271 | printk(KERN_CONT "\n"); | 271 | printk(KERN_CONT "\n"); |
272 | show_trace_log_lvl(task, regs, sp, log_lvl); | 272 | show_trace_log_lvl(task, regs, sp, bp, log_lvl); |
273 | } | 273 | } |
274 | 274 | ||
275 | void show_registers(struct pt_regs *regs) | 275 | void show_registers(struct pt_regs *regs) |
@@ -298,7 +298,7 @@ void show_registers(struct pt_regs *regs) | |||
298 | 298 | ||
299 | printk(KERN_EMERG "Stack:\n"); | 299 | printk(KERN_EMERG "Stack:\n"); |
300 | show_stack_log_lvl(NULL, regs, (unsigned long *)sp, | 300 | show_stack_log_lvl(NULL, regs, (unsigned long *)sp, |
301 | KERN_EMERG); | 301 | 0, KERN_EMERG); |
302 | 302 | ||
303 | printk(KERN_EMERG "Code: "); | 303 | printk(KERN_EMERG "Code: "); |
304 | 304 | ||
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 99fa3adf0141..d46cbe46b7ab 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -87,7 +87,7 @@ void exit_thread(void) | |||
87 | void show_regs(struct pt_regs *regs) | 87 | void show_regs(struct pt_regs *regs) |
88 | { | 88 | { |
89 | show_registers(regs); | 89 | show_registers(regs); |
90 | show_trace(NULL, regs, (unsigned long *)kernel_stack_pointer(regs)); | 90 | show_trace(NULL, regs, (unsigned long *)kernel_stack_pointer(regs), 0); |
91 | } | 91 | } |
92 | 92 | ||
93 | void show_regs_common(void) | 93 | void show_regs_common(void) |
diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c index 938c8e10a19a..6515733a289d 100644 --- a/arch/x86/kernel/stacktrace.c +++ b/arch/x86/kernel/stacktrace.c | |||
@@ -73,7 +73,7 @@ static const struct stacktrace_ops save_stack_ops_nosched = { | |||
73 | */ | 73 | */ |
74 | void save_stack_trace(struct stack_trace *trace) | 74 | void save_stack_trace(struct stack_trace *trace) |
75 | { | 75 | { |
76 | dump_trace(current, NULL, NULL, &save_stack_ops, trace); | 76 | dump_trace(current, NULL, NULL, 0, &save_stack_ops, trace); |
77 | if (trace->nr_entries < trace->max_entries) | 77 | if (trace->nr_entries < trace->max_entries) |
78 | trace->entries[trace->nr_entries++] = ULONG_MAX; | 78 | trace->entries[trace->nr_entries++] = ULONG_MAX; |
79 | } | 79 | } |
@@ -81,14 +81,14 @@ EXPORT_SYMBOL_GPL(save_stack_trace); | |||
81 | 81 | ||
82 | void save_stack_trace_regs(struct stack_trace *trace, struct pt_regs *regs) | 82 | void save_stack_trace_regs(struct stack_trace *trace, struct pt_regs *regs) |
83 | { | 83 | { |
84 | dump_trace(current, regs, NULL, &save_stack_ops, trace); | 84 | dump_trace(current, regs, NULL, 0, &save_stack_ops, trace); |
85 | if (trace->nr_entries < trace->max_entries) | 85 | if (trace->nr_entries < trace->max_entries) |
86 | trace->entries[trace->nr_entries++] = ULONG_MAX; | 86 | trace->entries[trace->nr_entries++] = ULONG_MAX; |
87 | } | 87 | } |
88 | 88 | ||
89 | void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) | 89 | void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) |
90 | { | 90 | { |
91 | dump_trace(tsk, NULL, NULL, &save_stack_ops_nosched, trace); | 91 | dump_trace(tsk, NULL, NULL, 0, &save_stack_ops_nosched, trace); |
92 | if (trace->nr_entries < trace->max_entries) | 92 | if (trace->nr_entries < trace->max_entries) |
93 | trace->entries[trace->nr_entries++] = ULONG_MAX; | 93 | trace->entries[trace->nr_entries++] = ULONG_MAX; |
94 | } | 94 | } |
diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c index 72cbec14d783..2d49d4e19a36 100644 --- a/arch/x86/oprofile/backtrace.c +++ b/arch/x86/oprofile/backtrace.c | |||
@@ -126,7 +126,7 @@ x86_backtrace(struct pt_regs * const regs, unsigned int depth) | |||
126 | if (!user_mode_vm(regs)) { | 126 | if (!user_mode_vm(regs)) { |
127 | unsigned long stack = kernel_stack_pointer(regs); | 127 | unsigned long stack = kernel_stack_pointer(regs); |
128 | if (depth) | 128 | if (depth) |
129 | dump_trace(NULL, regs, (unsigned long *)stack, | 129 | dump_trace(NULL, regs, (unsigned long *)stack, 0, |
130 | &backtrace_ops, &depth); | 130 | &backtrace_ops, &depth); |
131 | return; | 131 | return; |
132 | } | 132 | } |