SOFT_DISABLE_INTS(r3,r4)
 1:     bl      .preempt_schedule_irq
 
-       /* Hard-disable interrupts again (and update PACA) */
-#ifdef CONFIG_PPC_BOOK3E
-       wrteei  0
-#else
-       ld      r10,PACAKMSR(r13) /* Get kernel MSR without EE */
-       mtmsrd  r10,1
-#endif /* CONFIG_PPC_BOOK3E */
-       li      r0,PACA_IRQ_HARD_DIS
-       stb     r0,PACAIRQHAPPENED(r13)
-
        /* Re-test flags and eventually loop */
        clrrdi  r9,r1,THREAD_SHIFT
        ld      r4,TI_FLAGS(r9)
 user_work:
 #endif /* CONFIG_PREEMPT */
 
-       /* Enable interrupts */
-#ifdef CONFIG_PPC_BOOK3E
-       wrteei  1
-#else
-       ori     r10,r10,MSR_EE
-       mtmsrd  r10,1
-#endif /* CONFIG_PPC_BOOK3E */
-
        andi.   r0,r4,_TIF_NEED_RESCHED
        beq     1f
        bl      .restore_interrupts
 
  * if they are currently disabled. This is typically called before
  * schedule() or do_signal() when returning to userspace. We do it
  * in C to avoid the burden of dealing with lockdep etc...
+ *
+ * NOTE: This is called with interrupts hard disabled but not marked
+ * as such in paca->irq_happened, so we need to resync this.
  */
 void restore_interrupts(void)
 {
-       if (irqs_disabled())
+       if (irqs_disabled()) {
+               local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
                local_irq_enable();
+       } else
+               __hard_irq_enable();
 }
 
 #endif /* CONFIG_PPC64 */