Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 8f4b589

Browse files
jgowansMarc Zyngier
authored andcommitted
irqchip/gic-v3-its: Enable RESEND_WHEN_IN_PROGRESS for LPIs
GICv3 LPIs are impacted by an architectural design issue: they do not have a global active state and as such a given LPI can be delivered to a new CPU after an affinity change while the previous instance of the same LPI handler has not yet completed on the original CPU. If LPIs had an active state, this second LPI would not be delivered until the first CPU deactivated the initial LPI, just like SPIs. To solve this issue, use the newly introduced IRQD_RESEND_WHEN_IN_PROGRESS flag, ensuring that we do not lose an LPI being delivered during that window by getting the GIC to resend it. This workaround gets enabled for all LPIs, including the VPE doorbells. Suggested-by: Marc Zyngier <[email protected]> Signed-off-by: James Gowans <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Marc Zyngier <[email protected]> Cc: KarimAllah Raslan <[email protected]> Cc: Yipeng Zou <[email protected]> Cc: Zhang Jianhua <[email protected]> [maz: massaged commit message] Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 9c15eeb commit 8f4b589

File tree

1 file changed

+2
-0
lines changed

1 file changed

+2
-0
lines changed

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3585,6 +3585,7 @@ static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
35853585
irqd = irq_get_irq_data(virq + i);
35863586
irqd_set_single_target(irqd);
35873587
irqd_set_affinity_on_activate(irqd);
3588+
irqd_set_resend_when_in_progress(irqd);
35883589
pr_debug("ID:%d pID:%d vID:%d\n",
35893590
(int)(hwirq + i - its_dev->event_map.lpi_base),
35903591
(int)(hwirq + i), virq + i);
@@ -4523,6 +4524,7 @@ static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq
45234524
irq_domain_set_hwirq_and_chip(domain, virq + i, i,
45244525
irqchip, vm->vpes[i]);
45254526
set_bit(i, bitmap);
4527+
irqd_set_resend_when_in_progress(irq_get_irq_data(virq + i));
45264528
}
45274529

45284530
if (err) {

0 commit comments

Comments
 (0)