powerpc: Fix emulation of illegal instructions on PowerNV platform
authorPaul Mackerras <paulus@samba.org>
Fri, 14 Jun 2013 10:07:41 +0000 (20:07 +1000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Sat, 15 Jun 2013 02:24:11 +0000 (12:24 +1000)
Normally, the kernel emulates a few instructions that are unimplemented
on some processors (e.g. the old dcba instruction), or privileged (e.g.
mfpvr).  The emulation of unimplemented instructions is currently not
working on the PowerNV platform.  The reason is that on these machines,
unimplemented and illegal instructions cause a hypervisor emulation
assist interrupt, rather than a program interrupt as on older CPUs.
Our vector for the emulation assist interrupt just calls
program_check_exception() directly, without setting the bit in SRR1
that indicates an illegal instruction interrupt.  This fixes it by
making the emulation assist interrupt set that bit before calling
program_check_interrupt().  With this, old programs that use no-longer
implemented instructions such as dcba now work again.

CC: <stable@vger.kernel.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/traps.c

index e783453f910d45be9a7b12f266d708ddef123ed9..40e4a17c8ba0f249e2b65d85d4014fe7aa47f7a7 100644 (file)
@@ -683,7 +683,7 @@ machine_check_common:
        STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
        STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
        STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
-       STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception)
+       STD_EXCEPTION_COMMON(0xe40, emulation_assist, .emulation_assist_interrupt)
        STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
 #ifdef CONFIG_PPC_DOORBELL
        STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .doorbell_exception)
index f18c79c324eff539a25f8a5f10d13566a68eb573..c0e5caf8ccc72c0f7624b1e7dc9c3f7ecfe4b242 100644 (file)
@@ -1165,6 +1165,16 @@ bail:
        exception_exit(prev_state);
 }
 
+/*
+ * This occurs when running in hypervisor mode on POWER6 or later
+ * and an illegal instruction is encountered.
+ */
+void __kprobes emulation_assist_interrupt(struct pt_regs *regs)
+{
+       regs->msr |= REASON_ILLEGAL;
+       program_check_exception(regs);
+}
+
 void alignment_exception(struct pt_regs *regs)
 {
        enum ctx_state prev_state = exception_enter();