From 20c5792dc96ed2ae55784b4b761c4233135d308d Mon Sep 17 00:00:00 2001 From: Mykola Kvach Date: Tue, 19 May 2026 17:31:54 +0300 Subject: [PATCH] xen/arm: gic-v3: Preserve ARE_NS when disabling the distributor 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 Reviewed-by: Michal Orzel Reviewed-by: Luca Fancellu Release-Acked-by: Oleksii Kurochko (cherry picked from commit e63ba93511b33c0d3bb8cc5870f946f41e1d2655) --- 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 dfd5d44603..194a984f0b 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -749,12 +749,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);