diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-18 12:43:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-18 12:43:09 -0400 |
commit | 515b696b282f856c3ad1679ccd658120faa387d0 (patch) | |
tree | d9d7c1185c396617f128ca23463062308d11393b /arch/sh/kernel/traps.c | |
parent | fa877c71e2136bd682b45022c96d5e073ced9f58 (diff) | |
parent | 064a16dc41be879d12bd5de5d2f9d38d890e0ee7 (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.c | 45 |
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 |
11 | static void handle_BUG(struct pt_regs *regs) | 13 | void 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 | ||
34 | invalid: | ||
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 | |||
96 | BUILD_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 | } | ||