]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 5 Dec 2023 00:24:40 +0000 (09:24 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 5 Dec 2023 00:24:40 +0000 (09:24 +0900)
added patches:
x86-apic-msi-fix-misconfigured-non-maskable-msi-quirk.patch

queue-6.1/series
queue-6.1/x86-apic-msi-fix-misconfigured-non-maskable-msi-quirk.patch [new file with mode: 0644]

index f1788c78898214194e0a6d9e4bae18f771b80c0d..39fd90c7a3a0778839a6996a293107ebbe02d0a7 100644 (file)
@@ -104,3 +104,4 @@ r8169-fix-deadlock-on-rtl8125-in-jumbo-mtu-mode.patch
 xen-allow-platform-pci-interrupt-to-be-shared.patch
 xen-simplify-evtchn_do_upcall-call-maze.patch
 x86-xen-fix-percpu-vcpu_info-allocation.patch
+x86-apic-msi-fix-misconfigured-non-maskable-msi-quirk.patch
diff --git a/queue-6.1/x86-apic-msi-fix-misconfigured-non-maskable-msi-quirk.patch b/queue-6.1/x86-apic-msi-fix-misconfigured-non-maskable-msi-quirk.patch
new file mode 100644 (file)
index 0000000..3b611c9
--- /dev/null
@@ -0,0 +1,173 @@
+From b56ebe7c896dc78b5865ec2c4b1dae3c93537517 Mon Sep 17 00:00:00 2001
+From: Koichiro Den <den@valinux.co.jp>
+Date: Thu, 26 Oct 2023 12:20:36 +0900
+Subject: x86/apic/msi: Fix misconfigured non-maskable MSI quirk
+
+From: Koichiro Den <den@valinux.co.jp>
+
+commit b56ebe7c896dc78b5865ec2c4b1dae3c93537517 upstream.
+
+commit ef8dd01538ea ("genirq/msi: Make interrupt allocation less
+convoluted"), reworked the code so that the x86 specific quirk for affinity
+setting of non-maskable PCI/MSI interrupts is not longer activated if
+necessary.
+
+This could be solved by restoring the original logic in the core MSI code,
+but after a deeper analysis it turned out that the quirk flag is not
+required at all.
+
+The quirk is only required when the PCI/MSI device cannot mask the MSI
+interrupts, which in turn also prevents reservation mode from being enabled
+for the affected interrupt.
+
+This allows ot remove the NOMASK quirk bit completely as msi_set_affinity()
+can instead check whether reservation mode is enabled for the interrupt,
+which gives exactly the same answer.
+
+Even in the momentary non-existing case that the reservation mode would be
+not set for a maskable MSI interrupt this would not cause any harm as it
+just would cause msi_set_affinity() to go needlessly through the
+functionaly equivalent slow path, which works perfectly fine with maskable
+interrupts as well.
+
+Rework msi_set_affinity() to query the reservation mode and remove all
+NOMASK quirk logic from the core code.
+
+[ tglx: Massaged changelog ]
+
+Fixes: ef8dd01538ea ("genirq/msi: Make interrupt allocation less convoluted")
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Koichiro Den <den@valinux.co.jp>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20231026032036.2462428-1-den@valinux.co.jp
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/apic/msi.c |    8 +++-----
+ include/linux/irq.h        |   24 +++---------------------
+ kernel/irq/debugfs.c       |    1 -
+ kernel/irq/msi.c           |   12 +-----------
+ 4 files changed, 7 insertions(+), 38 deletions(-)
+
+--- a/arch/x86/kernel/apic/msi.c
++++ b/arch/x86/kernel/apic/msi.c
+@@ -55,14 +55,14 @@ msi_set_affinity(struct irq_data *irqd,
+        * caused by the non-atomic update of the address/data pair.
+        *
+        * Direct update is possible when:
+-       * - The MSI is maskable (remapped MSI does not use this code path)).
+-       *   The quirk bit is not set in this case.
++       * - The MSI is maskable (remapped MSI does not use this code path).
++       *   The reservation mode bit is set in this case.
+        * - The new vector is the same as the old vector
+        * - The old vector is MANAGED_IRQ_SHUTDOWN_VECTOR (interrupt starts up)
+        * - The interrupt is not yet started up
+        * - The new destination CPU is the same as the old destination CPU
+        */
+-      if (!irqd_msi_nomask_quirk(irqd) ||
++      if (!irqd_can_reserve(irqd) ||
+           cfg->vector == old_cfg.vector ||
+           old_cfg.vector == MANAGED_IRQ_SHUTDOWN_VECTOR ||
+           !irqd_is_started(irqd) ||
+@@ -202,8 +202,6 @@ struct irq_domain * __init native_create
+       if (!d) {
+               irq_domain_free_fwnode(fn);
+               pr_warn("Failed to initialize PCI-MSI irqdomain.\n");
+-      } else {
+-              d->flags |= IRQ_DOMAIN_MSI_NOMASK_QUIRK;
+       }
+       return d;
+ }
+--- a/include/linux/irq.h
++++ b/include/linux/irq.h
+@@ -215,8 +215,6 @@ struct irq_data {
+  * IRQD_SINGLE_TARGET         - IRQ allows only a single affinity target
+  * IRQD_DEFAULT_TRIGGER_SET   - Expected trigger already been set
+  * IRQD_CAN_RESERVE           - Can use reservation mode
+- * IRQD_MSI_NOMASK_QUIRK      - Non-maskable MSI quirk for affinity change
+- *                              required
+  * IRQD_HANDLE_ENFORCE_IRQCTX - Enforce that handle_irq_*() is only invoked
+  *                              from actual interrupt context.
+  * IRQD_AFFINITY_ON_ACTIVATE  - Affinity is set on activation. Don't call
+@@ -245,10 +243,9 @@ enum {
+       IRQD_SINGLE_TARGET              = (1 << 24),
+       IRQD_DEFAULT_TRIGGER_SET        = (1 << 25),
+       IRQD_CAN_RESERVE                = (1 << 26),
+-      IRQD_MSI_NOMASK_QUIRK           = (1 << 27),
+-      IRQD_HANDLE_ENFORCE_IRQCTX      = (1 << 28),
+-      IRQD_AFFINITY_ON_ACTIVATE       = (1 << 29),
+-      IRQD_IRQ_ENABLED_ON_SUSPEND     = (1 << 30),
++      IRQD_HANDLE_ENFORCE_IRQCTX      = (1 << 27),
++      IRQD_AFFINITY_ON_ACTIVATE       = (1 << 28),
++      IRQD_IRQ_ENABLED_ON_SUSPEND     = (1 << 29),
+ };
+ #define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors)
+@@ -423,21 +420,6 @@ static inline bool irqd_can_reserve(stru
+       return __irqd_to_state(d) & IRQD_CAN_RESERVE;
+ }
+-static inline void irqd_set_msi_nomask_quirk(struct irq_data *d)
+-{
+-      __irqd_to_state(d) |= IRQD_MSI_NOMASK_QUIRK;
+-}
+-
+-static inline void irqd_clr_msi_nomask_quirk(struct irq_data *d)
+-{
+-      __irqd_to_state(d) &= ~IRQD_MSI_NOMASK_QUIRK;
+-}
+-
+-static inline bool irqd_msi_nomask_quirk(struct irq_data *d)
+-{
+-      return __irqd_to_state(d) & IRQD_MSI_NOMASK_QUIRK;
+-}
+-
+ static inline void irqd_set_affinity_on_activate(struct irq_data *d)
+ {
+       __irqd_to_state(d) |= IRQD_AFFINITY_ON_ACTIVATE;
+--- a/kernel/irq/debugfs.c
++++ b/kernel/irq/debugfs.c
+@@ -121,7 +121,6 @@ static const struct irq_bit_descr irqdat
+       BIT_MASK_DESCR(IRQD_AFFINITY_ON_ACTIVATE),
+       BIT_MASK_DESCR(IRQD_MANAGED_SHUTDOWN),
+       BIT_MASK_DESCR(IRQD_CAN_RESERVE),
+-      BIT_MASK_DESCR(IRQD_MSI_NOMASK_QUIRK),
+       BIT_MASK_DESCR(IRQD_FORWARDED_TO_VCPU),
+--- a/kernel/irq/msi.c
++++ b/kernel/irq/msi.c
+@@ -807,7 +807,6 @@ static int msi_handle_pci_fail(struct ir
+ #define VIRQ_CAN_RESERVE      0x01
+ #define VIRQ_ACTIVATE         0x02
+-#define VIRQ_NOMASK_QUIRK     0x04
+ static int msi_init_virq(struct irq_domain *domain, int virq, unsigned int vflags)
+ {
+@@ -816,8 +815,6 @@ static int msi_init_virq(struct irq_doma
+       if (!(vflags & VIRQ_CAN_RESERVE)) {
+               irqd_clr_can_reserve(irqd);
+-              if (vflags & VIRQ_NOMASK_QUIRK)
+-                      irqd_set_msi_nomask_quirk(irqd);
+               /*
+                * If the interrupt is managed but no CPU is available to
+@@ -877,15 +874,8 @@ int __msi_domain_alloc_irqs(struct irq_d
+        * Interrupt can use a reserved vector and will not occupy
+        * a real device vector until the interrupt is requested.
+        */
+-      if (msi_check_reservation_mode(domain, info, dev)) {
++      if (msi_check_reservation_mode(domain, info, dev))
+               vflags |= VIRQ_CAN_RESERVE;
+-              /*
+-               * MSI affinity setting requires a special quirk (X86) when
+-               * reservation mode is active.
+-               */
+-              if (domain->flags & IRQ_DOMAIN_MSI_NOMASK_QUIRK)
+-                      vflags |= VIRQ_NOMASK_QUIRK;
+-      }
+       msi_for_each_desc(desc, dev, MSI_DESC_NOTASSOCIATED) {
+               ops->set_desc(&arg, desc);