Between the mtc0 or di instruction that disables interrupts and the
following hazard barrier a processor may still take interrupts.  If an
interrupt is taken after interrupts are disabled but before the state
is updated it will appear to restore_all that it is incorrectly returning
with interrupts disabled.
Signed-off-by: Chris Dearman <chris@mips.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
 
        .align  5
 NESTED(handle_int, PT_SIZE, sp)
+#ifdef CONFIG_TRACE_IRQFLAGS
+       /*
+        * Check to see if the interrupted code has just disabled
+        * interrupts and ignore this interrupt for now if so.
+        *
+        * local_irq_disable() disables interrupts and then calls
+        * trace_hardirqs_off() to track the state. If an interrupt is taken
+        * after interrupts are disabled but before the state is updated
+        * it will appear to restore_all that it is incorrectly returning with
+        * interrupts disabled
+        */
+       .set    push
+       .set    noat
+       mfc0    k0, CP0_STATUS
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+       and     k0, ST0_IEP
+       bnez    k0, 1f
+
+       mfc0    k0, EP0_EPC
+       .set    noreorder
+       j       k0
+       rfe
+#else
+       and     k0, ST0_IE
+       bnez    k0, 1f
+
+       eret
+#endif
+1:
+       .set pop
+#endif
        SAVE_ALL
        CLI
        TRACE_IRQS_OFF