Skip to content

Commit f3b0946

Browse files
Marc ZyngierKAGA-KOKO
authored andcommitted
genirq/msi: Make sure PCI MSIs are activated early
Bharat Kumar Gogada reported issues with the generic MSI code, where the end-point ended up with garbage in its MSI configuration (both for the vector and the message). It turns out that the two MSI paths in the kernel are doing slightly different things: generic MSI: disable MSI -> allocate MSI -> enable MSI -> setup EP PCI MSI: disable MSI -> allocate MSI -> setup EP -> enable MSI And it turns out that end-points are allowed to latch the content of the MSI configuration registers as soon as MSIs are enabled. In Bharat's case, the end-point ends up using whatever was there already, which is not what you want. In order to make things converge, we introduce a new MSI domain flag (MSI_FLAG_ACTIVATE_EARLY) that is unconditionally set for PCI/MSI. When set, this flag forces the programming of the end-point as soon as the MSIs are allocated. A consequence of this is that we have an extra activate in irq_startup, but that should be without much consequence. tglx: - Several people reported a VMWare regression with PCI/MSI-X passthrough. It turns out that the patch also cures that issue. - We need to have a look at the MSI disable interrupt path, where we write the msg to all zeros without disabling MSI in the PCI device. Is that correct? Fixes: 52f518a "x86/MSI: Use hierarchical irqdomains to manage MSI interrupts" Reported-and-tested-by: Bharat Kumar Gogada <[email protected]> Reported-and-tested-by: Foster Snowhill <[email protected]> Reported-by: Matthias Prager <[email protected]> Reported-by: Jason Taylor <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Acked-by: Bjorn Helgaas <[email protected]> Cc: [email protected] Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Thomas Gleixner <[email protected]>
1 parent 81abf25 commit f3b0946

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

drivers/pci/msi.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,8 @@ struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode,
14111411
if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
14121412
pci_msi_domain_update_chip_ops(info);
14131413

1414+
info->flags |= MSI_FLAG_ACTIVATE_EARLY;
1415+
14141416
domain = msi_create_irq_domain(fwnode, info, parent);
14151417
if (!domain)
14161418
return NULL;

include/linux/msi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ enum {
270270
MSI_FLAG_MULTI_PCI_MSI = (1 << 2),
271271
/* Support PCI MSIX interrupts */
272272
MSI_FLAG_PCI_MSIX = (1 << 3),
273+
/* Needs early activate, required for PCI */
274+
MSI_FLAG_ACTIVATE_EARLY = (1 << 4),
273275
};
274276

275277
int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,

kernel/irq/msi.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,17 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
359359
else
360360
dev_dbg(dev, "irq [%d-%d] for MSI\n",
361361
virq, virq + desc->nvec_used - 1);
362+
/*
363+
* This flag is set by the PCI layer as we need to activate
364+
* the MSI entries before the PCI layer enables MSI in the
365+
* card. Otherwise the card latches a random msi message.
366+
*/
367+
if (info->flags & MSI_FLAG_ACTIVATE_EARLY) {
368+
struct irq_data *irq_data;
369+
370+
irq_data = irq_domain_get_irq_data(domain, desc->irq);
371+
irq_domain_activate_irq(irq_data);
372+
}
362373
}
363374

364375
return 0;

0 commit comments

Comments
 (0)