summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/traps.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-07-30 19:42:10 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-07-31 12:04:30 +0100
commit15ac49b65024f55c4371a53214879a9c77c4fbf9 (patch)
treebcff50c21d64e51e672697771fc6a0cc29af1afd /arch/arm/kernel/traps.c
parentc5dff4ffd327088d85035bec535b7d0c9ea03151 (diff)
downloadlinux-15ac49b65024f55c4371a53214879a9c77c4fbf9.tar.gz
linux-15ac49b65024f55c4371a53214879a9c77c4fbf9.tar.bz2
linux-15ac49b65024f55c4371a53214879a9c77c4fbf9.zip
ARM: Fix undefined instruction exception handling
While trying to get a v3.5 kernel booted on the cubox, I noticed that VFP does not work correctly with VFP bounce handling. This is because of the confusion over 16-bit vs 32-bit instructions, and where PC is supposed to point to. The rule is that FP handlers are entered with regs->ARM_pc pointing at the _next_ instruction to be executed. However, if the exception is not handled, regs->ARM_pc points at the faulting instruction. This is easy for ARM mode, because we know that the next instruction and previous instructions are separated by four bytes. This is not true of Thumb2 though. Since all FP instructions are 32-bit in Thumb2, it makes things easy. We just need to select the appropriate adjustment. Do this by moving the adjustment out of do_undefinstr() into the assembly code, as only the assembly code knows whether it's dealing with a 32-bit or 16-bit instruction. Cc: <stable@vger.kernel.org> Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/traps.c')
-rw-r--r--arch/arm/kernel/traps.c8
1 files changed, 0 insertions, 8 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 3647170e9a16..c7cae6b9a4d9 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -370,18 +370,10 @@ static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
{
- unsigned int correction = thumb_mode(regs) ? 2 : 4;
unsigned int instr;
siginfo_t info;
void __user *pc;
- /*
- * According to the ARM ARM, PC is 2 or 4 bytes ahead,
- * depending whether we're in Thumb mode or not.
- * Correct this offset.
- */
- regs->ARM_pc -= correction;
-
pc = (void __user *)instruction_pointer(regs);
if (processor_mode(regs) == SVC_MODE) {