Commit d1dbe37c authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by David Gibson
Browse files

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: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarCédric Le Goater <clg@kaod.org>
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent 4b3fc377
Loading
Loading
Loading
Loading
+8 −11
Original line number Diff line number Diff line
@@ -794,6 +794,14 @@ static void ppc_hw_interrupt(CPUPPCState *env)
            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) {
        /* External critical interrupt */
        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);
            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)) {
            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);