summaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/traps.c
diff options
context:
space:
mode:
authorMatt Fleming <matt@console-pimps.org>2009-08-16 21:54:48 +0100
committerMatt Fleming <matt@console-pimps.org>2009-08-21 13:02:44 +0100
commitb344e24a8e8ceda83d1285d22e3e5baf4f5e42d3 (patch)
tree4b9500264a797736b48b59c3f0977277ace53386 /arch/sh/kernel/traps.c
parent97efbbd5886e27b61c19c77d41f6491f5d96fbd0 (diff)
downloadlinux-stable-b344e24a8e8ceda83d1285d22e3e5baf4f5e42d3.tar.gz
linux-stable-b344e24a8e8ceda83d1285d22e3e5baf4f5e42d3.tar.bz2
linux-stable-b344e24a8e8ceda83d1285d22e3e5baf4f5e42d3.zip
sh: unwinder: Introduce UNWINDER_BUG() and UNWINDER_BUG_ON()
We can't assume that if we execute the unwinder code and the unwinder was already running that it has faulted. Clearly two kernel threads can invoke the unwinder at the same time and may be running simultaneously. The previous approach used BUG() and BUG_ON() in the unwinder code to detect whether the unwinder was incapable of unwinding the stack, and that the next available unwinder should be used instead. A better approach is to explicitly invoke a trap handler to switch unwinders when the current unwinder cannot continue. Signed-off-by: Matt Fleming <matt@console-pimps.org>
Diffstat (limited to 'arch/sh/kernel/traps.c')
-rw-r--r--arch/sh/kernel/traps.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index b3e0067db358..881b9a32b7de 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -8,7 +8,7 @@
#include <asm/system.h>
#ifdef CONFIG_BUG
-static void handle_BUG(struct pt_regs *regs)
+void handle_BUG(struct pt_regs *regs)
{
enum bug_trap_type tt;
tt = report_bug(regs->pc, regs);
@@ -29,7 +29,10 @@ int is_valid_bugaddr(unsigned long addr)
if (probe_kernel_address((insn_size_t *)addr, opcode))
return 0;
- return opcode == TRAPA_BUG_OPCODE;
+ if (opcode == TRAPA_BUG_OPCODE || opcode == TRAPA_UNWINDER_BUG_OPCODE)
+ return 1;
+
+ return 0;
}
#endif