Skip to content

Commit 548183e

Browse files
sean-jcjoergroedel
authored andcommitted
iommu/vt-d: Wire up irq_ack() to irq_move_irq() for posted MSIs
Set the posted MSI irq_chip's irq_ack() hook to irq_move_irq() instead of a dummy/empty callback so that posted MSIs process pending changes to the IRQ's SMP affinity. Failure to honor a pending set-affinity results in userspace being unable to change the effective affinity of the IRQ, as IRQD_SETAFFINITY_PENDING is never cleared and so irq_set_affinity_locked() always defers moving the IRQ. The issue is most easily reproducible by setting /proc/irq/xx/smp_affinity multiple times in quick succession, as only the first update is likely to be handled in process context. Fixes: ed1e48e ("iommu/vt-d: Enable posted mode for device MSIs") Cc: Robert Lippert <rlippert@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Reported-by: Wentao Yang <wentaoyang@google.com> Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson <seanjc@google.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20250321194249.1217961-1-seanjc@google.com Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent df4bf3f commit 548183e

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

drivers/iommu/intel/irq_remapping.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,43 +1287,44 @@ static struct irq_chip intel_ir_chip = {
12871287
};
12881288

12891289
/*
1290-
* With posted MSIs, all vectors are multiplexed into a single notification
1291-
* vector. Devices MSIs are then dispatched in a demux loop where
1292-
* EOIs can be coalesced as well.
1290+
* With posted MSIs, the MSI vectors are multiplexed into a single notification
1291+
* vector, and only the notification vector is sent to the APIC IRR. Device
1292+
* MSIs are then dispatched in a demux loop that harvests the MSIs from the
1293+
* CPU's Posted Interrupt Request bitmap. I.e. Posted MSIs never get sent to
1294+
* the APIC IRR, and thus do not need an EOI. The notification handler instead
1295+
* performs a single EOI after processing the PIR.
12931296
*
1294-
* "INTEL-IR-POST" IRQ chip does not do EOI on ACK, thus the dummy irq_ack()
1295-
* function. Instead EOI is performed by the posted interrupt notification
1296-
* handler.
1297+
* Note! Pending SMP/CPU affinity changes, which are per MSI, must still be
1298+
* honored, only the APIC EOI is omitted.
12971299
*
12981300
* For the example below, 3 MSIs are coalesced into one CPU notification. Only
1299-
* one apic_eoi() is needed.
1301+
* one apic_eoi() is needed, but each MSI needs to process pending changes to
1302+
* its CPU affinity.
13001303
*
13011304
* __sysvec_posted_msi_notification()
13021305
* irq_enter();
13031306
* handle_edge_irq()
13041307
* irq_chip_ack_parent()
1305-
* dummy(); // No EOI
1308+
* irq_move_irq(); // No EOI
13061309
* handle_irq_event()
13071310
* driver_handler()
13081311
* handle_edge_irq()
13091312
* irq_chip_ack_parent()
1310-
* dummy(); // No EOI
1313+
* irq_move_irq(); // No EOI
13111314
* handle_irq_event()
13121315
* driver_handler()
13131316
* handle_edge_irq()
13141317
* irq_chip_ack_parent()
1315-
* dummy(); // No EOI
1318+
* irq_move_irq(); // No EOI
13161319
* handle_irq_event()
13171320
* driver_handler()
13181321
* apic_eoi()
13191322
* irq_exit()
1323+
*
13201324
*/
1321-
1322-
static void dummy_ack(struct irq_data *d) { }
1323-
13241325
static struct irq_chip intel_ir_chip_post_msi = {
13251326
.name = "INTEL-IR-POST",
1326-
.irq_ack = dummy_ack,
1327+
.irq_ack = irq_move_irq,
13271328
.irq_set_affinity = intel_ir_set_affinity,
13281329
.irq_compose_msi_msg = intel_ir_compose_msi_msg,
13291330
.irq_set_vcpu_affinity = intel_ir_set_vcpu_affinity,

0 commit comments

Comments
 (0)