summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/x86-ioapic-Prevent-inconsistent-state-when-moving-an.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches-rt/x86-ioapic-Prevent-inconsistent-state-when-moving-an.patch')
-rw-r--r--debian/patches-rt/x86-ioapic-Prevent-inconsistent-state-when-moving-an.patch73
1 files changed, 73 insertions, 0 deletions
diff --git a/debian/patches-rt/x86-ioapic-Prevent-inconsistent-state-when-moving-an.patch b/debian/patches-rt/x86-ioapic-Prevent-inconsistent-state-when-moving-an.patch
new file mode 100644
index 000000000..c27214c1b
--- /dev/null
+++ b/debian/patches-rt/x86-ioapic-Prevent-inconsistent-state-when-moving-an.patch
@@ -0,0 +1,73 @@
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Thu, 17 Oct 2019 12:19:01 +0200
+Subject: [PATCH] x86/ioapic: Prevent inconsistent state when moving an
+ interrupt
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.4/older/patches-5.4.3-rt1.tar.xz
+
+There is an issue with threaded interrupts which are marked ONESHOT
+and using the fasteoi handler:
+
+ if (IS_ONESHOT())
+ mask_irq();
+ ....
+ cond_unmask_eoi_irq()
+ chip->irq_eoi();
+ if (setaffinity_pending) {
+ mask_ioapic();
+ ...
+ move_affinity();
+ unmask_ioapic();
+ }
+
+So if setaffinity is pending the interrupt will be moved and then
+unconditionally unmasked at the ioapic level, which is wrong in two
+aspects:
+
+ 1) It should be kept masked up to the point where the threaded handler
+ finished.
+
+ 2) The physical chip state and the software masked state are inconsistent
+
+Guard both the mask and the unmask with a check for the software masked
+state. If the line is marked masked then the ioapic line is also masked, so
+both mask_ioapic() and unmask_ioapic() can be skipped safely.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Sebastian Siewior <bigeasy@linutronix.de>
+Fixes: 3aa551c9b4c4 ("genirq: add threaded interrupt handler support")
+Link: https://lkml.kernel.org/r/20191017101938.321393687@linutronix.de
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ arch/x86/kernel/apic/io_apic.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/arch/x86/kernel/apic/io_apic.c
++++ b/arch/x86/kernel/apic/io_apic.c
+@@ -1727,9 +1727,10 @@ static bool io_apic_level_ack_pending(st
+
+ static inline bool ioapic_irqd_mask(struct irq_data *data)
+ {
+- /* If we are moving the irq we need to mask it */
++ /* If we are moving the IRQ we need to mask it */
+ if (unlikely(irqd_is_setaffinity_pending(data))) {
+- mask_ioapic_irq(data);
++ if (!irqd_irq_masked(data))
++ mask_ioapic_irq(data);
+ return true;
+ }
+ return false;
+@@ -1766,7 +1767,9 @@ static inline void ioapic_irqd_unmask(st
+ */
+ if (!io_apic_level_ack_pending(data->chip_data))
+ irq_move_masked_irq(data);
+- unmask_ioapic_irq(data);
++ /* If the IRQ is masked in the core, leave it: */
++ if (!irqd_irq_masked(data))
++ unmask_ioapic_irq(data);
+ }
+ }
+ #else