diff options
author | Ben Dooks <ben.dooks@codethink.co.uk> | 2013-07-19 17:12:05 +0100 |
---|---|---|
committer | Ben Dooks <ben.dooks@codethink.co.uk> | 2013-07-22 18:05:04 +0100 |
commit | 06d6875fdc9845ed8647472d7c91c2e163268996 (patch) | |
tree | fafada62c4e1089b22021f0a559dd8971e17cc17 | |
parent | 1af99f33f8b04abba05552dc564ed6f2315455c1 (diff) | |
download | linux-06d6875fdc9845ed8647472d7c91c2e163268996.tar.gz |
ARM: traps: use <asm/opcodes.h> to get correct instruction order
The trap handler needs to take into account the endian configuration of
the system when loading instructions. Use <asm/opcodes.h> to provide the
necessary conversion functions.
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
-rw-r--r-- | arch/arm/kernel/traps.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 1c089119b2d7..0a56e13dc411 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -34,6 +34,7 @@ #include <asm/unwind.h> #include <asm/tls.h> #include <asm/system_misc.h> +#include <asm/opcodes.h> #include "signal.h" @@ -411,23 +412,24 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) if (processor_mode(regs) == SVC_MODE) { #ifdef CONFIG_THUMB2_KERNEL if (thumb_mode(regs)) { - instr = ((u16 *)pc)[0]; + instr = __mem_to_opcode_thumb16(((u16 *)pc)[0]); if (is_wide_instruction(instr)) { instr <<= 16; - instr |= ((u16 *)pc)[1]; + instr |= __mem_to_opcode_thumb16(((u16 *)pc)[1]); } } else #endif - instr = *(u32 *) pc; + instr = __mem_to_opcode_arm(*(u32 *) pc); } else if (thumb_mode(regs)) { if (get_user(instr, (u16 __user *)pc)) goto die_sig; + instr = __mem_to_opcode_thumb16(instr); if (is_wide_instruction(instr)) { unsigned int instr2; if (get_user(instr2, (u16 __user *)pc+1)) goto die_sig; instr <<= 16; - instr |= instr2; + instr |= __mem_to_opcode_thumb16(instr2); } } else if (get_user(instr, (u32 __user *)pc)) { goto die_sig; |