aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2022-05-12 16:14:52 +0100
committerPeter Maydell <peter.maydell@linaro.org>2022-05-19 16:19:02 +0100
commit272f75e89088c968c861fef516a4ebc70846dcd5 (patch)
treeaebe964a171ba3ac1df69e6fb64210db21e44294
parent3d52472f81f0e0684fcab238ab816faeee6b8bcd (diff)
hw/intc/arm_gicv3_cpuif: Handle CPUs that don't specify GICv3 parameters
We allow a GICv3 to be connected to any CPU, but we don't do anything to handle the case where the CPU type doesn't in hardware have a GICv3 CPU interface and so the various GIC configuration fields (gic_num_lrs, vprebits, vpribits) are not specified. The current behaviour is that we will add the EL1 CPU interface registers, but will not put in the EL2 CPU interface registers, even if the CPU has EL2, which will leave the GIC in a broken state and probably result in the guest crashing as it tries to set it up. This only affects the virt board when using the cortex-a15 or cortex-a7 CPU types (both 32-bit) with -machine gic-version=3 (or 'max') and -machine virtualization=on. Instead of failing to set up the EL2 registers, if the CPU doesn't define the GIC configuration set it to a reasonable default, matching the standard configuration for most Arm CPUs. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20220512151457.3899052-2-peter.maydell@linaro.org
-rw-r--r--hw/intc/arm_gicv3_cpuif.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
index 9efba798f8..df2f858356 100644
--- a/hw/intc/arm_gicv3_cpuif.c
+++ b/hw/intc/arm_gicv3_cpuif.c
@@ -2755,6 +2755,15 @@ void gicv3_init_cpuif(GICv3State *s)
ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));
GICv3CPUState *cs = &s->cpu[i];
+ /*
+ * If the CPU doesn't define a GICv3 configuration, probably because
+ * in real hardware it doesn't have one, then we use default values
+ * matching the one used by most Arm CPUs. This applies to:
+ * cpu->gic_num_lrs
+ * cpu->gic_vpribits
+ * cpu->gic_vprebits
+ */
+
/* Note that we can't just use the GICv3CPUState as an opaque pointer
* in define_arm_cp_regs_with_opaque(), because when we're called back
* it might be with code translated by CPU 0 but run by CPU 1, in
@@ -2763,13 +2772,12 @@ void gicv3_init_cpuif(GICv3State *s)
* get back to the GICv3CPUState from the CPUARMState.
*/
define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
- if (arm_feature(&cpu->env, ARM_FEATURE_EL2)
- && cpu->gic_num_lrs) {
+ if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
int j;
- cs->num_list_regs = cpu->gic_num_lrs;
- cs->vpribits = cpu->gic_vpribits;
- cs->vprebits = cpu->gic_vprebits;
+ cs->num_list_regs = cpu->gic_num_lrs ?: 4;
+ cs->vpribits = cpu->gic_vpribits ?: 5;
+ cs->vprebits = cpu->gic_vprebits ?: 5;
/* Check against architectural constraints: getting these
* wrong would be a bug in the CPU code defining these,