]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Aug 2021 08:26:12 +0000 (10:26 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Aug 2021 08:26:12 +0000 (10:26 +0200)
added patches:
pci-msi-correct-misleading-comments.patch
pci-msi-do-not-set-invalid-bits-in-msi-mask.patch
pci-msi-protect-msi_desc-masked-for-multi-msi.patch
pci-msi-use-msi_mask_irq-in-pci_msi_shutdown.patch

queue-4.9/pci-msi-correct-misleading-comments.patch [new file with mode: 0644]
queue-4.9/pci-msi-do-not-set-invalid-bits-in-msi-mask.patch [new file with mode: 0644]
queue-4.9/pci-msi-protect-msi_desc-masked-for-multi-msi.patch [new file with mode: 0644]
queue-4.9/pci-msi-use-msi_mask_irq-in-pci_msi_shutdown.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/pci-msi-correct-misleading-comments.patch b/queue-4.9/pci-msi-correct-misleading-comments.patch
new file mode 100644 (file)
index 0000000..8739a2e
--- /dev/null
@@ -0,0 +1,45 @@
+From 689e6b5351573c38ccf92a0dd8b3e2c2241e4aff Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Thu, 29 Jul 2021 23:51:45 +0200
+Subject: PCI/MSI: Correct misleading comments
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 689e6b5351573c38ccf92a0dd8b3e2c2241e4aff upstream.
+
+The comments about preserving the cached state in pci_msi[x]_shutdown() are
+misleading as the MSI descriptors are freed right after those functions
+return. So there is nothing to restore. Preparatory change.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Marc Zyngier <maz@kernel.org>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20210729222542.621609423@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/msi.c |    5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -919,7 +919,6 @@ void pci_msi_shutdown(struct pci_dev *de
+       /* Return the device with MSI unmasked as initial states */
+       mask = msi_mask(desc->msi_attrib.multi_cap);
+-      /* Keep cached state to be restored */
+       __pci_msi_desc_mask_irq(desc, mask, 0);
+       /* Restore dev->irq to its default pin-assertion irq */
+@@ -1021,10 +1020,8 @@ void pci_msix_shutdown(struct pci_dev *d
+               return;
+       /* Return the device with MSI-X masked as initial states */
+-      for_each_pci_msi_entry(entry, dev) {
+-              /* Keep cached states to be restored */
++      for_each_pci_msi_entry(entry, dev)
+               __pci_msix_desc_mask_irq(entry, 1);
+-      }
+       pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
+       pci_intx_for_msi(dev, 1);
diff --git a/queue-4.9/pci-msi-do-not-set-invalid-bits-in-msi-mask.patch b/queue-4.9/pci-msi-do-not-set-invalid-bits-in-msi-mask.patch
new file mode 100644 (file)
index 0000000..eb9477b
--- /dev/null
@@ -0,0 +1,64 @@
+From 361fd37397f77578735907341579397d5bed0a2d Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Thu, 29 Jul 2021 23:51:44 +0200
+Subject: PCI/MSI: Do not set invalid bits in MSI mask
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 361fd37397f77578735907341579397d5bed0a2d upstream.
+
+msi_mask_irq() takes a mask and a flags argument. The mask argument is used
+to mask out bits from the cached mask and the flags argument to set bits.
+
+Some places invoke it with a flags argument which sets bits which are not
+used by the device, i.e. when the device supports up to 8 vectors a full
+unmask in some places sets the mask to 0xFFFFFF00. While devices probably
+do not care, it's still bad practice.
+
+Fixes: 7ba1930db02f ("PCI MSI: Unmask MSI if setup failed")
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Marc Zyngier <maz@kernel.org>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20210729222542.568173099@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/msi.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -639,21 +639,21 @@ static int msi_capability_init(struct pc
+       /* Configure MSI capability structure */
+       ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
+       if (ret) {
+-              msi_mask_irq(entry, mask, ~mask);
++              msi_mask_irq(entry, mask, 0);
+               free_msi_irqs(dev);
+               return ret;
+       }
+       ret = msi_verify_entries(dev);
+       if (ret) {
+-              msi_mask_irq(entry, mask, ~mask);
++              msi_mask_irq(entry, mask, 0);
+               free_msi_irqs(dev);
+               return ret;
+       }
+       ret = populate_msi_sysfs(dev);
+       if (ret) {
+-              msi_mask_irq(entry, mask, ~mask);
++              msi_mask_irq(entry, mask, 0);
+               free_msi_irqs(dev);
+               return ret;
+       }
+@@ -920,7 +920,7 @@ void pci_msi_shutdown(struct pci_dev *de
+       /* Return the device with MSI unmasked as initial states */
+       mask = msi_mask(desc->msi_attrib.multi_cap);
+       /* Keep cached state to be restored */
+-      __pci_msi_desc_mask_irq(desc, mask, ~mask);
++      __pci_msi_desc_mask_irq(desc, mask, 0);
+       /* Restore dev->irq to its default pin-assertion irq */
+       dev->irq = desc->msi_attrib.default_irq;
diff --git a/queue-4.9/pci-msi-protect-msi_desc-masked-for-multi-msi.patch b/queue-4.9/pci-msi-protect-msi_desc-masked-for-multi-msi.patch
new file mode 100644 (file)
index 0000000..44b3509
--- /dev/null
@@ -0,0 +1,114 @@
+From 77e89afc25f30abd56e76a809ee2884d7c1b63ce Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Thu, 29 Jul 2021 23:51:47 +0200
+Subject: PCI/MSI: Protect msi_desc::masked for multi-MSI
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 77e89afc25f30abd56e76a809ee2884d7c1b63ce upstream.
+
+Multi-MSI uses a single MSI descriptor and there is a single mask register
+when the device supports per vector masking. To avoid reading back the mask
+register the value is cached in the MSI descriptor and updates are done by
+clearing and setting bits in the cache and writing it to the device.
+
+But nothing protects msi_desc::masked and the mask register from being
+modified concurrently on two different CPUs for two different Linux
+interrupts which belong to the same multi-MSI descriptor.
+
+Add a lock to struct device and protect any operation on the mask and the
+mask register with it.
+
+This makes the update of msi_desc::masked unconditional, but there is no
+place which requires a modification of the hardware register without
+updating the masked cache.
+
+msi_mask_irq() is now an empty wrapper which will be cleaned up in follow
+up changes.
+
+The problem goes way back to the initial support of multi-MSI, but picking
+the commit which introduced the mask cache is a valid cut off point
+(2.6.30).
+
+Fixes: f2440d9acbe8 ("PCI MSI: Refactor interrupt masking code")
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Marc Zyngier <maz@kernel.org>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20210729222542.726833414@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/core.c    |    1 +
+ drivers/pci/msi.c      |   19 ++++++++++---------
+ include/linux/device.h |    1 +
+ include/linux/msi.h    |    2 +-
+ 4 files changed, 13 insertions(+), 10 deletions(-)
+
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -710,6 +710,7 @@ void device_initialize(struct device *de
+       device_pm_init(dev);
+       set_dev_node(dev, -1);
+ #ifdef CONFIG_GENERIC_MSI_IRQ
++      raw_spin_lock_init(&dev->msi_lock);
+       INIT_LIST_HEAD(&dev->msi_list);
+ #endif
+ }
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -189,24 +189,25 @@ static inline __attribute_const__ u32 ms
+  * reliably as devices without an INTx disable bit will then generate a
+  * level IRQ which will never be cleared.
+  */
+-u32 __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
++void __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
+ {
+-      u32 mask_bits = desc->masked;
++      raw_spinlock_t *lock = &desc->dev->msi_lock;
++      unsigned long flags;
+       if (pci_msi_ignore_mask || !desc->msi_attrib.maskbit)
+-              return 0;
++              return;
+-      mask_bits &= ~mask;
+-      mask_bits |= flag;
++      raw_spin_lock_irqsave(lock, flags);
++      desc->masked &= ~mask;
++      desc->masked |= flag;
+       pci_write_config_dword(msi_desc_to_pci_dev(desc), desc->mask_pos,
+-                             mask_bits);
+-
+-      return mask_bits;
++                             desc->masked);
++      raw_spin_unlock_irqrestore(lock, flags);
+ }
+ static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
+ {
+-      desc->masked = __pci_msi_desc_mask_irq(desc, mask, flag);
++      __pci_msi_desc_mask_irq(desc, mask, flag);
+ }
+ static void __iomem *pci_msix_desc_addr(struct msi_desc *desc)
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -812,6 +812,7 @@ struct device {
+       struct dev_pin_info     *pins;
+ #endif
+ #ifdef CONFIG_GENERIC_MSI_IRQ
++      raw_spinlock_t          msi_lock;
+       struct list_head        msi_list;
+ #endif
+--- a/include/linux/msi.h
++++ b/include/linux/msi.h
+@@ -133,7 +133,7 @@ void __pci_write_msi_msg(struct msi_desc
+ void pci_write_msi_msg(unsigned int irq, struct msi_msg *msg);
+ u32 __pci_msix_desc_mask_irq(struct msi_desc *desc, u32 flag);
+-u32 __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag);
++void __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag);
+ void pci_msi_mask_irq(struct irq_data *data);
+ void pci_msi_unmask_irq(struct irq_data *data);
diff --git a/queue-4.9/pci-msi-use-msi_mask_irq-in-pci_msi_shutdown.patch b/queue-4.9/pci-msi-use-msi_mask_irq-in-pci_msi_shutdown.patch
new file mode 100644 (file)
index 0000000..bca682f
--- /dev/null
@@ -0,0 +1,33 @@
+From d28d4ad2a1aef27458b3383725bb179beb8d015c Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Thu, 29 Jul 2021 23:51:46 +0200
+Subject: PCI/MSI: Use msi_mask_irq() in pci_msi_shutdown()
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit d28d4ad2a1aef27458b3383725bb179beb8d015c upstream.
+
+No point in using the raw write function from shutdown. Preparatory change
+to introduce proper serialization for the msi_desc::masked cache.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Marc Zyngier <maz@kernel.org>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20210729222542.674391354@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/msi.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -919,7 +919,7 @@ void pci_msi_shutdown(struct pci_dev *de
+       /* Return the device with MSI unmasked as initial states */
+       mask = msi_mask(desc->msi_attrib.multi_cap);
+-      __pci_msi_desc_mask_irq(desc, mask, 0);
++      msi_mask_irq(desc, mask, 0);
+       /* Restore dev->irq to its default pin-assertion irq */
+       dev->irq = desc->msi_attrib.default_irq;
index 5debf74d18c518e001ff10098bcd6b98606c2c7b..3408283cfb5ab3eca2fceb7531237a0fc8303873 100644 (file)
@@ -9,3 +9,7 @@ tcp_bbr-fix-u32-wrap-bug-in-round-logic-if-bbr_init-.patch
 xen-events-fix-race-in-set_evtchn_to_irq.patch
 x86-tools-fix-objdump-version-check-again.patch
 pci-msi-enable-and-mask-msi-x-early.patch
+pci-msi-do-not-set-invalid-bits-in-msi-mask.patch
+pci-msi-correct-misleading-comments.patch
+pci-msi-use-msi_mask_irq-in-pci_msi_shutdown.patch
+pci-msi-protect-msi_desc-masked-for-multi-msi.patch