From: Marc Zyngier maz@kernel.org
mainline inclusion from mainline-5.10 commit cd1752d34ef33d68d82ef9dcc699b4eaa17c07fc category: bugfix bugzilla: NA CVE: NA
-------------------------------------------------
On resending an interrupt, we only check the outermost irqchip for a irq_retrigger callback. However, this callback could be implemented at an inner level. Use irq_chip_retrigger_hierarchy() in this case.
Reviewed-by: Valentin Schneider valentin.schneider@arm.com Signed-off-by: Marc Zyngier maz@kernel.org Signed-off-by: Liao Chang liaochang1@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- kernel/irq/resend.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c index 5064b13b80d60..34f79ddfef182 100644 --- a/kernel/irq/resend.c +++ b/kernel/irq/resend.c @@ -49,6 +49,18 @@ static DECLARE_TASKLET(resend_tasklet, resend_irqs, 0);
#endif
+static int try_retrigger(struct irq_desc *desc) +{ + if (desc->irq_data.chip->irq_retrigger) + return desc->irq_data.chip->irq_retrigger(&desc->irq_data); + +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY + return irq_chip_retrigger_hierarchy(&desc->irq_data); +#else + return 0; +#endif +} + /* * IRQ resend * @@ -72,9 +84,7 @@ void check_irq_resend(struct irq_desc *desc) desc->istate &= ~IRQS_PENDING; desc->istate |= IRQS_REPLAY;
- if ((!desc->irq_data.chip->irq_retrigger || - !desc->irq_data.chip->irq_retrigger(&desc->irq_data)) && - !handle_enforce_irqctx(&desc->irq_data)) { + if (!try_retrigger(desc)) { #ifdef CONFIG_HARDIRQS_SW_RESEND unsigned int irq = irq_desc_get_irq(desc);