|
@@ -355,9 +355,24 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
|
|
pc = (void __user *)instruction_pointer(regs);
|
|
pc = (void __user *)instruction_pointer(regs);
|
|
|
|
|
|
if (processor_mode(regs) == SVC_MODE) {
|
|
if (processor_mode(regs) == SVC_MODE) {
|
|
- instr = *(u32 *) pc;
|
|
|
|
|
|
+#ifdef CONFIG_THUMB2_KERNEL
|
|
|
|
+ if (thumb_mode(regs)) {
|
|
|
|
+ instr = ((u16 *)pc)[0];
|
|
|
|
+ if (is_wide_instruction(instr)) {
|
|
|
|
+ instr <<= 16;
|
|
|
|
+ instr |= ((u16 *)pc)[1];
|
|
|
|
+ }
|
|
|
|
+ } else
|
|
|
|
+#endif
|
|
|
|
+ instr = *(u32 *) pc;
|
|
} else if (thumb_mode(regs)) {
|
|
} else if (thumb_mode(regs)) {
|
|
get_user(instr, (u16 __user *)pc);
|
|
get_user(instr, (u16 __user *)pc);
|
|
|
|
+ if (is_wide_instruction(instr)) {
|
|
|
|
+ unsigned int instr2;
|
|
|
|
+ get_user(instr2, (u16 __user *)pc+1);
|
|
|
|
+ instr <<= 16;
|
|
|
|
+ instr |= instr2;
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
get_user(instr, (u32 __user *)pc);
|
|
get_user(instr, (u32 __user *)pc);
|
|
}
|
|
}
|