@samitouri / QOSamiQemu / commits / 6c86e20591

hw/intc/arm_gicv3_cpuif: Don't allow GICv3 if CPU has GICv5 cpuif

The GICv3 and GICv5 CPU interfaces are not compatible, and a CPU will only implement either one or the other. If we find that we're trying to connect a GICv3 to a CPU that implements FEAT_GCIE, fail. This will only happen if the board code has a bug and doesn't configure its CPUs and its GIC consistently. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Message-id: 20260327111700.795099-56-peter.maydell@linaro.org

Peter Maydell committed Mar 27, 2026 at 11:16 UTC 6c86e20591aa37619bef7153936497008a9722d7
3 files changed +15 -3
hw/intc/arm_gicv3.c
+1 -1
@@ -449,7 +449,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
449
450 gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops);
451
452 - gicv3_init_cpuif(s);
452 + gicv3_init_cpuif(s, errp);
453 }
454
455 static void arm_gicv3_class_init(ObjectClass *klass, const void *data)
hw/intc/arm_gicv3_cpuif.c
+13 -1
@@ -16,6 +16,7 @@
16 #include "qemu/bitops.h"
17 #include "qemu/log.h"
18 #include "qemu/main-loop.h"
19 +#include "qapi/error.h"
20 #include "trace.h"
21 #include "gicv3_internal.h"
22 #include "hw/core/irq.h"
@@ -3047,7 +3048,7 @@ static void gicv3_cpuif_el_change_hook(ARMCPU *cpu, void *opaque)
3048 gicv3_cpuif_virt_irq_fiq_update(cs);
3049 }
3050
3050 -void gicv3_init_cpuif(GICv3State *s)
3051 +void gicv3_init_cpuif(GICv3State *s, Error **errp)
3052 {
3053 /* Called from the GICv3 realize function; register our system
3054 * registers with the CPU
@@ -3058,6 +3059,17 @@ void gicv3_init_cpuif(GICv3State *s)
3059 ARMCPU *cpu = ARM_CPU(qemu_get_cpu(s->first_cpu_idx + i));
3060 GICv3CPUState *cs = &s->cpu[i];
3061
3062 + if (cpu_isar_feature(aa64_gcie, cpu)) {
3063 + /*
3064 + * Attempt to connect GICv3 to a CPU with GICv5 cpuif
3065 + * (almost certainly a bug in the board code)
3066 + */
3067 + error_setg(errp,
3068 + "Cannot connect GICv3 to CPU %d which has GICv5 cpuif",
3069 + i);
3070 + return;
3071 + }
3072 +
3073 /*
3074 * If the CPU doesn't define a GICv3 configuration, probably because
3075 * in real hardware it doesn't have one, then we use default values
hw/intc/gicv3_internal.h
+1 -1
@@ -722,7 +722,7 @@ void gicv3_redist_mov_vlpi(GICv3CPUState *src, uint64_t src_vptaddr,
722 void gicv3_redist_vinvall(GICv3CPUState *cs, uint64_t vptaddr);
723
724 void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
725 -void gicv3_init_cpuif(GICv3State *s);
725 +void gicv3_init_cpuif(GICv3State *s, Error **errp);
726
727 /**
728 * gicv3_cpuif_update: