powerpc/64: Fix __check_irq_replay missing decrementer interrupt
[sfrench/cifs-2.6.git] / arch / powerpc / kernel / irq.c
index 0bcec745a6724771c076e34132fb40e158b318f1..f291f7826abc65fe27bd9502ff45d922fa3f9e4e 100644 (file)
@@ -145,6 +145,19 @@ notrace unsigned int __check_irq_replay(void)
 
        /* Clear bit 0 which we wouldn't clear otherwise */
        local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS;
+       if (happened & PACA_IRQ_HARD_DIS) {
+               /*
+                * We may have missed a decrementer interrupt if hard disabled.
+                * Check the decrementer register in case we had a rollover
+                * while hard disabled.
+                */
+               if (!(happened & PACA_IRQ_DEC)) {
+                       if (decrementer_check_overflow()) {
+                               local_paca->irq_happened |= PACA_IRQ_DEC;
+                               happened |= PACA_IRQ_DEC;
+                       }
+               }
+       }
 
        /*
         * Force the delivery of pending soft-disabled interrupts on PS3.
@@ -170,7 +183,7 @@ notrace unsigned int __check_irq_replay(void)
         * in case we also had a rollover while hard disabled
         */
        local_paca->irq_happened &= ~PACA_IRQ_DEC;
-       if ((happened & PACA_IRQ_DEC) || decrementer_check_overflow())
+       if (happened & PACA_IRQ_DEC)
                return 0x900;
 
        /* Finally check if an external interrupt happened */