ARM: Correct BUG() assembly to ensure it is endian-agnostic
authorBen Dooks <ben.dooks@codethink.co.uk>
Thu, 25 Jul 2013 13:38:03 +0000 (14:38 +0100)
committerVictor Kamensky <victor.kamensky@linaro.org>
Thu, 13 Mar 2014 21:48:37 +0000 (14:48 -0700)
Currently BUG() uses .word or .hword to create the necessary illegal
instructions. However if we are building BE8 then these get swapped
by the linker into different illegal instructions in the text. This
means that the BUG() macro does not get trapped properly.

Change to using <asm/opcodes.h> to provide the necessary ARM instruction
building as we cannot rely on gcc/gas having the `.inst` instructions
which where added to try and resolve this issue (reported by Dave Martin
<Dave.Martin@arm.com>).

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
(cherry picked from commit 63328070eff2f4fd730c86966a0dbc976147c39f)

Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
arch/arm/include/asm/bug.h
arch/arm/kernel/traps.c

index 7af5c6c3653a8061bad62211bbd3073af82ab3f0..b274bde24905a7503f60d38672346636d093854b 100644 (file)
@@ -2,6 +2,8 @@
 #define _ASMARM_BUG_H
 
 #include <linux/linkage.h>
+#include <linux/types.h>
+#include <asm/opcodes.h>
 
 #ifdef CONFIG_BUG
 
  */
 #ifdef CONFIG_THUMB2_KERNEL
 #define BUG_INSTR_VALUE 0xde02
-#define BUG_INSTR_TYPE ".hword "
+#define BUG_INSTR(__value) __inst_thumb16(__value)
 #else
 #define BUG_INSTR_VALUE 0xe7f001f2
-#define BUG_INSTR_TYPE ".word "
+#define BUG_INSTR(__value) __inst_arm(__value)
 #endif
 
 
@@ -33,7 +35,7 @@
 
 #define __BUG(__file, __line, __value)                         \
 do {                                                           \
-       asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n"        \
+       asm volatile("1:\t" BUG_INSTR(__value) "\n"  \
                ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
                "2:\t.asciz " #__file "\n"                      \
                ".popsection\n"                                 \
@@ -48,7 +50,7 @@ do {                                                          \
 
 #define __BUG(__file, __line, __value)                         \
 do {                                                           \
-       asm volatile(BUG_INSTR_TYPE #__value);                  \
+       asm volatile(BUG_INSTR(__value) "\n");                  \
        unreachable();                                          \
 } while (0)
 #endif  /* CONFIG_DEBUG_BUGVERBOSE */
index 5989b0f317dda83a4bbd9052d62834a30ede0f8a..b4fd850c34b2f6db706439b084b495cf9cd2adda 100644 (file)
@@ -348,15 +348,17 @@ void arm_notify_die(const char *str, struct pt_regs *regs,
 int is_valid_bugaddr(unsigned long pc)
 {
 #ifdef CONFIG_THUMB2_KERNEL
-       unsigned short bkpt;
+       u16 bkpt;
+       u16 insn = __opcode_to_mem_thumb16(BUG_INSTR_VALUE);
 #else
-       unsigned long bkpt;
+       u32 bkpt;
+       u32 insn = __opcode_to_mem_arm(BUG_INSTR_VALUE);
 #endif
 
        if (probe_kernel_address((unsigned *)pc, bkpt))
                return 0;
 
-       return bkpt == BUG_INSTR_VALUE;
+       return bkpt == insn;
 }
 
 #endif