[kvm-unit-tests PATCH v6 01/14] arm64: fix overflow in gic-v2 initialisation

Joey Gouly joey.gouly at arm.com
Fri Jan 23 08:50:40 PST 2026


The gic-v2 DT bindings can have up to 4 registers, GIC dist base, GIC cpu
interface base, vGIC dist base and vGIC cpu interface base.

QEMU when booting at EL1 fills out the first 2, when booting at EL2 it fills
out all 4 reg values in the DT.

However `struct gicv2_data` only contains fields for 2 bases, causing the loop
over GICV3_NR_REDISTS to write to random areas of memory after `gicv2_data`.

Fix this by only looping if we know it's a gic-v3, and only reading 2 bases if
it's a gic-v2.

Fixes: a5a2d35cba2e ("arm/arm64: gicv3: support up to 8 redistributor regions")
Signed-off-by: Joey Gouly <joey.gouly at arm.com>
---
 lib/arm/gic.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/lib/arm/gic.c b/lib/arm/gic.c
index af43a96d..1b2dc101 100644
--- a/lib/arm/gic.c
+++ b/lib/arm/gic.c
@@ -69,6 +69,16 @@ gic_get_dt_bases(const char *compatible, void **base1, void **base2, void **base
 	assert(ret == 0);
 	*base1 = ioremap(reg.addr, reg.size);
 
+	if (!base3) {
+		assert(!strcmp(compatible, "arm,cortex-a15-gic"));
+		ret = dt_pbus_translate(&gic, 1, &reg);
+		assert(ret == 0);
+		*base2 = ioremap(reg.addr, reg.size);
+		return true;
+	}
+
+	assert(!strcmp(compatible, "arm,gic-v3"));
+
 	for (i = 0; i < GICV3_NR_REDISTS; ++i) {
 		ret = dt_pbus_translate(&gic, i + 1, &reg);
 		if (ret == -FDT_ERR_NOTFOUND)
@@ -77,13 +87,6 @@ gic_get_dt_bases(const char *compatible, void **base1, void **base2, void **base
 		base2[i] = ioremap(reg.addr, reg.size);
 	}
 
-	if (!base3) {
-		assert(!strcmp(compatible, "arm,cortex-a15-gic"));
-		return true;
-	}
-
-	assert(!strcmp(compatible, "arm,gic-v3"));
-
 	dt_for_each_subnode(node, subnode) {
 		const struct fdt_property *prop;
 
-- 
2.25.1




More information about the linux-arm-kernel mailing list