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: