aboutsummaryrefslogtreecommitdiff
path: root/arch/sh/include
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/include')
-rw-r--r--arch/sh/include/asm/bug.h25
-rw-r--r--arch/sh/include/asm/system.h5
-rw-r--r--arch/sh/include/asm/unwinder.h6
3 files changed, 36 insertions, 0 deletions
diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h
index c0171804016..b7d9822fd6c 100644
--- a/arch/sh/include/asm/bug.h
+++ b/arch/sh/include/asm/bug.h
@@ -1,6 +1,7 @@
#ifndef __ASM_SH_BUG_H
#define __ASM_SH_BUG_H
+#define TRAPA_UNWINDER_BUG_OPCODE 0xc33b /* trapa #0x3b */
#define TRAPA_BUG_OPCODE 0xc33e /* trapa #0x3e */
#ifdef CONFIG_GENERIC_BUG
@@ -72,6 +73,30 @@ do { \
unlikely(__ret_warn_on); \
})
+#define UNWINDER_BUG() \
+do { \
+ __asm__ __volatile__ ( \
+ "1:\t.short %O0\n" \
+ _EMIT_BUG_ENTRY \
+ : \
+ : "n" (TRAPA_UNWINDER_BUG_OPCODE), \
+ "i" (__FILE__), \
+ "i" (__LINE__), "i" (0), \
+ "i" (sizeof(struct bug_entry))); \
+} while (0)
+
+#define UNWINDER_BUG_ON(x) ({ \
+ int __ret_unwinder_on = !!(x); \
+ if (__builtin_constant_p(__ret_unwinder_on)) { \
+ if (__ret_unwinder_on) \
+ UNWINDER_BUG(); \
+ } else { \
+ if (unlikely(__ret_unwinder_on)) \
+ UNWINDER_BUG(); \
+ } \
+ unlikely(__ret_unwinder_on); \
+})
+
#endif /* CONFIG_GENERIC_BUG */
#include <asm-generic/bug.h>
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index ab79e1f4fbe..f9e2ceb94d9 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -181,6 +181,11 @@ BUILD_TRAP_HANDLER(breakpoint);
BUILD_TRAP_HANDLER(singlestep);
BUILD_TRAP_HANDLER(fpu_error);
BUILD_TRAP_HANDLER(fpu_state_restore);
+BUILD_TRAP_HANDLER(unwinder);
+
+#ifdef CONFIG_BUG
+extern void handle_BUG(struct pt_regs *);
+#endif
#define arch_align_stack(x) (x)
diff --git a/arch/sh/include/asm/unwinder.h b/arch/sh/include/asm/unwinder.h
index 3dc551453e2..1e65c07b3e1 100644
--- a/arch/sh/include/asm/unwinder.h
+++ b/arch/sh/include/asm/unwinder.h
@@ -22,4 +22,10 @@ extern void stack_reader_dump(struct task_struct *, struct pt_regs *,
unsigned long *, const struct stacktrace_ops *,
void *);
+/*
+ * Used by fault handling code to signal to the unwinder code that it
+ * should switch to a different unwinder.
+ */
+extern int unwinder_faulted;
+
#endif /* _LINUX_UNWINDER_H */