Commit ec53646f authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc

Pull another powerpc irq fix from Benjamin Herrenschmidt:
 "It looks like my previous fix for the lazy irq masking problem wasn't
  quite enough.  There was another problem related to performance
  monitor interrupts acting as NMIs leaving the flags in an incorrect
  state.  Here's a fix that finally seems to make perf solid again."

* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc:
  powerpc/irq: Fix another case of lazy IRQ state getting out of sync
parents 04e53358 7c0482e3
...@@ -588,23 +588,19 @@ _GLOBAL(ret_from_except_lite) ...@@ -588,23 +588,19 @@ _GLOBAL(ret_from_except_lite)
fast_exc_return_irq: fast_exc_return_irq:
restore: restore:
/* /*
* This is the main kernel exit path, we first check if we * This is the main kernel exit path. First we check if we
* have to change our interrupt state. * are about to re-enable interrupts
*/ */
ld r5,SOFTE(r1) ld r5,SOFTE(r1)
lbz r6,PACASOFTIRQEN(r13) lbz r6,PACASOFTIRQEN(r13)
cmpwi cr1,r5,0 cmpwi cr0,r5,0
cmpw cr0,r5,r6 beq restore_irq_off
beq cr0,4f
/* We do, handle disable first, which is easy */ /* We are enabling, were we already enabled ? Yes, just return */
bne cr1,3f; cmpwi cr0,r6,1
li r0,0 beq cr0,do_restore
stb r0,PACASOFTIRQEN(r13);
TRACE_DISABLE_INTS
b 4f
3: /* /*
* We are about to soft-enable interrupts (we are hard disabled * We are about to soft-enable interrupts (we are hard disabled
* at this point). We check if there's anything that needs to * at this point). We check if there's anything that needs to
* be replayed first. * be replayed first.
...@@ -626,7 +622,7 @@ restore_no_replay: ...@@ -626,7 +622,7 @@ restore_no_replay:
/* /*
* Final return path. BookE is handled in a different file * Final return path. BookE is handled in a different file
*/ */
4: do_restore:
#ifdef CONFIG_PPC_BOOK3E #ifdef CONFIG_PPC_BOOK3E
b .exception_return_book3e b .exception_return_book3e
#else #else
...@@ -699,6 +695,25 @@ fast_exception_return: ...@@ -699,6 +695,25 @@ fast_exception_return:
#endif /* CONFIG_PPC_BOOK3E */ #endif /* CONFIG_PPC_BOOK3E */
/*
* We are returning to a context with interrupts soft disabled.
*
* However, we may also about to hard enable, so we need to
* make sure that in this case, we also clear PACA_IRQ_HARD_DIS
* or that bit can get out of sync and bad things will happen
*/
restore_irq_off:
ld r3,_MSR(r1)
lbz r7,PACAIRQHAPPENED(r13)
andi. r0,r3,MSR_EE
beq 1f
rlwinm r7,r7,0,~PACA_IRQ_HARD_DIS
stb r7,PACAIRQHAPPENED(r13)
1: li r0,0
stb r0,PACASOFTIRQEN(r13);
TRACE_DISABLE_INTS
b do_restore
/* /*
* Something did happen, check if a re-emit is needed * Something did happen, check if a re-emit is needed
* (this also clears paca->irq_happened) * (this also clears paca->irq_happened)
...@@ -748,6 +763,9 @@ restore_check_irq_replay: ...@@ -748,6 +763,9 @@ restore_check_irq_replay:
#endif /* CONFIG_PPC_BOOK3E */ #endif /* CONFIG_PPC_BOOK3E */
1: b .ret_from_except /* What else to do here ? */ 1: b .ret_from_except /* What else to do here ? */
3:
do_work: do_work:
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
andi. r0,r3,MSR_PR /* Returning to user mode? */ andi. r0,r3,MSR_PR /* Returning to user mode? */
......
...@@ -229,6 +229,19 @@ notrace void arch_local_irq_restore(unsigned long en) ...@@ -229,6 +229,19 @@ notrace void arch_local_irq_restore(unsigned long en)
*/ */
if (unlikely(irq_happened != PACA_IRQ_HARD_DIS)) if (unlikely(irq_happened != PACA_IRQ_HARD_DIS))
__hard_irq_disable(); __hard_irq_disable();
#ifdef CONFIG_TRACE_IRQFLAG
else {
/*
* We should already be hard disabled here. We had bugs
* where that wasn't the case so let's dbl check it and
* warn if we are wrong. Only do that when IRQ tracing
* is enabled as mfmsr() can be costly.
*/
if (WARN_ON(mfmsr() & MSR_EE))
__hard_irq_disable();
}
#endif /* CONFIG_TRACE_IRQFLAG */
set_soft_enabled(0); set_soft_enabled(0);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment