Skip to content

Commit a4cb365

Browse files
npigginmpe
authored andcommitted
powerpc/64s/interrupt: Fix lost interrupts when returning to soft-masked context
It's possible for an interrupt returning to an irqs-disabled context to lose a pending soft-masked irq because it branches to part of the exit code for irqs-enabled contexts, which is meant to clear only the PACA_IRQS_HARD_DIS flag from PACAIRQHAPPENED by zeroing the byte. This just looks like a simple thinko from a recent commit (if there was no hard mask pending, there would be no reason to clear it anyway). This also adds comment to the code that actually does need to clear the flag. Fixes: e485f6c ("powerpc/64/interrupt: Fix return to masked context after hard-mask irq becomes pending") Reported-by: Sachin Sant <[email protected]> Reported-by: Guenter Roeck <[email protected]> Signed-off-by: Nicholas Piggin <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent e237506 commit a4cb365

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

arch/powerpc/kernel/interrupt_64.S

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
538538
beq .Lfast_kernel_interrupt_return_\srr\() // EE already disabled
539539
lbz r11,PACAIRQHAPPENED(r13)
540540
andi. r10,r11,PACA_IRQ_MUST_HARD_MASK
541-
beq 1f // No HARD_MASK pending
541+
beq .Lfast_kernel_interrupt_return_\srr\() // No HARD_MASK pending
542542

543543
/* Must clear MSR_EE from _MSR */
544544
#ifdef CONFIG_PPC_BOOK3S
@@ -555,12 +555,23 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
555555
b .Lfast_kernel_interrupt_return_\srr\()
556556

557557
.Linterrupt_return_\srr\()_soft_enabled:
558+
/*
559+
* In the soft-enabled case, need to double-check that we have no
560+
* pending interrupts that might have come in before we reached the
561+
* restart section of code, and restart the exit so those can be
562+
* handled.
563+
*
564+
* If there are none, it is be possible that the interrupt still
565+
* has PACA_IRQ_HARD_DIS set, which needs to be cleared for the
566+
* interrupted context. This clear will not clobber a new pending
567+
* interrupt coming in, because we're in the restart section, so
568+
* such would return to the restart location.
569+
*/
558570
#ifdef CONFIG_PPC_BOOK3S
559571
lbz r11,PACAIRQHAPPENED(r13)
560572
andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l
561573
bne- interrupt_return_\srr\()_kernel_restart
562574
#endif
563-
1:
564575
li r11,0
565576
stb r11,PACAIRQHAPPENED(r13) // clear the possible HARD_DIS
566577

0 commit comments

Comments
 (0)