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


Reply via email to