ppc: Fix conditions for delivering external interrupts to a guest
External interrupts can bypass the MSR_EE test if they occur in guest mode and LPES0 is clear. In that case they are directed to the hypervisor Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> 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:
parent
4b3fc37788
commit
d1dbe37c1e
@ -794,6 +794,14 @@ static void ppc_hw_interrupt(CPUPPCState *env)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Extermal interrupt can ignore MSR:EE under some circumstances */
|
||||||
|
if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
|
||||||
|
bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
|
||||||
|
if (msr_ee != 0 || (env->has_hv_mode && msr_hv == 0 && !lpes0)) {
|
||||||
|
powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (msr_ce != 0) {
|
if (msr_ce != 0) {
|
||||||
/* External critical interrupt */
|
/* External critical interrupt */
|
||||||
if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
|
if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
|
||||||
@ -839,17 +847,6 @@ static void ppc_hw_interrupt(CPUPPCState *env)
|
|||||||
powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DECR);
|
powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DECR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* External interrupt */
|
|
||||||
if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
|
|
||||||
/* Taking an external interrupt does not clear the external
|
|
||||||
* interrupt status
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
|
|
||||||
#endif
|
|
||||||
powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
|
if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
|
||||||
env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
|
env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
|
||||||
powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);
|
powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);
|
||||||
|
Loading…
Reference in New Issue
Block a user