diff options
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.patch | 73 |
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 |