| From 2226667a145db2e1f314d7f57fd644fe69863ab9 Mon Sep 17 00:00:00 2001 |
| From: Marc Zyngier <maz@kernel.org> |
| Date: Thu, 4 Nov 2021 18:01:29 +0000 |
| Subject: PCI/MSI: Deal with devices lying about their MSI mask capability |
| |
| From: Marc Zyngier <maz@kernel.org> |
| |
| 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 | 3 +++ |
| include/linux/pci.h | 2 ++ |
| 2 files changed, 5 insertions(+) |
| |
| --- a/drivers/pci/msi.c |
| +++ b/drivers/pci/msi.c |
| @@ -585,6 +585,9 @@ msi_setup_entry(struct pci_dev *dev, int |
| 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); |
| --- a/include/linux/pci.h |
| +++ b/include/linux/pci.h |
| @@ -227,6 +227,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 { |