msi_set_affinity() re-injects a pending interrupt on its new target by looking at the outermost domain chip and invoking its irq_retrigger() callback directly, without checking whether that callback is present.
Keep calling the outermost chip's irq_retrigger() when it is present, but fall back to irq_chip_retrigger_hierarchy() otherwise, which walks up the interrupt hierarchy until it finds a chip that implements irq_retrigger(). Suggested-by: Thomas Gleixner <[email protected]> Reviewed-by: Shradha Gupta <[email protected]> Reviewed-by: Thomas Gleixner <[email protected]> Signed-off-by: Naman Jain <[email protected]> --- arch/x86/kernel/apic/msi.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c index 66bc5d3e79db3..66647d51c0473 100644 --- a/arch/x86/kernel/apic/msi.c +++ b/arch/x86/kernel/apic/msi.c @@ -136,8 +136,14 @@ msi_set_affinity(struct irq_data *irqd, const struct cpumask *mask, bool force) * underlying vector store. It's just checking the local APIC's * IRR. */ - if (lapic_vector_set_in_irr(cfg->vector)) - irq_data_get_irq_chip(irqd)->irq_retrigger(irqd); + if (lapic_vector_set_in_irr(cfg->vector)) { + struct irq_chip *chip = irq_data_get_irq_chip(irqd); + + if (chip->irq_retrigger) + chip->irq_retrigger(irqd); + else + irq_chip_retrigger_hierarchy(irqd); + } return ret; } -- 2.43.0
