]> Git Repo - qemu.git/commitdiff
ppc: Fix conditions for delivering external interrupts to a guest
authorBenjamin Herrenschmidt <[email protected]>
Mon, 27 Jun 2016 06:55:17 +0000 (08:55 +0200)
committerDavid Gibson <[email protected]>
Thu, 30 Jun 2016 23:57:01 +0000 (09:57 +1000)
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 <[email protected]>
Signed-off-by: Cédric Le Goater <[email protected]>
Signed-off-by: David Gibson <[email protected]>
target-ppc/excp_helper.c

index 533866b87b607b59e40fd5ab4346905ae561fd42..26adda49b24805bbfe0522f20dd67de126ccc6dc 100644 (file)
@@ -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);
This page took 0.024256 seconds and 4 git commands to generate.