ppc: Rework generation of priv and inval interrupts

Recent server processors use the Hypervisor Emulation Assistance
interrupt for illegal instructions and *some* type of SPR accesses.

Also the code was always generating inval instructions even for priv
violations due to setting the wrong flags

Finally, the checking for PR/HV was open coded everywhere.

This reworks it all, using little helper macros for checking, and
adding the HV interrupt (which gets converted back to program check
in the slow path of excp_helper.c on CPUs that don't want it).

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[clg: fixed checkpatch.pl errors ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Benjamin Herrenschmidt 2016-06-21 23:48:51 +02:00 committed by David Gibson
parent 33595dc9f3
commit 9b2fadda3e
3 changed files with 311 additions and 399 deletions

View File

@ -1721,6 +1721,7 @@ void cpu_loop(CPUPPCState *env)
queue_signal(env, info.si_signo, &info);
break;
case POWERPC_EXCP_PROGRAM: /* Program exception */
case POWERPC_EXCP_HV_EMU: /* HV emulation */
/* XXX: check this */
switch (env->error_code & ~0xF) {
case POWERPC_EXCP_FP:

View File

@ -128,6 +128,19 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
ail = 0;
}
/* Hypervisor emulation assistance interrupt only exists on server
* arch 2.05 server or later. We also don't want to generate it if
* we don't have HVB in msr_mask (PAPR mode).
*/
if (excp == POWERPC_EXCP_HV_EMU
#if defined(TARGET_PPC64)
&& !((env->mmu_model & POWERPC_MMU_64) && (env->msr_mask & MSR_HVB))
#endif /* defined(TARGET_PPC64) */
) {
excp = POWERPC_EXCP_PROGRAM;
}
switch (excp) {
case POWERPC_EXCP_NONE:
/* Should never happen */
@ -249,6 +262,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
break;
}
goto store_current;
case POWERPC_EXCP_HV_EMU:
srr0 = SPR_HSRR0;
srr1 = SPR_HSRR1;
new_msr |= (target_ulong)MSR_HVB;
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
goto store_current;
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
goto store_current;
case POWERPC_EXCP_SYSCALL: /* System call exception */

File diff suppressed because it is too large Load Diff