summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2025-03-26 23:20:22 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2025-03-26 23:20:22 +0300
commit87dc996d56b7871da02ea6047cd46bb879443974 (patch)
tree3f7fb52f614f268084f82b80c75c9ba35969169a
parentf6e0150b2003fb2b9265028a618aa1732b3edc8f (diff)
parent3ece3e8e5976c49c3f887e5923f998eabd54ff40 (diff)
downloadlinux-87dc996d56b7871da02ea6047cd46bb879443974.tar.xz
Merge tag 'irq-urgent-2025-03-26' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull MSI irq fix from Thomas Gleixner: "An urgent fix for the XEN related PCI/MSI changes: XEN used a global variable to disable the masking of MSI interrupts as XEN handles that on the hypervisor side. This turned out to be a problem with VMD as the PCI devices behind a VMD bridge are not always handled by the hypervisor and then require masking by guest. To solve this the global variable was replaced by a interrupt domain specific flag, which is set by the generic XEN PCI/MSI domain, but not by VMD or any other domain in the system. So far, so good. But the implementation (and the reviewer) missed the fact, that accessing the domain flag cannot be done directly because there are at least two situations, where this fails. Legacy architectures are not providing interrupt domains at all. The new MSI parent domains do not require to have a domain info pointer. Both cases result in a unconditional NULL pointer derefence. The PCI/MSI code already has a function to query the MSI domain specific flag in a safe way, which handles all possible cases of PCI/MSI backends. So the fix it simply to replace the open coded checks by invoking the safe helper to query the flag" * tag 'irq-urgent-2025-03-26' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: PCI/MSI: Handle the NOMASK flag correctly for all PCI/MSI backends
-rw-r--r--drivers/pci/msi/msi.c18
1 files changed, 6 insertions, 12 deletions
diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
index d74162880d83..7058d59e7c5f 100644
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -285,8 +285,6 @@ static void pci_msi_set_enable(struct pci_dev *dev, int enable)
static int msi_setup_msi_desc(struct pci_dev *dev, int nvec,
struct irq_affinity_desc *masks)
{
- const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
- const struct msi_domain_info *info = d->host_data;
struct msi_desc desc;
u16 control;
@@ -297,7 +295,7 @@ static int msi_setup_msi_desc(struct pci_dev *dev, int nvec,
/* Lies, damned lies, and MSIs */
if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING)
control |= PCI_MSI_FLAGS_MASKBIT;
- if (info->flags & MSI_FLAG_NO_MASK)
+ if (pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY))
control &= ~PCI_MSI_FLAGS_MASKBIT;
desc.nvec_used = nvec;
@@ -604,20 +602,18 @@ static void __iomem *msix_map_region(struct pci_dev *dev,
*/
void msix_prepare_msi_desc(struct pci_dev *dev, struct msi_desc *desc)
{
- const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
- const struct msi_domain_info *info = d->host_data;
-
desc->nvec_used = 1;
desc->pci.msi_attrib.is_msix = 1;
desc->pci.msi_attrib.is_64 = 1;
desc->pci.msi_attrib.default_irq = dev->irq;
desc->pci.mask_base = dev->msix_base;
- desc->pci.msi_attrib.can_mask = !(info->flags & MSI_FLAG_NO_MASK) &&
- !desc->pci.msi_attrib.is_virtual;
- if (desc->pci.msi_attrib.can_mask) {
+
+ if (!pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY) &&
+ !desc->pci.msi_attrib.is_virtual) {
void __iomem *addr = pci_msix_desc_addr(desc);
+ desc->pci.msi_attrib.can_mask = 1;
desc->pci.msix_ctrl = readl(addr + PCI_MSIX_ENTRY_VECTOR_CTRL);
}
}
@@ -715,8 +711,6 @@ static int msix_setup_interrupts(struct pci_dev *dev, struct msix_entry *entries
static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
int nvec, struct irq_affinity *affd)
{
- const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
- const struct msi_domain_info *info = d->host_data;
int ret, tsize;
u16 control;
@@ -747,7 +741,7 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
/* Disable INTX */
pci_intx_for_msi(dev, 0);
- if (!(info->flags & MSI_FLAG_NO_MASK)) {
+ if (!pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY)) {
/*
* Ensure that all table entries are masked to prevent
* stale entries from firing in a crash kernel.