diff options
-rw-r--r-- | target/arm/cpu64.c | 12 | ||||
-rw-r--r-- | target/arm/kvm64.c | 9 | ||||
-rw-r--r-- | target/arm/kvm_arm.h | 14 |
3 files changed, 29 insertions, 6 deletions
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index ee55237a9b..ab63115c77 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -426,13 +426,13 @@ static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp) * restriction allows us to avoid fixing up functionality that assumes a * uniform execution state like do_interrupt. */ - if (!kvm_enabled()) { - error_setg(errp, "'aarch64' feature cannot be disabled " - "unless KVM is enabled"); - return; - } - if (value == false) { + if (!kvm_enabled() || !kvm_arm_aarch32_supported(CPU(cpu))) { + error_setg(errp, "'aarch64' feature cannot be disabled " + "unless KVM is enabled and 32-bit EL1 " + "is supported"); + return; + } unset_feature(&cpu->env, ARM_FEATURE_AARCH64); } else { set_feature(&cpu->env, ARM_FEATURE_AARCH64); diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 22d19c9aec..3d91846beb 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -24,7 +24,9 @@ #include "exec/gdbstub.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.h" +#include "sysemu/kvm_int.h" #include "kvm_arm.h" +#include "hw/boards.h" #include "internals.h" static bool have_guest_debug; @@ -593,6 +595,13 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) return true; } +bool kvm_arm_aarch32_supported(CPUState *cpu) +{ + KVMState *s = KVM_STATE(current_machine->accelerator); + + return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT); +} + #define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5 int kvm_arch_init_vcpu(CPUState *cs) diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 2a07333c61..98af1050a7 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -208,6 +208,15 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf); void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu); /** + * kvm_arm_aarch32_supported: + * @cs: CPUState + * + * Returns: true if the KVM VCPU can enable AArch32 mode + * and false otherwise. + */ +bool kvm_arm_aarch32_supported(CPUState *cs); + +/** * kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the * IPA address space supported by KVM * @@ -247,6 +256,11 @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) cpu->host_cpu_probe_failed = true; } +static inline bool kvm_arm_aarch32_supported(CPUState *cs) +{ + return false; +} + static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms) { return -ENOENT; |