Commit 8592edf0 authored by Ben Dooks's avatar Ben Dooks

ARM: alignment: correctly decode instructions in BE8 mode.

If we are in BE8 mode, we must deal with the instruction stream being
in LE order when data is being loaded in BE order. Ensure the data is
swapped before processing to avoid thre following:

Change to using <asm/opcodes.h> to provide the necessary conversion
functions to change the byte ordering.

This stops the following warning messages from the kernel on a fault:

Unhandled fault: alignment exception (0x001) at 0xbfa09567
Alignment trap: not handling instruction 030091e8 at [<80333e8c>]
Signed-off-by: default avatarBen Dooks <ben.dooks@codethink.co.uk>
Reviewed-by: default avatarDave Martin <Dave.Martin@arm.com>
Tested-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
parent 98dec91f
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <asm/cp15.h> #include <asm/cp15.h>
#include <asm/system_info.h> #include <asm/system_info.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <asm/opcodes.h>
#include "fault.h" #include "fault.h"
...@@ -762,21 +763,25 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) ...@@ -762,21 +763,25 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (thumb_mode(regs)) { if (thumb_mode(regs)) {
u16 *ptr = (u16 *)(instrptr & ~1); u16 *ptr = (u16 *)(instrptr & ~1);
fault = probe_kernel_address(ptr, tinstr); fault = probe_kernel_address(ptr, tinstr);
tinstr = __mem_to_opcode_thumb16(tinstr);
if (!fault) { if (!fault) {
if (cpu_architecture() >= CPU_ARCH_ARMv7 && if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
IS_T32(tinstr)) { IS_T32(tinstr)) {
/* Thumb-2 32-bit */ /* Thumb-2 32-bit */
u16 tinst2 = 0; u16 tinst2 = 0;
fault = probe_kernel_address(ptr + 1, tinst2); fault = probe_kernel_address(ptr + 1, tinst2);
instr = (tinstr << 16) | tinst2; tinst2 = __mem_to_opcode_thumb16(tinst2);
instr = __opcode_thumb32_compose(tinstr, tinst2);
thumb2_32b = 1; thumb2_32b = 1;
} else { } else {
isize = 2; isize = 2;
instr = thumb2arm(tinstr); instr = thumb2arm(tinstr);
} }
} }
} else } else {
fault = probe_kernel_address(instrptr, instr); fault = probe_kernel_address(instrptr, instr);
instr = __mem_to_opcode_arm(instr);
}
if (fault) { if (fault) {
type = TYPE_FAULT; type = TYPE_FAULT;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment