[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, ®);
+ 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, ®);
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