Skip to content

Commit ff363f4

Browse files
committed
x86/msi: Force affinity setup before startup
The X86 MSI mechanism cannot handle interrupt affinity changes safely after startup other than from an interrupt handler, unless interrupt remapping is enabled. The startup sequence in the generic interrupt code violates that assumption. Mark the irq chips with the new IRQCHIP_AFFINITY_PRE_STARTUP flag so that the default interrupt setting happens before the interrupt is started up for the first time. While the interrupt remapping MSI chip does not require this, there is no point in treating it differently as this might spare an interrupt to a CPU which is not in the default affinity mask. For the non-remapping case go to the direct write path when the interrupt is not yet started similar to the not yet activated case. Fixes: 1840475 ("genirq: Expose default irq affinity mask (take 3)") Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Marc Zyngier <[email protected]> Reviewed-by: Marc Zyngier <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected]
1 parent 0c0e37d commit ff363f4

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

arch/x86/kernel/apic/msi.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,13 @@ msi_set_affinity(struct irq_data *irqd, const struct cpumask *mask, bool force)
5858
* The quirk bit is not set in this case.
5959
* - The new vector is the same as the old vector
6060
* - The old vector is MANAGED_IRQ_SHUTDOWN_VECTOR (interrupt starts up)
61+
* - The interrupt is not yet started up
6162
* - The new destination CPU is the same as the old destination CPU
6263
*/
6364
if (!irqd_msi_nomask_quirk(irqd) ||
6465
cfg->vector == old_cfg.vector ||
6566
old_cfg.vector == MANAGED_IRQ_SHUTDOWN_VECTOR ||
67+
!irqd_is_started(irqd) ||
6668
cfg->dest_apicid == old_cfg.dest_apicid) {
6769
irq_msi_update_msg(irqd, cfg);
6870
return ret;
@@ -150,7 +152,8 @@ static struct irq_chip pci_msi_controller = {
150152
.irq_ack = irq_chip_ack_parent,
151153
.irq_retrigger = irq_chip_retrigger_hierarchy,
152154
.irq_set_affinity = msi_set_affinity,
153-
.flags = IRQCHIP_SKIP_SET_WAKE,
155+
.flags = IRQCHIP_SKIP_SET_WAKE |
156+
IRQCHIP_AFFINITY_PRE_STARTUP,
154157
};
155158

156159
int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
@@ -219,7 +222,8 @@ static struct irq_chip pci_msi_ir_controller = {
219222
.irq_mask = pci_msi_mask_irq,
220223
.irq_ack = irq_chip_ack_parent,
221224
.irq_retrigger = irq_chip_retrigger_hierarchy,
222-
.flags = IRQCHIP_SKIP_SET_WAKE,
225+
.flags = IRQCHIP_SKIP_SET_WAKE |
226+
IRQCHIP_AFFINITY_PRE_STARTUP,
223227
};
224228

225229
static struct msi_domain_info pci_msi_ir_domain_info = {
@@ -273,7 +277,8 @@ static struct irq_chip dmar_msi_controller = {
273277
.irq_retrigger = irq_chip_retrigger_hierarchy,
274278
.irq_compose_msi_msg = dmar_msi_compose_msg,
275279
.irq_write_msi_msg = dmar_msi_write_msg,
276-
.flags = IRQCHIP_SKIP_SET_WAKE,
280+
.flags = IRQCHIP_SKIP_SET_WAKE |
281+
IRQCHIP_AFFINITY_PRE_STARTUP,
277282
};
278283

279284
static int dmar_msi_init(struct irq_domain *domain,

arch/x86/kernel/hpet.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ static struct irq_chip hpet_msi_controller __ro_after_init = {
508508
.irq_set_affinity = msi_domain_set_affinity,
509509
.irq_retrigger = irq_chip_retrigger_hierarchy,
510510
.irq_write_msi_msg = hpet_msi_write_msg,
511-
.flags = IRQCHIP_SKIP_SET_WAKE,
511+
.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_AFFINITY_PRE_STARTUP,
512512
};
513513

514514
static int hpet_msi_init(struct irq_domain *domain,

0 commit comments

Comments
 (0)