| From b9255a7cb51754e8d2645b65dd31805e282b4f3e Mon Sep 17 00:00:00 2001 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Thu, 29 Jul 2021 23:51:43 +0200 |
| Subject: PCI/MSI: Enforce MSI[X] entry updates to be visible |
| |
| From: Thomas Gleixner <tglx@linutronix.de> |
| |
| commit b9255a7cb51754e8d2645b65dd31805e282b4f3e upstream. |
| |
| Nothing enforces the posted writes to be visible when the function |
| returns. Flush them even if the flush might be redundant when the entry is |
| masked already as the unmask will flush as well. This is either setup or a |
| rare affinity change event so the extra flush is not the end of the world. |
| |
| While this is more a theoretical issue especially the logic in the X86 |
| specific msi_set_affinity() function relies on the assumption that the |
| update has reached the hardware when the function returns. |
| |
| Again, as this never has been enforced the Fixes tag refers to a commit in: |
| git://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git |
| |
| Fixes: f036d4ea5fa7 ("[PATCH] ia32 Message Signalled Interrupt support") |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Tested-by: Marc Zyngier <maz@kernel.org> |
| Reviewed-by: Marc Zyngier <maz@kernel.org> |
| Acked-by: Bjorn Helgaas <bhelgaas@google.com> |
| Cc: stable@vger.kernel.org |
| Link: https://lore.kernel.org/r/20210729222542.515188147@linutronix.de |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/pci/msi.c | 5 +++++ |
| 1 file changed, 5 insertions(+) |
| |
| --- a/drivers/pci/msi.c |
| +++ b/drivers/pci/msi.c |
| @@ -340,6 +340,9 @@ void __pci_write_msi_msg(struct msi_desc |
| |
| if (unmasked) |
| __pci_msix_desc_mask_irq(entry, 0); |
| + |
| + /* Ensure that the writes are visible in the device */ |
| + readl(base + PCI_MSIX_ENTRY_DATA); |
| } else { |
| int pos = dev->msi_cap; |
| u16 msgctl; |
| @@ -360,6 +363,8 @@ void __pci_write_msi_msg(struct msi_desc |
| pci_write_config_word(dev, pos + PCI_MSI_DATA_32, |
| msg->data); |
| } |
| + /* Ensure that the writes are visible in the device */ |
| + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); |
| } |
| entry->msg = *msg; |
| } |