xen/arch/arm/gic-v3.c | 14 +++++++++----- xen/arch/arm/include/asm/gic_v3_defs.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-)
From: Mykola Kvach <mykola_kvach@epam.com>
gicv3_do_wait_for_rwp() is used for both distributor and
redistributor writes. The CTLR register is at offset 0 for both,
but the RWP bit is not in the same position.
For GICD_CTLR, RWP is bit 31. For GICR_CTLR, bit 31 is UWP,
while RWP is bit 3. The redistributor wait path was therefore
polling UWP instead of RWP.
UWP covers upstream writes, including Generate SGI packets, and is
not a substitute for redistributor register write completion. The
existing redistributor callers need RWP semantics for redistributor
register writes such as GICR_ICENABLER0 and GICR_CTLR updates.
Add GICR_CTLR_RWP and pass the expected RWP bit to the shared
helper.
Fixes: bc183a0235e ("xen/arm: Add support for GIC v3")
Reported-by: Luca Fancellu <luca.fancellu@arm.com>
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
---
xen/arch/arm/gic-v3.c | 14 +++++++++-----
xen/arch/arm/include/asm/gic_v3_defs.h | 1 +
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 7f365cdbe9..dfd5d44603 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -274,16 +274,20 @@ static void gicv3_enable_sre(void)
isb();
}
-/* Wait for completion of a distributor change */
-static void gicv3_do_wait_for_rwp(void __iomem *base)
+/* Wait for completion of a distributor/redistributor change */
+static void gicv3_do_wait_for_rwp(void __iomem *base, uint32_t rwp_bit)
{
uint32_t val;
bool timeout = false;
s_time_t deadline = NOW() + MILLISECS(1000);
do {
+ /*
+ * GICD_CTLR and GICR_CTLR are both at offset 0, so this is
+ * valid for either a distributor or redistributor base.
+ */
val = readl_relaxed(base + GICD_CTLR);
- if ( !(val & GICD_CTLR_RWP) )
+ if ( !(val & rwp_bit) )
break;
if ( NOW() > deadline )
{
@@ -300,12 +304,12 @@ static void gicv3_do_wait_for_rwp(void __iomem *base)
static void gicv3_dist_wait_for_rwp(void)
{
- gicv3_do_wait_for_rwp(GICD);
+ gicv3_do_wait_for_rwp(GICD, GICD_CTLR_RWP);
}
static void gicv3_redist_wait_for_rwp(void)
{
- gicv3_do_wait_for_rwp(GICD_RDIST_BASE);
+ gicv3_do_wait_for_rwp(GICD_RDIST_BASE, GICR_CTLR_RWP);
}
static void gicv3_wait_for_rwp(int irq)
diff --git a/xen/arch/arm/include/asm/gic_v3_defs.h b/xen/arch/arm/include/asm/gic_v3_defs.h
index c373b94d19..3714cfeb7d 100644
--- a/xen/arch/arm/include/asm/gic_v3_defs.h
+++ b/xen/arch/arm/include/asm/gic_v3_defs.h
@@ -146,6 +146,7 @@
#define GICR_NSACR (0x0E00)
#define GICR_CTLR_ENABLE_LPIS (1U << 0)
+#define GICR_CTLR_RWP (1U << 3)
#define GICR_TYPER_PLPIS (1U << 0)
#define GICR_TYPER_VLPIS (1U << 1)
--
2.43.0
On 14-May-26 11:08, Mykola Kvach wrote:
> From: Mykola Kvach <mykola_kvach@epam.com>
>
> gicv3_do_wait_for_rwp() is used for both distributor and
> redistributor writes. The CTLR register is at offset 0 for both,
> but the RWP bit is not in the same position.
>
> For GICD_CTLR, RWP is bit 31. For GICR_CTLR, bit 31 is UWP,
> while RWP is bit 3. The redistributor wait path was therefore
> polling UWP instead of RWP.
>
> UWP covers upstream writes, including Generate SGI packets, and is
> not a substitute for redistributor register write completion. The
> existing redistributor callers need RWP semantics for redistributor
> register writes such as GICR_ICENABLER0 and GICR_CTLR updates.
>
> Add GICR_CTLR_RWP and pass the expected RWP bit to the shared
> helper.
>
> Fixes: bc183a0235e ("xen/arm: Add support for GIC v3")
> Reported-by: Luca Fancellu <luca.fancellu@arm.com>
> Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Good, now it matches what Linux did a few years ago:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0df6664
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
~Michal
Hi Mykola,
> On 14 May 2026, at 10:08, Mykola Kvach <xakep.amatop@gmail.com> wrote:
>
> From: Mykola Kvach <mykola_kvach@epam.com>
>
> gicv3_do_wait_for_rwp() is used for both distributor and
> redistributor writes. The CTLR register is at offset 0 for both,
> but the RWP bit is not in the same position.
>
> For GICD_CTLR, RWP is bit 31. For GICR_CTLR, bit 31 is UWP,
> while RWP is bit 3. The redistributor wait path was therefore
> polling UWP instead of RWP.
>
> UWP covers upstream writes, including Generate SGI packets, and is
> not a substitute for redistributor register write completion. The
> existing redistributor callers need RWP semantics for redistributor
> register writes such as GICR_ICENABLER0 and GICR_CTLR updates.
>
> Add GICR_CTLR_RWP and pass the expected RWP bit to the shared
> helper.
>
> Fixes: bc183a0235e ("xen/arm: Add support for GIC v3")
> Reported-by: Luca Fancellu <luca.fancellu@arm.com>
> Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
> ---
This looks ok to me
Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
Cheers,
Luca
Oleksii, can we have a release ack for this fix?
On Fri, 15 May 2026, Luca Fancellu wrote:
> Hi Mykola,
>
> > On 14 May 2026, at 10:08, Mykola Kvach <xakep.amatop@gmail.com> wrote:
> >
> > From: Mykola Kvach <mykola_kvach@epam.com>
> >
> > gicv3_do_wait_for_rwp() is used for both distributor and
> > redistributor writes. The CTLR register is at offset 0 for both,
> > but the RWP bit is not in the same position.
> >
> > For GICD_CTLR, RWP is bit 31. For GICR_CTLR, bit 31 is UWP,
> > while RWP is bit 3. The redistributor wait path was therefore
> > polling UWP instead of RWP.
> >
> > UWP covers upstream writes, including Generate SGI packets, and is
> > not a substitute for redistributor register write completion. The
> > existing redistributor callers need RWP semantics for redistributor
> > register writes such as GICR_ICENABLER0 and GICR_CTLR updates.
> >
> > Add GICR_CTLR_RWP and pass the expected RWP bit to the shared
> > helper.
> >
> > Fixes: bc183a0235e ("xen/arm: Add support for GIC v3")
> > Reported-by: Luca Fancellu <luca.fancellu@arm.com>
> > Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
> > ---
>
> This looks ok to me
>
> Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
>
> Cheers,
> Luca
>
On 5/15/26 11:36 PM, Stefano Stabellini wrote:
> Oleksii, can we have a release ack for this fix?
Release-Acked-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Thanks.
~ Oleksii
>
> On Fri, 15 May 2026, Luca Fancellu wrote:
>> Hi Mykola,
>>
>>> On 14 May 2026, at 10:08, Mykola Kvach <xakep.amatop@gmail.com> wrote:
>>>
>>> From: Mykola Kvach <mykola_kvach@epam.com>
>>>
>>> gicv3_do_wait_for_rwp() is used for both distributor and
>>> redistributor writes. The CTLR register is at offset 0 for both,
>>> but the RWP bit is not in the same position.
>>>
>>> For GICD_CTLR, RWP is bit 31. For GICR_CTLR, bit 31 is UWP,
>>> while RWP is bit 3. The redistributor wait path was therefore
>>> polling UWP instead of RWP.
>>>
>>> UWP covers upstream writes, including Generate SGI packets, and is
>>> not a substitute for redistributor register write completion. The
>>> existing redistributor callers need RWP semantics for redistributor
>>> register writes such as GICR_ICENABLER0 and GICR_CTLR updates.
>>>
>>> Add GICR_CTLR_RWP and pass the expected RWP bit to the shared
>>> helper.
>>>
>>> Fixes: bc183a0235e ("xen/arm: Add support for GIC v3")
>>> Reported-by: Luca Fancellu <luca.fancellu@arm.com>
>>> Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
>>> ---
>>
>> This looks ok to me
>>
>> Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
>>
>> Cheers,
>> Luca
>>
© 2016 - 2026 Red Hat, Inc.