From b344e24a8e8ceda83d1285d22e3e5baf4f5e42d3 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 16 Aug 2009 21:54:48 +0100 Subject: 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 --- arch/sh/include/asm/bug.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'arch/sh/include/asm/bug.h') diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h index c01718040166..b7d9822fd6c2 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 -- cgit v1.2.3 From e115f2c17cbceee93b34d787a7a4a867fc73e7b4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 22 Aug 2009 05:28:25 +0900 Subject: sh: unwinder: Use a special bug flag for unwinder traps. This simplifies the unwinder trap handling, dropping the use of the special trapa vector and simply piggybacking on top of the BUG support. A new BUGFLAG_UNWINDER is added for flagging the unwinder fault, before continuing on with regular BUG dispatch. Signed-off-by: Paul Mundt --- arch/sh/include/asm/bug.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'arch/sh/include/asm/bug.h') diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h index b7d9822fd6c2..23c5504a3a01 100644 --- a/arch/sh/include/asm/bug.h +++ b/arch/sh/include/asm/bug.h @@ -1,8 +1,8 @@ #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 */ +#define BUGFLAG_UNWINDER (1 << 1) #ifdef CONFIG_GENERIC_BUG #define HAVE_ARCH_BUG @@ -73,15 +73,16 @@ do { \ unlikely(__ret_warn_on); \ }) -#define UNWINDER_BUG() \ +#define UNWINDER_BUG() \ do { \ __asm__ __volatile__ ( \ "1:\t.short %O0\n" \ - _EMIT_BUG_ENTRY \ + _EMIT_BUG_ENTRY \ : \ - : "n" (TRAPA_UNWINDER_BUG_OPCODE), \ + : "n" (TRAPA_BUG_OPCODE), \ "i" (__FILE__), \ - "i" (__LINE__), "i" (0), \ + "i" (__LINE__), \ + "i" (BUGFLAG_UNWINDER), \ "i" (sizeof(struct bug_entry))); \ } while (0) -- cgit v1.2.3 From 74db2479c1fecefd0a190f282f28f00565309807 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 22 Aug 2009 05:31:45 +0900 Subject: sh64: dummy unwinder BUG wrappers. sh64 does not yet support GENERIC_BUG, but still wants unwinder support. Alias UNWINDER_BUG and UNWINDER_BUG_ON to their BUG counterparts until the conversion to GENERIC_BUG is completed. Signed-off-by: Paul Mundt --- arch/sh/include/asm/bug.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/sh/include/asm/bug.h') diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h index 23c5504a3a01..d02c01b3e6b9 100644 --- a/arch/sh/include/asm/bug.h +++ b/arch/sh/include/asm/bug.h @@ -98,6 +98,11 @@ do { \ unlikely(__ret_unwinder_on); \ }) +#else + +#define UNWINDER_BUG BUG +#define UNWINDER_BUG_ON BUG_ON + #endif /* CONFIG_GENERIC_BUG */ #include -- cgit v1.2.3