Skip to content

Commit bf59390

Browse files
paulusmackozbenh
authored andcommitted
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. CC: <[email protected]> Signed-off-by: Paul Mackerras <[email protected]> Signed-off-by: Benjamin Herrenschmidt <[email protected]>
1 parent 0e37739 commit bf59390

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

arch/powerpc/kernel/exceptions-64s.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ machine_check_common:
683683
STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
684684
STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
685685
STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
686-
STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception)
686+
STD_EXCEPTION_COMMON(0xe40, emulation_assist, .emulation_assist_interrupt)
687687
STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
688688
#ifdef CONFIG_PPC_DOORBELL
689689
STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .doorbell_exception)

arch/powerpc/kernel/traps.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,16 @@ void __kprobes program_check_exception(struct pt_regs *regs)
11651165
exception_exit(prev_state);
11661166
}
11671167

1168+
/*
1169+
* This occurs when running in hypervisor mode on POWER6 or later
1170+
* and an illegal instruction is encountered.
1171+
*/
1172+
void __kprobes emulation_assist_interrupt(struct pt_regs *regs)
1173+
{
1174+
regs->msr |= REASON_ILLEGAL;
1175+
program_check_exception(regs);
1176+
}
1177+
11681178
void alignment_exception(struct pt_regs *regs)
11691179
{
11701180
enum ctx_state prev_state = exception_enter();

0 commit comments

Comments
 (0)