]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
PCI/MSI: Deal with devices lying about their MSI mask capability
authorMarc Zyngier <maz@kernel.org>
Thu, 4 Nov 2021 18:01:29 +0000 (18:01 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 26 Nov 2021 10:36:19 +0000 (11:36 +0100)
commit 2226667a145db2e1f314d7f57fd644fe69863ab9 upstream.

It appears that some devices are lying about their mask capability,
pretending that they don't have it, while they actually do.
The net result is that now that we don't enable MSIs on such
endpoint.

Add a new per-device flag to deal with this. Further patches will
make use of it, sadly.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20211104180130.3825416-2-maz@kernel.org
Cc: Bjorn Helgaas <helgaas@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/pci/msi.c
include/linux/pci.h

index c824764f44ff70dd81a679030e0b79cc868f422a..d42c84a2d2eba7f1d8942dc9a4ee0aa30669793d 100644 (file)
@@ -569,6 +569,9 @@ msi_setup_entry(struct pci_dev *dev, int nvec, const struct irq_affinity *affd)
                goto out;
 
        pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);
+       /* Lies, damned lies, and MSIs */
+       if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING)
+               control |= PCI_MSI_FLAGS_MASKBIT;
 
        entry->msi_attrib.is_msix       = 0;
        entry->msi_attrib.is_64         = !!(control & PCI_MSI_FLAGS_64BIT);
index 6f9ca2f278b321f742be9bf9ec291efa595697dc..a4bbce871e08e1de2f9ae98188caeed4fd6c06f6 100644 (file)
@@ -205,6 +205,8 @@ enum pci_dev_flags {
        PCI_DEV_FLAGS_NO_FLR_RESET = (__force pci_dev_flags_t) (1 << 10),
        /* Don't use Relaxed Ordering for TLPs directed at this device */
        PCI_DEV_FLAGS_NO_RELAXED_ORDERING = (__force pci_dev_flags_t) (1 << 11),
+       /* Device does honor MSI masking despite saying otherwise */
+       PCI_DEV_FLAGS_HAS_MSI_MASKING = (__force pci_dev_flags_t) (1 << 12),
 };
 
 enum pci_irq_reroute_variant {