powerpc: Fix emulation of illegal instructions on PowerNV platform
PATCH 1/1 powerpc: Fix emulation of illegal instructions on PowerNV platform
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.
--- arch/powerpc/kernel/exceptions-64s.S | 2 +- arch/powerpc/kernel/traps.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-)
arch/powerpc/kernel/exceptions-64s.S +1 -1
@@ -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)
arch/powerpc/kernel/traps.c +10 -0
@@ -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 ();
Signature · 1 line
1.7.10.4
Quoted 9 lines · Paul Mackerras
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.
Hey Paul,
The only difference between (1) Program interrupt and (2) Hypervisor emulation assist interrupt is that in the earlier, HW sets "illegal instruction" as the reason code in the SRR1 registers implicitly. We fix it in the later interrupt vector by doing the same explicitly in SW ? The cause of the problem before was not having the appropriate reason code ("illegal instruction") in the SRR1 register for program_ check_exception() function to take it forward ?
Regards
Anshuman