diff options
author | Jesper Nilsson <jespern@axis.com> | 2014-10-08 08:57:35 -0400 |
---|---|---|
committer | Jesper Nilsson <jespern@axis.com> | 2014-12-19 18:05:36 -0500 |
commit | 421d085252613c4caf9c4f2fda3c722a9f5bc554 (patch) | |
tree | fc3e9c8ddfc48a019950154d4ce6fe12f2524dbf /arch | |
parent | ca36c1faddb48c478f7f8944b9b900fc72629310 (diff) |
CRIS: Use KALLSYMs if available in call stack dump
Also, print kernel version on oops.
Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/cris/kernel/traps.c | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/arch/cris/kernel/traps.c b/arch/cris/kernel/traps.c index 0ffda73734f5..da4c72401e27 100644 --- a/arch/cris/kernel/traps.c +++ b/arch/cris/kernel/traps.c | |||
@@ -14,6 +14,10 @@ | |||
14 | 14 | ||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/utsname.h> | ||
18 | #ifdef CONFIG_KALLSYMS | ||
19 | #include <linux/kallsyms.h> | ||
20 | #endif | ||
17 | 21 | ||
18 | #include <asm/pgtable.h> | 22 | #include <asm/pgtable.h> |
19 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
@@ -34,25 +38,24 @@ static int kstack_depth_to_print = 24; | |||
34 | 38 | ||
35 | void (*nmi_handler)(struct pt_regs *); | 39 | void (*nmi_handler)(struct pt_regs *); |
36 | 40 | ||
37 | void | 41 | void show_trace(unsigned long *stack) |
38 | show_trace(unsigned long *stack) | ||
39 | { | 42 | { |
40 | unsigned long addr, module_start, module_end; | 43 | unsigned long addr, module_start, module_end; |
41 | extern char _stext, _etext; | 44 | extern char _stext, _etext; |
42 | int i; | 45 | int i; |
43 | 46 | ||
44 | printk("\nCall Trace: "); | 47 | pr_err("\nCall Trace: "); |
45 | 48 | ||
46 | i = 1; | 49 | i = 1; |
47 | module_start = VMALLOC_START; | 50 | module_start = VMALLOC_START; |
48 | module_end = VMALLOC_END; | 51 | module_end = VMALLOC_END; |
49 | 52 | ||
50 | while (((long)stack & (THREAD_SIZE-1)) != 0) { | 53 | while (((long)stack & (THREAD_SIZE - 1)) != 0) { |
51 | if (__get_user(addr, stack)) { | 54 | if (__get_user(addr, stack)) { |
52 | /* This message matches "failing address" marked | 55 | /* This message matches "failing address" marked |
53 | s390 in ksymoops, so lines containing it will | 56 | s390 in ksymoops, so lines containing it will |
54 | not be filtered out by ksymoops. */ | 57 | not be filtered out by ksymoops. */ |
55 | printk("Failing address 0x%lx\n", (unsigned long)stack); | 58 | pr_err("Failing address 0x%lx\n", (unsigned long)stack); |
56 | break; | 59 | break; |
57 | } | 60 | } |
58 | stack++; | 61 | stack++; |
@@ -68,10 +71,14 @@ show_trace(unsigned long *stack) | |||
68 | if (((addr >= (unsigned long)&_stext) && | 71 | if (((addr >= (unsigned long)&_stext) && |
69 | (addr <= (unsigned long)&_etext)) || | 72 | (addr <= (unsigned long)&_etext)) || |
70 | ((addr >= module_start) && (addr <= module_end))) { | 73 | ((addr >= module_start) && (addr <= module_end))) { |
74 | #ifdef CONFIG_KALLSYMS | ||
75 | print_ip_sym(addr); | ||
76 | #else | ||
71 | if (i && ((i % 8) == 0)) | 77 | if (i && ((i % 8) == 0)) |
72 | printk("\n "); | 78 | pr_err("\n "); |
73 | printk("[<%08lx>] ", addr); | 79 | pr_err("[<%08lx>] ", addr); |
74 | i++; | 80 | i++; |
81 | #endif | ||
75 | } | 82 | } |
76 | } | 83 | } |
77 | } | 84 | } |
@@ -111,21 +118,21 @@ show_stack(struct task_struct *task, unsigned long *sp) | |||
111 | 118 | ||
112 | stack = sp; | 119 | stack = sp; |
113 | 120 | ||
114 | printk("\nStack from %08lx:\n ", (unsigned long)stack); | 121 | pr_err("\nStack from %08lx:\n ", (unsigned long)stack); |
115 | for (i = 0; i < kstack_depth_to_print; i++) { | 122 | for (i = 0; i < kstack_depth_to_print; i++) { |
116 | if (((long)stack & (THREAD_SIZE-1)) == 0) | 123 | if (((long)stack & (THREAD_SIZE-1)) == 0) |
117 | break; | 124 | break; |
118 | if (i && ((i % 8) == 0)) | 125 | if (i && ((i % 8) == 0)) |
119 | printk("\n "); | 126 | pr_err("\n "); |
120 | if (__get_user(addr, stack)) { | 127 | if (__get_user(addr, stack)) { |
121 | /* This message matches "failing address" marked | 128 | /* This message matches "failing address" marked |
122 | s390 in ksymoops, so lines containing it will | 129 | s390 in ksymoops, so lines containing it will |
123 | not be filtered out by ksymoops. */ | 130 | not be filtered out by ksymoops. */ |
124 | printk("Failing address 0x%lx\n", (unsigned long)stack); | 131 | pr_err("Failing address 0x%lx\n", (unsigned long)stack); |
125 | break; | 132 | break; |
126 | } | 133 | } |
127 | stack++; | 134 | stack++; |
128 | printk("%08lx ", addr); | 135 | pr_err("%08lx ", addr); |
129 | } | 136 | } |
130 | show_trace(sp); | 137 | show_trace(sp); |
131 | } | 138 | } |
@@ -139,33 +146,32 @@ show_stack(void) | |||
139 | unsigned long *sp = (unsigned long *)rdusp(); | 146 | unsigned long *sp = (unsigned long *)rdusp(); |
140 | int i; | 147 | int i; |
141 | 148 | ||
142 | printk("Stack dump [0x%08lx]:\n", (unsigned long)sp); | 149 | pr_err("Stack dump [0x%08lx]:\n", (unsigned long)sp); |
143 | for (i = 0; i < 16; i++) | 150 | for (i = 0; i < 16; i++) |
144 | printk("sp + %d: 0x%08lx\n", i*4, sp[i]); | 151 | pr_err("sp + %d: 0x%08lx\n", i*4, sp[i]); |
145 | return 0; | 152 | return 0; |
146 | } | 153 | } |
147 | #endif | 154 | #endif |
148 | 155 | ||
149 | void | 156 | void set_nmi_handler(void (*handler)(struct pt_regs *)) |
150 | set_nmi_handler(void (*handler)(struct pt_regs *)) | ||
151 | { | 157 | { |
152 | nmi_handler = handler; | 158 | nmi_handler = handler; |
153 | arch_enable_nmi(); | 159 | arch_enable_nmi(); |
154 | } | 160 | } |
155 | 161 | ||
156 | #ifdef CONFIG_DEBUG_NMI_OOPS | 162 | #ifdef CONFIG_DEBUG_NMI_OOPS |
157 | void | 163 | void oops_nmi_handler(struct pt_regs *regs) |
158 | oops_nmi_handler(struct pt_regs *regs) | ||
159 | { | 164 | { |
160 | stop_watchdog(); | 165 | stop_watchdog(); |
161 | oops_in_progress = 1; | 166 | oops_in_progress = 1; |
162 | printk("NMI!\n"); | 167 | pr_err("NMI!\n"); |
163 | show_registers(regs); | 168 | show_registers(regs); |
164 | oops_in_progress = 0; | 169 | oops_in_progress = 0; |
170 | oops_exit(); | ||
171 | pr_err("\n"); /* Flush mtdoops. */ | ||
165 | } | 172 | } |
166 | 173 | ||
167 | static int __init | 174 | static int __init oops_nmi_register(void) |
168 | oops_nmi_register(void) | ||
169 | { | 175 | { |
170 | set_nmi_handler(oops_nmi_handler); | 176 | set_nmi_handler(oops_nmi_handler); |
171 | return 0; | 177 | return 0; |
@@ -180,8 +186,7 @@ __initcall(oops_nmi_register); | |||
180 | * similar to an Oops dump, and if the kernel is configured to be a nice | 186 | * similar to an Oops dump, and if the kernel is configured to be a nice |
181 | * doggy, then halt instead of reboot. | 187 | * doggy, then halt instead of reboot. |
182 | */ | 188 | */ |
183 | void | 189 | void watchdog_bite_hook(struct pt_regs *regs) |
184 | watchdog_bite_hook(struct pt_regs *regs) | ||
185 | { | 190 | { |
186 | #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY | 191 | #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY |
187 | local_irq_disable(); | 192 | local_irq_disable(); |
@@ -196,8 +201,7 @@ watchdog_bite_hook(struct pt_regs *regs) | |||
196 | } | 201 | } |
197 | 202 | ||
198 | /* This is normally the Oops function. */ | 203 | /* This is normally the Oops function. */ |
199 | void | 204 | void die_if_kernel(const char *str, struct pt_regs *regs, long err) |
200 | die_if_kernel(const char *str, struct pt_regs *regs, long err) | ||
201 | { | 205 | { |
202 | if (user_mode(regs)) | 206 | if (user_mode(regs)) |
203 | return; | 207 | return; |
@@ -211,13 +215,17 @@ die_if_kernel(const char *str, struct pt_regs *regs, long err) | |||
211 | stop_watchdog(); | 215 | stop_watchdog(); |
212 | #endif | 216 | #endif |
213 | 217 | ||
218 | oops_enter(); | ||
214 | handle_BUG(regs); | 219 | handle_BUG(regs); |
215 | 220 | ||
216 | printk("%s: %04lx\n", str, err & 0xffff); | 221 | pr_err("Linux %s %s\n", utsname()->release, utsname()->version); |
222 | pr_err("%s: %04lx\n", str, err & 0xffff); | ||
217 | 223 | ||
218 | show_registers(regs); | 224 | show_registers(regs); |
219 | 225 | ||
226 | oops_exit(); | ||
220 | oops_in_progress = 0; | 227 | oops_in_progress = 0; |
228 | pr_err("\n"); /* Flush mtdoops. */ | ||
221 | 229 | ||
222 | #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY | 230 | #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY |
223 | reset_watchdog(); | 231 | reset_watchdog(); |
@@ -225,8 +233,7 @@ die_if_kernel(const char *str, struct pt_regs *regs, long err) | |||
225 | do_exit(SIGSEGV); | 233 | do_exit(SIGSEGV); |
226 | } | 234 | } |
227 | 235 | ||
228 | void __init | 236 | void __init trap_init(void) |
229 | trap_init(void) | ||
230 | { | 237 | { |
231 | /* Nothing needs to be done */ | 238 | /* Nothing needs to be done */ |
232 | } | 239 | } |