Re: [PATCH 03/10] irqchip/gic-v5: Serialise IRS synchronisation requests

From: Lorenzo Pieralisi

Date: Tue Nov 03 2026 - 04:21:28 EST


On Mon, Nov 02, 2026 at 01:32:56PM +0000, Sascha Bischoff wrote:
> IRS_SYNCR writes are ignored while IRS_SYNC_STATUSR.IDLE is clear.
> Calls to gicv5_irs_syncr() for different IRQs can overlap, allowing
> the second request to be dropped. Its caller can then observe the
> first request completing and assume that its own events have been
> processed.
>
> Serialise the request and completion poll with a raw spinlock. We use
> atomic polling, as the lock cannot be held over a sleeping wait.
>
> Fixes: 57d72196dfc8 ("irqchip/gic-v5: Add GICv5 ITS support")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Sascha Bischoff <sascha.bischoff@xxxxxxx>
> ---
> drivers/irqchip/irq-gic-v5-irs.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/irqchip/irq-gic-v5-irs.c b/drivers/irqchip/irq-gic-v5-irs.c
> index 4edf787f3f97f..ead76560ea08f 100644
> --- a/drivers/irqchip/irq-gic-v5-irs.c
> +++ b/drivers/irqchip/irq-gic-v5-irs.c
> @@ -10,6 +10,7 @@
> #include <linux/log2.h>
> #include <linux/of.h>
> #include <linux/of_address.h>
> +#include <linux/spinlock.h>
>
> #include <linux/irqchip.h>
> #include <linux/irqchip/arm-gic-v5.h>
> @@ -22,6 +23,8 @@
> #define LPI_ID_BITS_LINEAR 12
>
> static DEFINE_PER_CPU_READ_MOSTLY(struct gicv5_irs_chip_data *, per_cpu_irs_data);
> +/* Synchronization requests must not overlap in an IRS Domain. */
> +static DEFINE_RAW_SPINLOCK(irs_sync_lock);
> static LIST_HEAD(irs_nodes);
>
> static u32 irs_readl_relaxed(struct gicv5_irs_chip_data *irs_data,
> @@ -507,10 +510,11 @@ void gicv5_irs_syncr(void)
> return;
>
> syncr = FIELD_PREP(GICV5_IRS_SYNCR_SYNC, 1);
> + guard(raw_spinlock_irqsave)(&irs_sync_lock);

Why does it have to be a spinlock ?

Thanks,
Lorenzo

> irs_writel_relaxed(irs_data, syncr, GICV5_IRS_SYNCR);
>
> - gicv5_wait_for_op(irs_data->irs_base, GICV5_IRS_SYNC_STATUSR,
> - GICV5_IRS_SYNC_STATUSR_IDLE);
> + gicv5_wait_for_op_atomic(irs_data->irs_base, GICV5_IRS_SYNC_STATUSR,
> + GICV5_IRS_SYNC_STATUSR_IDLE, NULL);
> }
>
> int gicv5_irs_register_cpu(int cpuid)
>
> --
> 2.34.1
>