Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+6 -12
+6 -12
drivers/pci/msi/msi.c
··· 285 285 static int msi_setup_msi_desc(struct pci_dev *dev, int nvec, 286 286 struct irq_affinity_desc *masks) 287 287 { 288 - const struct irq_domain *d = dev_get_msi_domain(&dev->dev); 289 - const struct msi_domain_info *info = d->host_data; 290 288 struct msi_desc desc; 291 289 u16 control; 292 290 ··· 295 297 /* Lies, damned lies, and MSIs */ 296 298 if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING) 297 299 control |= PCI_MSI_FLAGS_MASKBIT; 298 - if (info->flags & MSI_FLAG_NO_MASK) 300 + if (pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY)) 299 301 control &= ~PCI_MSI_FLAGS_MASKBIT; 300 302 301 303 desc.nvec_used = nvec; ··· 602 604 */ 603 605 void msix_prepare_msi_desc(struct pci_dev *dev, struct msi_desc *desc) 604 606 { 605 - const struct irq_domain *d = dev_get_msi_domain(&dev->dev); 606 - const struct msi_domain_info *info = d->host_data; 607 - 608 607 desc->nvec_used = 1; 609 608 desc->pci.msi_attrib.is_msix = 1; 610 609 desc->pci.msi_attrib.is_64 = 1; 611 610 desc->pci.msi_attrib.default_irq = dev->irq; 612 611 desc->pci.mask_base = dev->msix_base; 613 - desc->pci.msi_attrib.can_mask = !(info->flags & MSI_FLAG_NO_MASK) && 614 - !desc->pci.msi_attrib.is_virtual; 615 612 616 - if (desc->pci.msi_attrib.can_mask) { 613 + 614 + if (!pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY) && 615 + !desc->pci.msi_attrib.is_virtual) { 617 616 void __iomem *addr = pci_msix_desc_addr(desc); 618 617 618 + desc->pci.msi_attrib.can_mask = 1; 619 619 desc->pci.msix_ctrl = readl(addr + PCI_MSIX_ENTRY_VECTOR_CTRL); 620 620 } 621 621 } ··· 711 715 static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, 712 716 int nvec, struct irq_affinity *affd) 713 717 { 714 - const struct irq_domain *d = dev_get_msi_domain(&dev->dev); 715 - const struct msi_domain_info *info = d->host_data; 716 718 int ret, tsize; 717 719 u16 control; 718 720 ··· 741 747 /* Disable INTX */ 742 748 pci_intx_for_msi(dev, 0); 743 749 744 - if (!(info->flags & MSI_FLAG_NO_MASK)) { 750 + if (!pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY)) { 745 751 /* 746 752 * Ensure that all table entries are masked to prevent 747 753 * stale entries from firing in a crash kernel.