From: Greg Kroah-Hartman Date: Mon, 16 Aug 2021 08:24:03 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v5.4.142~31 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ce67a4448f9df9fdcb646ab1e6c39be6e2fff6da;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches 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 --- diff --git a/queue-4.4/pci-msi-correct-misleading-comments.patch b/queue-4.4/pci-msi-correct-misleading-comments.patch new file mode 100644 index 00000000000..e518e56d3ac --- /dev/null +++ b/queue-4.4/pci-msi-correct-misleading-comments.patch @@ -0,0 +1,45 @@ +From 689e6b5351573c38ccf92a0dd8b3e2c2241e4aff Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Thu, 29 Jul 2021 23:51:45 +0200 +Subject: PCI/MSI: Correct misleading comments + +From: Thomas Gleixner + +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 +Tested-by: Marc Zyngier +Reviewed-by: Marc Zyngier +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20210729222542.621609423@linutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/msi.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/drivers/pci/msi.c ++++ b/drivers/pci/msi.c +@@ -890,7 +890,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 */ +@@ -988,10 +987,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.4/pci-msi-do-not-set-invalid-bits-in-msi-mask.patch b/queue-4.4/pci-msi-do-not-set-invalid-bits-in-msi-mask.patch new file mode 100644 index 00000000000..93bdf2ed337 --- /dev/null +++ b/queue-4.4/pci-msi-do-not-set-invalid-bits-in-msi-mask.patch @@ -0,0 +1,64 @@ +From 361fd37397f77578735907341579397d5bed0a2d Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Thu, 29 Jul 2021 23:51:44 +0200 +Subject: PCI/MSI: Do not set invalid bits in MSI mask + +From: Thomas Gleixner + +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 +Tested-by: Marc Zyngier +Reviewed-by: Marc Zyngier +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20210729222542.568173099@linutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/msi.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/pci/msi.c ++++ b/drivers/pci/msi.c +@@ -624,21 +624,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; + } +@@ -891,7 +891,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.4/pci-msi-protect-msi_desc-masked-for-multi-msi.patch b/queue-4.4/pci-msi-protect-msi_desc-masked-for-multi-msi.patch new file mode 100644 index 00000000000..3045afef838 --- /dev/null +++ b/queue-4.4/pci-msi-protect-msi_desc-masked-for-multi-msi.patch @@ -0,0 +1,114 @@ +From 77e89afc25f30abd56e76a809ee2884d7c1b63ce Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Thu, 29 Jul 2021 23:51:47 +0200 +Subject: PCI/MSI: Protect msi_desc::masked for multi-MSI + +From: Thomas Gleixner + +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 +Tested-by: Marc Zyngier +Reviewed-by: Marc Zyngier +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20210729222542.726833414@linutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -187,24 +187,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); + } + + /* +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -794,6 +794,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 +@@ -128,7 +128,7 @@ void __pci_read_msi_msg(struct msi_desc + void __pci_write_msi_msg(struct msi_desc *entry, 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.4/pci-msi-use-msi_mask_irq-in-pci_msi_shutdown.patch b/queue-4.4/pci-msi-use-msi_mask_irq-in-pci_msi_shutdown.patch new file mode 100644 index 00000000000..8780fdb1830 --- /dev/null +++ b/queue-4.4/pci-msi-use-msi_mask_irq-in-pci_msi_shutdown.patch @@ -0,0 +1,33 @@ +From d28d4ad2a1aef27458b3383725bb179beb8d015c Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Thu, 29 Jul 2021 23:51:46 +0200 +Subject: PCI/MSI: Use msi_mask_irq() in pci_msi_shutdown() + +From: Thomas Gleixner + +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 +Tested-by: Marc Zyngier +Reviewed-by: Marc Zyngier +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20210729222542.674391354@linutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/msi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/msi.c ++++ b/drivers/pci/msi.c +@@ -890,7 +890,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; diff --git a/queue-4.4/series b/queue-4.4/series index 6eaeb8c6b21..1dc0fc54054 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -4,3 +4,7 @@ net-fix-memory-leak-in-ieee802154_raw_deliver.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