diff options
Diffstat (limited to 'arch/arm/kernel/traps.c')
-rw-r--r-- | arch/arm/kernel/traps.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index bc9f9da782cb..7f5b99eb2c50 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -21,12 +21,14 @@ | |||
21 | #include <linux/kdebug.h> | 21 | #include <linux/kdebug.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/kexec.h> | 23 | #include <linux/kexec.h> |
24 | #include <linux/bug.h> | ||
24 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
25 | #include <linux/init.h> | 26 | #include <linux/init.h> |
26 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
27 | 28 | ||
28 | #include <linux/atomic.h> | 29 | #include <linux/atomic.h> |
29 | #include <asm/cacheflush.h> | 30 | #include <asm/cacheflush.h> |
31 | #include <asm/exception.h> | ||
30 | #include <asm/system.h> | 32 | #include <asm/system.h> |
31 | #include <asm/unistd.h> | 33 | #include <asm/unistd.h> |
32 | #include <asm/traps.h> | 34 | #include <asm/traps.h> |
@@ -270,6 +272,8 @@ void die(const char *str, struct pt_regs *regs, int err) | |||
270 | spin_lock_irq(&die_lock); | 272 | spin_lock_irq(&die_lock); |
271 | console_verbose(); | 273 | console_verbose(); |
272 | bust_spinlocks(1); | 274 | bust_spinlocks(1); |
275 | if (!user_mode(regs)) | ||
276 | report_bug(regs->ARM_pc, regs); | ||
273 | ret = __die(str, err, thread, regs); | 277 | ret = __die(str, err, thread, regs); |
274 | 278 | ||
275 | if (regs && kexec_should_crash(thread->task)) | 279 | if (regs && kexec_should_crash(thread->task)) |
@@ -301,6 +305,24 @@ void arm_notify_die(const char *str, struct pt_regs *regs, | |||
301 | } | 305 | } |
302 | } | 306 | } |
303 | 307 | ||
308 | #ifdef CONFIG_GENERIC_BUG | ||
309 | |||
310 | int is_valid_bugaddr(unsigned long pc) | ||
311 | { | ||
312 | #ifdef CONFIG_THUMB2_KERNEL | ||
313 | unsigned short bkpt; | ||
314 | #else | ||
315 | unsigned long bkpt; | ||
316 | #endif | ||
317 | |||
318 | if (probe_kernel_address((unsigned *)pc, bkpt)) | ||
319 | return 0; | ||
320 | |||
321 | return bkpt == BUG_INSTR_VALUE; | ||
322 | } | ||
323 | |||
324 | #endif | ||
325 | |||
304 | static LIST_HEAD(undef_hook); | 326 | static LIST_HEAD(undef_hook); |
305 | static DEFINE_SPINLOCK(undef_lock); | 327 | static DEFINE_SPINLOCK(undef_lock); |
306 | 328 | ||
@@ -706,16 +728,6 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs) | |||
706 | arm_notify_die("unknown data abort code", regs, &info, instr, 0); | 728 | arm_notify_die("unknown data abort code", regs, &info, instr, 0); |
707 | } | 729 | } |
708 | 730 | ||
709 | void __attribute__((noreturn)) __bug(const char *file, int line) | ||
710 | { | ||
711 | printk(KERN_CRIT"kernel BUG at %s:%d!\n", file, line); | ||
712 | *(int *)0 = 0; | ||
713 | |||
714 | /* Avoid "noreturn function does return" */ | ||
715 | for (;;); | ||
716 | } | ||
717 | EXPORT_SYMBOL(__bug); | ||
718 | |||
719 | void __readwrite_bug(const char *fn) | 731 | void __readwrite_bug(const char *fn) |
720 | { | 732 | { |
721 | printk("%s called, but not implemented\n", fn); | 733 | printk("%s called, but not implemented\n", fn); |