aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/traps.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-18 12:43:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-18 12:43:09 -0400
commit515b696b282f856c3ad1679ccd658120faa387d0 (patch)
treed9d7c1185c396617f128ca23463062308d11393b /arch/sh/kernel/traps.c
parentfa877c71e2136bd682b45022c96d5e073ced9f58 (diff)
parent064a16dc41be879d12bd5de5d2f9d38d890e0ee7 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (262 commits) sh: mach-ecovec24: Add user debug switch support sh: Kill off unused se_skipped in alignment trap notification code. sh: Wire up HAVE_SYSCALL_TRACEPOINTS. video: sh_mobile_lcdcfb: use both register sets for display panning video: sh_mobile_lcdcfb: implement display panning sh: Fix up sh7705 flush_dcache_page() build. sh: kfr2r09: document the PLL/FLL <-> RF relationship. sh: mach-ecovec24: need asm/clock.h. sh: mach-ecovec24: deassert usb irq on boot. sh: Add KEYSC support for EcoVec24 sh: add kycr2_delay for sh_keysc sh: cpufreq: Include CPU id in info messages. sh: multi-evt support for SH-X3 proto CPU. sh: clkfwk: remove bogus set_bus_parent() from SH7709. sh: Fix the indication point of the liquid crystal of AP-325RXA(AP3300) sh: Add EcoVec24 romImage defconfig sh: USB disable process is needed if romImage boot for EcoVec24 sh: EcoVec24: add HIZA setting for LED sh: EcoVec24: write MAC address in boot sh: Add romImage support for EcoVec24 ...
Diffstat (limited to 'arch/sh/kernel/traps.c')
-rw-r--r--arch/sh/kernel/traps.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index b3e0067db358..a8396f36bd14 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -5,18 +5,33 @@
5#include <linux/signal.h> 5#include <linux/signal.h>
6#include <linux/sched.h> 6#include <linux/sched.h>
7#include <linux/uaccess.h> 7#include <linux/uaccess.h>
8#include <linux/hardirq.h>
9#include <asm/unwinder.h>
8#include <asm/system.h> 10#include <asm/system.h>
9 11
10#ifdef CONFIG_BUG 12#ifdef CONFIG_BUG
11static void handle_BUG(struct pt_regs *regs) 13void handle_BUG(struct pt_regs *regs)
12{ 14{
15 const struct bug_entry *bug;
16 unsigned long bugaddr = regs->pc;
13 enum bug_trap_type tt; 17 enum bug_trap_type tt;
14 tt = report_bug(regs->pc, regs); 18
19 if (!is_valid_bugaddr(bugaddr))
20 goto invalid;
21
22 bug = find_bug(bugaddr);
23
24 /* Switch unwinders when unwind_stack() is called */
25 if (bug->flags & BUGFLAG_UNWINDER)
26 unwinder_faulted = 1;
27
28 tt = report_bug(bugaddr, regs);
15 if (tt == BUG_TRAP_TYPE_WARN) { 29 if (tt == BUG_TRAP_TYPE_WARN) {
16 regs->pc += instruction_size(regs->pc); 30 regs->pc += instruction_size(bugaddr);
17 return; 31 return;
18 } 32 }
19 33
34invalid:
20 die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); 35 die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
21} 36}
22 37
@@ -28,8 +43,10 @@ int is_valid_bugaddr(unsigned long addr)
28 return 0; 43 return 0;
29 if (probe_kernel_address((insn_size_t *)addr, opcode)) 44 if (probe_kernel_address((insn_size_t *)addr, opcode))
30 return 0; 45 return 0;
46 if (opcode == TRAPA_BUG_OPCODE)
47 return 1;
31 48
32 return opcode == TRAPA_BUG_OPCODE; 49 return 0;
33} 50}
34#endif 51#endif
35 52
@@ -75,3 +92,23 @@ BUILD_TRAP_HANDLER(bug)
75 92
76 force_sig(SIGTRAP, current); 93 force_sig(SIGTRAP, current);
77} 94}
95
96BUILD_TRAP_HANDLER(nmi)
97{
98 TRAP_HANDLER_DECL;
99
100 nmi_enter();
101
102 switch (notify_die(DIE_NMI, "NMI", regs, 0, vec & 0xff, SIGINT)) {
103 case NOTIFY_OK:
104 case NOTIFY_STOP:
105 break;
106 case NOTIFY_BAD:
107 die("Fatal Non-Maskable Interrupt", regs, SIGINT);
108 default:
109 printk(KERN_ALERT "Got NMI, but nobody cared. Ignoring...\n");
110 break;
111 }
112
113 nmi_exit();
114}