Skip to content

Commit 87dc996

Browse files
committed
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
2 parents f6e0150 + 3ece3e8 commit 87dc996

File tree

1 file changed

+6
-12
lines changed

1 file changed

+6
-12
lines changed

drivers/pci/msi/msi.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,6 @@ static void pci_msi_set_enable(struct pci_dev *dev, int enable)
285285
static int msi_setup_msi_desc(struct pci_dev *dev, int nvec,
286286
struct irq_affinity_desc *masks)
287287
{
288-
const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
289-
const struct msi_domain_info *info = d->host_data;
290288
struct msi_desc desc;
291289
u16 control;
292290

@@ -297,7 +295,7 @@ static int msi_setup_msi_desc(struct pci_dev *dev, int nvec,
297295
/* Lies, damned lies, and MSIs */
298296
if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING)
299297
control |= PCI_MSI_FLAGS_MASKBIT;
300-
if (info->flags & MSI_FLAG_NO_MASK)
298+
if (pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY))
301299
control &= ~PCI_MSI_FLAGS_MASKBIT;
302300

303301
desc.nvec_used = nvec;
@@ -604,20 +602,18 @@ static void __iomem *msix_map_region(struct pci_dev *dev,
604602
*/
605603
void msix_prepare_msi_desc(struct pci_dev *dev, struct msi_desc *desc)
606604
{
607-
const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
608-
const struct msi_domain_info *info = d->host_data;
609-
610605
desc->nvec_used = 1;
611606
desc->pci.msi_attrib.is_msix = 1;
612607
desc->pci.msi_attrib.is_64 = 1;
613608
desc->pci.msi_attrib.default_irq = dev->irq;
614609
desc->pci.mask_base = dev->msix_base;
615-
desc->pci.msi_attrib.can_mask = !(info->flags & MSI_FLAG_NO_MASK) &&
616-
!desc->pci.msi_attrib.is_virtual;
617610

618-
if (desc->pci.msi_attrib.can_mask) {
611+
612+
if (!pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY) &&
613+
!desc->pci.msi_attrib.is_virtual) {
619614
void __iomem *addr = pci_msix_desc_addr(desc);
620615

616+
desc->pci.msi_attrib.can_mask = 1;
621617
desc->pci.msix_ctrl = readl(addr + PCI_MSIX_ENTRY_VECTOR_CTRL);
622618
}
623619
}
@@ -715,8 +711,6 @@ static int msix_setup_interrupts(struct pci_dev *dev, struct msix_entry *entries
715711
static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
716712
int nvec, struct irq_affinity *affd)
717713
{
718-
const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
719-
const struct msi_domain_info *info = d->host_data;
720714
int ret, tsize;
721715
u16 control;
722716

@@ -747,7 +741,7 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
747741
/* Disable INTX */
748742
pci_intx_for_msi(dev, 0);
749743

750-
if (!(info->flags & MSI_FLAG_NO_MASK)) {
744+
if (!pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY)) {
751745
/*
752746
* Ensure that all table entries are masked to prevent
753747
* stale entries from firing in a crash kernel.

0 commit comments

Comments
 (0)