aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorBen Dooks <ben.dooks@codethink.co.uk>2013-07-25 09:38:03 -0400
committerBen Dooks <ben.dooks@codethink.co.uk>2013-10-19 15:46:35 -0400
commit63328070eff2f4fd730c86966a0dbc976147c39f (patch)
treeac939b9767e21a42a3354bdc69aaefc23e2c62d0 /arch/arm
parent3460743e025addc1ecbd496db2231181a2431774 (diff)
ARM: Correct BUG() assembly to ensure it is endian-agnostic
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>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/include/asm/bug.h10
-rw-r--r--arch/arm/kernel/traps.c8
2 files changed, 11 insertions, 7 deletions
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h
index 7af5c6c3653a..b274bde24905 100644
--- a/arch/arm/include/asm/bug.h
+++ b/arch/arm/include/asm/bug.h
@@ -2,6 +2,8 @@
2#define _ASMARM_BUG_H 2#define _ASMARM_BUG_H
3 3
4#include <linux/linkage.h> 4#include <linux/linkage.h>
5#include <linux/types.h>
6#include <asm/opcodes.h>
5 7
6#ifdef CONFIG_BUG 8#ifdef CONFIG_BUG
7 9
@@ -12,10 +14,10 @@
12 */ 14 */
13#ifdef CONFIG_THUMB2_KERNEL 15#ifdef CONFIG_THUMB2_KERNEL
14#define BUG_INSTR_VALUE 0xde02 16#define BUG_INSTR_VALUE 0xde02
15#define BUG_INSTR_TYPE ".hword " 17#define BUG_INSTR(__value) __inst_thumb16(__value)
16#else 18#else
17#define BUG_INSTR_VALUE 0xe7f001f2 19#define BUG_INSTR_VALUE 0xe7f001f2
18#define BUG_INSTR_TYPE ".word " 20#define BUG_INSTR(__value) __inst_arm(__value)
19#endif 21#endif
20 22
21 23
@@ -33,7 +35,7 @@
33 35
34#define __BUG(__file, __line, __value) \ 36#define __BUG(__file, __line, __value) \
35do { \ 37do { \
36 asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n" \ 38 asm volatile("1:\t" BUG_INSTR(__value) "\n" \
37 ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \ 39 ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
38 "2:\t.asciz " #__file "\n" \ 40 "2:\t.asciz " #__file "\n" \
39 ".popsection\n" \ 41 ".popsection\n" \
@@ -48,7 +50,7 @@ do { \
48 50
49#define __BUG(__file, __line, __value) \ 51#define __BUG(__file, __line, __value) \
50do { \ 52do { \
51 asm volatile(BUG_INSTR_TYPE #__value); \ 53 asm volatile(BUG_INSTR(__value) "\n"); \
52 unreachable(); \ 54 unreachable(); \
53} while (0) 55} while (0)
54#endif /* CONFIG_DEBUG_BUGVERBOSE */ 56#endif /* CONFIG_DEBUG_BUGVERBOSE */
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index caf96da27360..6125f259b7b5 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -342,15 +342,17 @@ void arm_notify_die(const char *str, struct pt_regs *regs,
342int is_valid_bugaddr(unsigned long pc) 342int is_valid_bugaddr(unsigned long pc)
343{ 343{
344#ifdef CONFIG_THUMB2_KERNEL 344#ifdef CONFIG_THUMB2_KERNEL
345 unsigned short bkpt; 345 u16 bkpt;
346 u16 insn = __opcode_to_mem_thumb16(BUG_INSTR_VALUE);
346#else 347#else
347 unsigned long bkpt; 348 u32 bkpt;
349 u32 insn = __opcode_to_mem_arm(BUG_INSTR_VALUE);
348#endif 350#endif
349 351
350 if (probe_kernel_address((unsigned *)pc, bkpt)) 352 if (probe_kernel_address((unsigned *)pc, bkpt))
351 return 0; 353 return 0;
352 354
353 return bkpt == BUG_INSTR_VALUE; 355 return bkpt == insn;
354} 356}
355 357
356#endif 358#endif