[PATCH] xen/arm: gic-v3: Preserve ARE_NS when disabling the distributor

Mykola Kvach posted 1 patch 4 days, 5 hours ago
Patches applied successfully (tree, apply log)
git fetch https://gitlab.com/xen-project/patchew/xen tags/patchew/0bc584018c025ee9fa5557276b9f3914ca9205d4.1779200467.git.mykola._5Fkvach@epam.com
xen/arch/arm/gic-v3.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
[PATCH] xen/arm: gic-v3: Preserve ARE_NS when disabling the distributor
Posted by Mykola Kvach 4 days, 5 hours ago
From: Mykola Kvach <mykola_kvach@epam.com>

gicv3_dist_init() disables the distributor before reprogramming the
global interrupt state. It used to do this by writing 0 to GICD_CTLR.

On a system where firmware has already enabled Non-secure affinity
routing, a zero write clears the Non-secure view's GICD_CTLR.ARE_NS bit.
Arm IHI 0069H.b, section 2.3.3 ("Changing affinity routing enables"),
states that changing GICD_CTLR.ARE_NS from 1 to 0 is UNPREDICTABLE. The
GICD_CTLR register description in section 12.9.4 carries the same rule
for the ARE_NS field.

Preserve ARE_NS while clearing the group enable bits. If firmware left
ARE_NS clear, the value written is still 0, preserving the existing
initialization flow.

Fixes: bc183a0235e0 ("xen/arm: Add support for GIC v3")
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
---
 xen/arch/arm/gic-v3.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 7f365cdbe9..dc00afc0ee 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -745,12 +745,17 @@ static void __init gicv3_dist_espi_init_aff(uint64_t affinity) { }
 static void __init gicv3_dist_init(void)
 {
     uint32_t type;
+    uint32_t ctlr;
     uint64_t affinity;
     unsigned int nr_lines;
     int i;
 
-    /* Disable the distributor */
-    writel_relaxed(0, GICD + GICD_CTLR);
+    /*
+     * Disable the distributor without clearing ARE_NS. The GIC architecture
+     * makes changing ARE_NS from 1 to 0 UNPREDICTABLE.
+     */
+    ctlr = readl_relaxed(GICD + GICD_CTLR);
+    writel_relaxed(ctlr & GICD_CTLR_ARE_NS, GICD + GICD_CTLR);
 
     type = readl_relaxed(GICD + GICD_TYPER);
     nr_lines = 32 * ((type & GICD_TYPE_LINES) + 1);
-- 
2.43.0
Re: [PATCH] xen/arm: gic-v3: Preserve ARE_NS when disabling the distributor
Posted by Luca Fancellu 3 days, 23 hours ago
Hi Mykola,

> On 19 May 2026, at 15:31, Mykola Kvach <xakep.amatop@gmail.com> wrote:
> 
> From: Mykola Kvach <mykola_kvach@epam.com>
> 
> gicv3_dist_init() disables the distributor before reprogramming the
> global interrupt state. It used to do this by writing 0 to GICD_CTLR.
> 
> On a system where firmware has already enabled Non-secure affinity
> routing, a zero write clears the Non-secure view's GICD_CTLR.ARE_NS bit.
> Arm IHI 0069H.b, section 2.3.3 ("Changing affinity routing enables"),
> states that changing GICD_CTLR.ARE_NS from 1 to 0 is UNPREDICTABLE. The
> GICD_CTLR register description in section 12.9.4 carries the same rule
> for the ARE_NS field.
> 
> Preserve ARE_NS while clearing the group enable bits. If firmware left
> ARE_NS clear, the value written is still 0, preserving the existing
> initialization flow.
> 
> Fixes: bc183a0235e0 ("xen/arm: Add support for GIC v3")
> Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
> ---

Looks ok to me and aligned to the specifications, bit 4 is preserved on both
Armv8-A (ARE_NS) and Armv8-R (ARE).

Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>

Cheers,
Luca