--- /dev/null
+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);