summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0013-x86-ioapic-Don-t-let-setaffinity-unmask-threaded-EOI.patch
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--debian/patches-rt/0013-x86-ioapic-Don-t-let-setaffinity-unmask-threaded-EOI.patch101
1 files changed, 101 insertions, 0 deletions
diff --git a/debian/patches-rt/0013-x86-ioapic-Don-t-let-setaffinity-unmask-threaded-EOI.patch b/debian/patches-rt/0013-x86-ioapic-Don-t-let-setaffinity-unmask-threaded-EOI.patch
new file mode 100644
index 000000000..5c222cfd8
--- /dev/null
+++ b/debian/patches-rt/0013-x86-ioapic-Don-t-let-setaffinity-unmask-threaded-EOI.patch
@@ -0,0 +1,101 @@
+From 39f1823e7293c365e7abdc19c1b15d772fc0dbc1 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 17 Jul 2018 18:25:31 +0200
+Subject: [PATCH 013/347] x86/ioapic: Don't let setaffinity unmask threaded EOI
+ interrupt too early
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.246-rt110.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();
+
+So if setaffinity is pending then the interrupt will be moved and then
+unmasked, which is wrong as it should be kept masked up to the point where
+the threaded handler finished. It's not a real problem, the interrupt will
+just be able to fire before the threaded handler has finished, though the irq
+masked state will be wrong for a bit.
+
+The patch below should cure the issue. It also renames the horribly
+misnomed functions so it becomes clear what they are supposed to do.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+[bigeasy: add the body of the patch, use the same functions in both
+ ifdef paths (spotted by Andy Shevchenko)]
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ arch/x86/kernel/apic/io_apic.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
+index 677508baf95a..b1a7f453415f 100644
+--- a/arch/x86/kernel/apic/io_apic.c
++++ b/arch/x86/kernel/apic/io_apic.c
+@@ -1732,7 +1732,7 @@ static bool io_apic_level_ack_pending(struct mp_chip_data *data)
+ return false;
+ }
+
+-static inline bool ioapic_irqd_mask(struct irq_data *data)
++static inline bool ioapic_prepare_move(struct irq_data *data)
+ {
+ /* If we are moving the IRQ we need to mask it */
+ if (unlikely(irqd_is_setaffinity_pending(data))) {
+@@ -1743,9 +1743,9 @@ static inline bool ioapic_irqd_mask(struct irq_data *data)
+ return false;
+ }
+
+-static inline void ioapic_irqd_unmask(struct irq_data *data, bool masked)
++static inline void ioapic_finish_move(struct irq_data *data, bool moveit)
+ {
+- if (unlikely(masked)) {
++ if (unlikely(moveit)) {
+ /* Only migrate the irq if the ack has been received.
+ *
+ * On rare occasions the broadcast level triggered ack gets
+@@ -1780,11 +1780,11 @@ static inline void ioapic_irqd_unmask(struct irq_data *data, bool masked)
+ }
+ }
+ #else
+-static inline bool ioapic_irqd_mask(struct irq_data *data)
++static inline bool ioapic_prepare_move(struct irq_data *data)
+ {
+ return false;
+ }
+-static inline void ioapic_irqd_unmask(struct irq_data *data, bool masked)
++static inline void ioapic_finish_move(struct irq_data *data, bool moveit)
+ {
+ }
+ #endif
+@@ -1793,11 +1793,11 @@ static void ioapic_ack_level(struct irq_data *irq_data)
+ {
+ struct irq_cfg *cfg = irqd_cfg(irq_data);
+ unsigned long v;
+- bool masked;
++ bool moveit;
+ int i;
+
+ irq_complete_move(cfg);
+- masked = ioapic_irqd_mask(irq_data);
++ moveit = ioapic_prepare_move(irq_data);
+
+ /*
+ * It appears there is an erratum which affects at least version 0x11
+@@ -1852,7 +1852,7 @@ static void ioapic_ack_level(struct irq_data *irq_data)
+ eoi_ioapic_pin(cfg->vector, irq_data->chip_data);
+ }
+
+- ioapic_irqd_unmask(irq_data, masked);
++ ioapic_finish_move(irq_data, moveit);
+ }
+
+ static void ioapic_ir_ack_level(struct irq_data *irq_data)
+--
+2.36.1
+