diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 3a6f895686..769afa0600 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1328,6 +1328,10 @@ static void machvirt_init(MachineState *machine) object_property_set_bool(cpuobj, false, "has_el3", NULL); } + if (object_property_find(cpuobj, "has_el2", NULL)) { + object_property_set_bool(cpuobj, false, "has_el2", NULL); + } + if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED) { object_property_set_int(cpuobj, vms->psci_conduit, "psci-conduit", NULL); diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index 0d86ba35ae..bc4e66b862 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -258,6 +258,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) object_property_set_bool(OBJECT(&s->apu_cpu[i]), s->secure, "has_el3", NULL); + object_property_set_bool(OBJECT(&s->apu_cpu[i]), + false, "has_el2", NULL); object_property_set_int(OBJECT(&s->apu_cpu[i]), GIC_BASE_ADDR, "reset-cbar", &error_abort); object_property_set_bool(OBJECT(&s->apu_cpu[i]), true, "realized", diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 93ebbc92af..3f2cdb65bf 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -496,6 +496,9 @@ static Property arm_cpu_reset_hivecs_property = static Property arm_cpu_rvbar_property = DEFINE_PROP_UINT64("rvbar", ARMCPU, rvbar, 0); +static Property arm_cpu_has_el2_property = + DEFINE_PROP_BOOL("has_el2", ARMCPU, has_el2, true); + static Property arm_cpu_has_el3_property = DEFINE_PROP_BOOL("has_el3", ARMCPU, has_el3, true); @@ -546,6 +549,11 @@ static void arm_cpu_post_init(Object *obj) #endif } + if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) { + qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el2_property, + &error_abort); + } + if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) { qdev_property_add_static(DEVICE(obj), &arm_cpu_has_pmu_property, &error_abort); @@ -694,6 +702,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) cpu->id_aa64pfr0 &= ~0xf000; } + if (!cpu->has_el2) { + unset_feature(env, ARM_FEATURE_EL2); + } + if (!cpu->has_pmu || !kvm_enabled()) { cpu->has_pmu = false; unset_feature(env, ARM_FEATURE_PMU); diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 16c7c10bfb..151a5d754e 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -577,6 +577,8 @@ struct ARMCPU { bool start_powered_off; /* CPU currently in PSCI powered-off state */ bool powered_off; + /* CPU has virtualization extension */ + bool has_el2; /* CPU has security extension */ bool has_el3; /* CPU has PMU (Performance Monitor Unit) */ diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 73c7f318ec..670c07ab6e 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -110,6 +110,7 @@ static void aarch64_a57_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V8_SHA256); set_feature(&cpu->env, ARM_FEATURE_V8_PMULL); set_feature(&cpu->env, ARM_FEATURE_CRC); + set_feature(&cpu->env, ARM_FEATURE_EL2); set_feature(&cpu->env, ARM_FEATURE_EL3); set_feature(&cpu->env, ARM_FEATURE_PMU); cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A57; @@ -169,6 +170,7 @@ static void aarch64_a53_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V8_SHA256); set_feature(&cpu->env, ARM_FEATURE_V8_PMULL); set_feature(&cpu->env, ARM_FEATURE_CRC); + set_feature(&cpu->env, ARM_FEATURE_EL2); set_feature(&cpu->env, ARM_FEATURE_EL3); set_feature(&cpu->env, ARM_FEATURE_PMU); cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A53;