Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a79a0cb1 authored by Ben Dooks's avatar Ben Dooks
Browse files

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: default avatarBen Dooks <ben.dooks@codethink.co.uk>
Tested-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
parent 8592edf0
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <asm/unwind.h>
#include <asm/tls.h>
#include <asm/system_misc.h>
#include <asm/opcodes.h>

static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };

@@ -402,25 +403,28 @@ 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];
				u16 inst2;
				inst2 = __mem_to_opcode_thumb16(((u16 *)pc)[1]);
				instr = __opcode_thumb32_compose(instr, inst2);
			}
		} 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;
			instr2 = __mem_to_opcode_thumb16(instr2);
			instr = __opcode_thumb32_compose(instr, instr2);
		}
	} else if (get_user(instr, (u32 __user *)pc)) {
		instr = __mem_to_opcode_arm(instr);
		goto die_sig;
	}