Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec53646f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+31 −13
Original line number Original line Diff line number Diff line
@@ -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:
	/*
	/*
	 * 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:


#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:
#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? */
+13 −0
Original line number Original line Diff line number Diff line
@@ -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);


	/*
	/*