]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
powerpc/64: fix irq replay missing preempt
authorNicholas Piggin <npiggin@gmail.com>
Tue, 15 Sep 2020 11:46:45 +0000 (21:46 +1000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Oct 2020 09:08:00 +0000 (10:08 +0100)
[ Upstream commit 903fd31d3212ab72d564c68f6cfb5d04db68773e ]

Prior to commit 3282a3da25bd ("powerpc/64: Implement soft interrupt
replay in C"), replayed interrupts returned by the regular interrupt
exit code, which performs preemption in case an interrupt had set
need_resched.

This logic was missed by the conversion. Adding preempt_disable/enable
around the interrupt replay and final irq enable will reschedule if
needed.

Fixes: 3282a3da25bd ("powerpc/64: Implement soft interrupt replay in C")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200915114650.3980244-1-npiggin@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/powerpc/kernel/irq.c

index 05b1cc0e009e43f755ceba40b01b59e7921b7956..297ee79febc6c91743d15f0f460192fbb33dd89c 100644 (file)
@@ -368,6 +368,12 @@ notrace void arch_local_irq_restore(unsigned long mask)
                }
        }
 
+       /*
+        * Disable preempt here, so that the below preempt_enable will
+        * perform resched if required (a replayed interrupt may set
+        * need_resched).
+        */
+       preempt_disable();
        irq_soft_mask_set(IRQS_ALL_DISABLED);
        trace_hardirqs_off();
 
@@ -377,6 +383,7 @@ notrace void arch_local_irq_restore(unsigned long mask)
        trace_hardirqs_on();
        irq_soft_mask_set(IRQS_ENABLED);
        __hard_irq_enable();
+       preempt_enable();
 }
 EXPORT_SYMBOL(arch_local_irq_restore);