hwaccel_enabled() return whether any hardware accelerator is enabled. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson --- include/system/hw_accel.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/system/hw_accel.h b/include/system/hw_accel.h index fa9228d5d2d..49556b026e0 100644 --- a/include/system/hw_accel.h +++ b/include/system/hw_accel.h @@ -39,4 +39,17 @@ void cpu_synchronize_pre_loadvm(CPUState *cpu); void cpu_synchronize_post_reset(CPUState *cpu); void cpu_synchronize_post_init(CPUState *cpu); +/** + * hwaccel_enabled: + * + * Returns: %true if a hardware accelerator is enabled, %false otherwise. + */ +static inline bool hwaccel_enabled(void) +{ + return hvf_enabled() + || kvm_enabled() + || nvmm_enabled() + || whpx_enabled(); +} + #endif /* QEMU_HW_ACCEL_H */ -- 2.49.0 We should be able to use the 'host' CPU with any hardware accelerator. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Signed-off-by: Mohamed Mediouni Reviewed-by: Pierrick Bouvier --- target/arm/arm-qmp-cmds.c | 5 +++-- target/arm/cpu.c | 5 +++-- target/arm/cpu64.c | 11 ++++++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c index d292c974c44..1142e28cb76 100644 --- a/target/arm/arm-qmp-cmds.c +++ b/target/arm/arm-qmp-cmds.c @@ -31,6 +31,7 @@ #include "qapi/qapi-commands-misc-arm.h" #include "qobject/qdict.h" #include "qom/qom-qobject.h" +#include "system/hw_accel.h" #include "cpu.h" static GICCapability *gic_cap_new(int version) @@ -117,8 +118,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, return NULL; } - if (!kvm_enabled() && !strcmp(model->name, "host")) { - error_setg(errp, "The CPU type '%s' requires KVM", model->name); + if (!hwaccel_enabled() && !strcmp(model->name, "host")) { + error_setg(errp, "The CPU type 'host' requires hardware accelerator"); return NULL; } diff --git a/target/arm/cpu.c b/target/arm/cpu.c index e2b2337399c..d9a8f62934d 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1984,8 +1984,9 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) * this is the first point where we can report it. */ if (cpu->host_cpu_probe_failed) { - if (!kvm_enabled() && !hvf_enabled()) { - error_setg(errp, "The 'host' CPU type can only be used with KVM or HVF"); + if (!hwaccel_enabled()) { + error_setg(errp, "The 'host' CPU type can only be used with " + "hardware accelator such KVM/HVF"); } else { error_setg(errp, "Failed to retrieve host CPU features"); } diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 26cf7e6dfa2..034bbc504cd 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -26,6 +26,7 @@ #include "qemu/units.h" #include "system/kvm.h" #include "system/hvf.h" +#include "system/hw_accel.h" #include "system/qtest.h" #include "system/tcg.h" #include "kvm_arm.h" @@ -522,7 +523,7 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, APA3, 0); isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, GPA3, 0); - if (kvm_enabled() || hvf_enabled()) { + if (hwaccel_enabled()) { /* * Exit early if PAuth is enabled and fall through to disable it. * The algorithm selection properties are not present. @@ -599,10 +600,10 @@ void aarch64_add_pauth_properties(Object *obj) /* Default to PAUTH on, with the architected algorithm on TCG. */ qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_property); - if (kvm_enabled() || hvf_enabled()) { + if (hwaccel_enabled()) { /* * Mirror PAuth support from the probed sysregs back into the - * property for KVM or hvf. Is it just a bit backward? Yes it is! + * property for HW accel. Is it just a bit backward? Yes it is! * Note that prop_pauth is true whether the host CPU supports the * architected QARMA5 algorithm or the IMPDEF one. We don't * provide the separate pauth-impdef property for KVM or hvf, @@ -780,8 +781,8 @@ static void aarch64_host_initfn(Object *obj) static void aarch64_max_initfn(Object *obj) { - if (kvm_enabled() || hvf_enabled()) { - /* With KVM or HVF, '-cpu max' is identical to '-cpu host' */ + if (hwaccel_enabled()) { + /* When hardware acceleration enabled, '-cpu max' is identical to '-cpu host' */ aarch64_host_initfn(obj); return; } -- 2.49.0 Signed-off-by: Philippe Mathieu-Daudé --- target/arm/cpu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index d9a8f62934d..1dc2a8330d8 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1551,7 +1551,6 @@ static const Property arm_cpu_pmsav7_dregion_property = DEFINE_PROP_UNSIGNED_NODEFAULT("pmsav7-dregion", ARMCPU, pmsav7_dregion, qdev_prop_uint32, uint32_t); -#endif static bool arm_get_pmu(Object *obj, Error **errp) { @@ -1576,6 +1575,8 @@ static void arm_set_pmu(Object *obj, bool value, Error **errp) cpu->has_pmu = value; } +#endif + static bool aarch64_cpu_get_aarch64(Object *obj, Error **errp) { ARMCPU *cpu = ARM_CPU(obj); @@ -1771,12 +1772,12 @@ static void arm_cpu_post_init(Object *obj) if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) { qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el2_property); } -#endif if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) { cpu->has_pmu = true; object_property_add_bool(obj, "pmu", arm_get_pmu, arm_set_pmu); } +#endif /* * Allow user to turn off VFP and Neon support, but only for TCG -- -- 2.49.0 From: Mohamed Mediouni Factor hvf_psci_get_target_el() out so it will be easier to allow switching to other EL later. Signed-off-by: Mohamed Mediouni Signed-off-by: Philippe Mathieu-Daudé --- target/arm/hvf/hvf.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 47b0cd3a351..81dc4df686d 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -1107,6 +1107,10 @@ static void hvf_psci_cpu_off(ARMCPU *arm_cpu) assert(ret == QEMU_ARM_POWERCTL_RET_SUCCESS); } +static int hvf_psci_get_target_el(void) +{ + return 1; +} /* * Handle a PSCI call. * @@ -1128,7 +1132,6 @@ static bool hvf_handle_psci_call(CPUState *cpu) CPUState *target_cpu_state; ARMCPU *target_cpu; target_ulong entry; - int target_el = 1; int32_t ret = 0; trace_hvf_psci_call(param[0], param[1], param[2], param[3], @@ -1182,7 +1185,7 @@ static bool hvf_handle_psci_call(CPUState *cpu) entry = param[2]; context_id = param[3]; ret = arm_set_cpu_on(mpidr, entry, context_id, - target_el, target_aarch64); + hvf_psci_get_target_el(), target_aarch64); break; case QEMU_PSCI_0_1_FN_CPU_OFF: case QEMU_PSCI_0_2_FN_CPU_OFF: -- 2.49.0 Introduce arm_hw_accel_cpu_feature_supported() helper, an accelerator implementation to return whether a ARM feature is supported by host hardware. Allow optional fallback on emulation. Signed-off-by: Philippe Mathieu-Daudé --- target/arm/cpu.h | 12 ++++++++++++ target/arm/hvf/hvf.c | 20 ++++++++++++++++++++ target/arm/kvm.c | 22 ++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index dc9b6dce4c9..5136c4caabf 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2507,6 +2507,18 @@ static inline ARMSecuritySpace arm_secure_to_space(bool secure) } #if !defined(CONFIG_USER_ONLY) + +/** + * arm_hw_accel_cpu_feature_supported: + * @feat: Feature to test for support + * @can_emulate: Whether Allow to fall back to emulation if @feat is not + * supported by hardware accelerator + * + * Hardware accelerator implementation of cpu_feature_supported(). + */ +bool arm_hw_accel_cpu_feature_supported(enum arm_features feat, + bool can_emulate); + /** * arm_security_space_below_el3: * @env: cpu context diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 81dc4df686d..5174973991f 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -964,6 +964,26 @@ uint32_t hvf_arm_get_max_ipa_bit_size(void) return round_down_to_parange_bit_size(max_ipa_size); } +bool arm_hw_accel_cpu_feature_supported(enum arm_features feat, bool can_emulate) +{ + if (!hvf_enabled()) { + return false; + } + switch (feat) { + case ARM_FEATURE_V8: + case ARM_FEATURE_NEON: + case ARM_FEATURE_AARCH64: + case ARM_FEATURE_PMU: + case ARM_FEATURE_GENERIC_TIMER: + return true; + case ARM_FEATURE_EL2: + case ARM_FEATURE_EL3: + return false; + default: + g_assert_not_reached(); + } +} + void hvf_arm_set_cpu_features_from_host(ARMCPU *cpu) { if (!arm_host_cpu_features.dtb_compatible) { diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 66723448554..82853e68d8d 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -1771,6 +1771,28 @@ void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp) } } +bool arm_hw_accel_cpu_feature_supported(enum arm_features feat, bool can_emulate) +{ + if (!kvm_enabled()) { + return false; + } + switch (feat) { + case ARM_FEATURE_V8: + case ARM_FEATURE_NEON: + case ARM_FEATURE_AARCH64: + case ARM_FEATURE_GENERIC_TIMER: + return true; + case ARM_FEATURE_PMU: + return kvm_arm_pmu_supported(); + case ARM_FEATURE_EL2: + return kvm_arm_el2_supported(); + case ARM_FEATURE_EL3: + return false; + default: + g_assert_not_reached(); + } +} + bool kvm_arm_aarch32_supported(void) { return kvm_check_extension(kvm_state, KVM_CAP_ARM_EL1_32BIT); -- 2.49.0 host_cpu_feature_supported() is the generic method which dispatch to the host accelerator implementation, taking care to cache supported features. Signed-off-by: Philippe Mathieu-Daudé --- target/arm/cpu.h | 11 +++++++++++ target/arm/arm_hw_accel.c | 27 +++++++++++++++++++++++++++ target/arm/meson.build | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 target/arm/arm_hw_accel.c diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 5136c4caabf..aff60cef6da 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2508,6 +2508,16 @@ static inline ARMSecuritySpace arm_secure_to_space(bool secure) #if !defined(CONFIG_USER_ONLY) +/** + * host_cpu_feature_supported: + * @feat: Feature to test for support + * @can_emulate: Whether Allow to fall back to emulation if @feat is not + * supported by hardware accelerator + * + * Hardware accelerator implementation of cpu_feature_supported(). + */ +bool host_cpu_feature_supported(enum arm_features feature, bool can_emulate); + /** * arm_hw_accel_cpu_feature_supported: * @feat: Feature to test for support @@ -2515,6 +2525,7 @@ static inline ARMSecuritySpace arm_secure_to_space(bool secure) * supported by hardware accelerator * * Hardware accelerator implementation of cpu_feature_supported(). + * Common code should use the generic host_cpu_feature_supported() equivalent. */ bool arm_hw_accel_cpu_feature_supported(enum arm_features feat, bool can_emulate); diff --git a/target/arm/arm_hw_accel.c b/target/arm/arm_hw_accel.c new file mode 100644 index 00000000000..3a8ff007599 --- /dev/null +++ b/target/arm/arm_hw_accel.c @@ -0,0 +1,27 @@ +/* + * QEMU helpers for ARM hardware accelerators + * + * Copyright (c) Linaro + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "cpu.h" + +bool host_cpu_feature_supported(enum arm_features feat, bool can_emulate) +{ +#if defined(CONFIG_KVM) || defined(CONFIG_HVF) + static enum { F_UNKN, F_SUPP, F_UNSUPP } supported[64] = { }; + + assert(feat < ARRAY_SIZE(supported)); + if (supported[feat] == F_UNKN) { + supported[feat] = arm_hw_accel_cpu_feature_supported(feat, can_emulate); + } + return supported[feat] == F_SUPP; +#elif defined(CONFIG_TCG) + return can_emulate; +#else +#error +#endif +} diff --git a/target/arm/meson.build b/target/arm/meson.build index 07d9271aa4d..37718c85666 100644 --- a/target/arm/meson.build +++ b/target/arm/meson.build @@ -11,7 +11,7 @@ arm_ss.add(when: 'TARGET_AARCH64', if_true: files( arm_system_ss = ss.source_set() arm_common_system_ss = ss.source_set() arm_system_ss.add(files( - 'arm-qmp-cmds.c', + 'arm-qmp-cmds.c', 'arm_hw_accel.c', )) arm_system_ss.add(when: 'CONFIG_KVM', if_true: files('hyp_gdbstub.c', 'kvm.c')) arm_system_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c')) -- 2.49.0 Use the generic host_cpu_feature_supported() helper to check for the PMU feature support. This will allow to expand to non-KVM accelerators such HVF. Signed-off-by: Philippe Mathieu-Daudé --- target/arm/kvm_arm.h | 13 ------------- target/arm/cpu.c | 4 ++-- target/arm/kvm-stub.c | 5 ----- target/arm/kvm.c | 9 ++------- 4 files changed, 4 insertions(+), 27 deletions(-) diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 6a9b6374a6d..364578c50d6 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -177,14 +177,6 @@ void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp); */ bool kvm_arm_aarch32_supported(void); -/** - * kvm_arm_pmu_supported: - * - * Returns: true if KVM can enable the PMU - * and false otherwise. - */ -bool kvm_arm_pmu_supported(void); - /** * kvm_arm_sve_supported: * @@ -212,11 +204,6 @@ static inline bool kvm_arm_aarch32_supported(void) return false; } -static inline bool kvm_arm_pmu_supported(void) -{ - return false; -} - static inline bool kvm_arm_sve_supported(void) { return false; diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 1dc2a8330d8..c78a3c9cda8 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1564,8 +1564,8 @@ static void arm_set_pmu(Object *obj, bool value, Error **errp) ARMCPU *cpu = ARM_CPU(obj); if (value) { - if (kvm_enabled() && !kvm_arm_pmu_supported()) { - error_setg(errp, "'pmu' feature not supported by KVM on this host"); + if (host_cpu_feature_supported(ARM_FEATURE_PMU, false)) { + error_setg(errp, "'pmu' feature not supported by this host accelerator"); return; } set_feature(&cpu->env, ARM_FEATURE_PMU); diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c index c93462c5b9b..3beb336416d 100644 --- a/target/arm/kvm-stub.c +++ b/target/arm/kvm-stub.c @@ -32,11 +32,6 @@ bool kvm_arm_aarch32_supported(void) return false; } -bool kvm_arm_pmu_supported(void) -{ - return false; -} - bool kvm_arm_sve_supported(void) { return false; diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 82853e68d8d..0fe0f89f931 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -288,7 +288,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) 1 << KVM_ARM_VCPU_PTRAUTH_GENERIC); } - if (kvm_arm_pmu_supported()) { + if (host_cpu_feature_supported(ARM_FEATURE_PMU, false)) { init.features[0] |= 1 << KVM_ARM_VCPU_PMU_V3; pmu_supported = true; features |= 1ULL << ARM_FEATURE_PMU; @@ -506,11 +506,6 @@ void kvm_arm_add_vcpu_properties(ARMCPU *cpu) "Set off to disable KVM steal time."); } -bool kvm_arm_pmu_supported(void) -{ - return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3); -} - int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa) { KVMState *s = KVM_STATE(ms->accelerator); @@ -1783,7 +1778,7 @@ bool arm_hw_accel_cpu_feature_supported(enum arm_features feat, bool can_emulate case ARM_FEATURE_GENERIC_TIMER: return true; case ARM_FEATURE_PMU: - return kvm_arm_pmu_supported(); + return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3); case ARM_FEATURE_EL2: return kvm_arm_el2_supported(); case ARM_FEATURE_EL3: -- 2.49.0 Use the generic host_cpu_feature_supported() helper to check for the EL2 feature support. This will allow to expand to non-KVM accelerators such HVF. Signed-off-by: Philippe Mathieu-Daudé --- target/arm/kvm_arm.h | 11 ----------- hw/arm/virt.c | 8 +------- target/arm/kvm-stub.c | 5 ----- target/arm/kvm.c | 6 +++--- 4 files changed, 4 insertions(+), 26 deletions(-) diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 364578c50d6..7e5755d76b2 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -191,12 +191,6 @@ bool kvm_arm_sve_supported(void); */ bool kvm_arm_mte_supported(void); -/** - * kvm_arm_el2_supported: - * - * Returns true if KVM can enable EL2 and false otherwise. - */ -bool kvm_arm_el2_supported(void); #else static inline bool kvm_arm_aarch32_supported(void) @@ -213,11 +207,6 @@ static inline bool kvm_arm_mte_supported(void) { return false; } - -static inline bool kvm_arm_el2_supported(void) -{ - return false; -} #endif /** diff --git a/hw/arm/virt.c b/hw/arm/virt.c index ef6be3660f5..c2f71ecbfa7 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -2267,13 +2267,7 @@ static void machvirt_init(MachineState *machine) exit(1); } - if (vms->virt && kvm_enabled() && !kvm_arm_el2_supported()) { - error_report("mach-virt: host kernel KVM does not support providing " - "Virtualization extensions to the guest CPU"); - exit(1); - } - - if (vms->virt && !kvm_enabled() && !tcg_enabled() && !qtest_enabled()) { + if (vms->virt && !host_cpu_feature_supported(ARM_FEATURE_EL2, true)) { error_report("mach-virt: %s does not support providing " "Virtualization extensions to the guest CPU", current_accel_name()); diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c index 3beb336416d..35afcc7d6f9 100644 --- a/target/arm/kvm-stub.c +++ b/target/arm/kvm-stub.c @@ -42,11 +42,6 @@ bool kvm_arm_mte_supported(void) return false; } -bool kvm_arm_el2_supported(void) -{ - return false; -} - /* * These functions should never actually be called without KVM support. */ diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 0fe0f89f931..a9f05bfa7ea 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -274,7 +274,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) /* * Ask for EL2 if supported. */ - el2_supported = kvm_arm_el2_supported(); + el2_supported = host_cpu_feature_supported(ARM_FEATURE_EL2, false); if (el2_supported) { init.features[0] |= 1 << KVM_ARM_VCPU_HAS_EL2; } @@ -1780,7 +1780,7 @@ bool arm_hw_accel_cpu_feature_supported(enum arm_features feat, bool can_emulate case ARM_FEATURE_PMU: return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3); case ARM_FEATURE_EL2: - return kvm_arm_el2_supported(); + return kvm_check_extension(kvm_state, KVM_CAP_ARM_EL2); case ARM_FEATURE_EL3: return false; default: @@ -1918,7 +1918,7 @@ int kvm_arch_init_vcpu(CPUState *cs) cpu->kvm_init_features[0] |= (1 << KVM_ARM_VCPU_PTRAUTH_ADDRESS | 1 << KVM_ARM_VCPU_PTRAUTH_GENERIC); } - if (cpu->has_el2 && kvm_arm_el2_supported()) { + if (cpu->has_el2 && host_cpu_feature_supported(ARM_FEATURE_EL2, false)) { cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_HAS_EL2; } -- 2.49.0 From: Mohamed Mediouni When starting up the VM at EL2, more sysregs are available. Sync the state of those. Signed-off-by: Mohamed Mediouni [PMD: Adapted to host_cpu_feature_supported() API] Signed-off-by: Philippe Mathieu-Daudé --- target/arm/hvf/hvf.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 5174973991f..778dc3cedf7 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -400,6 +400,7 @@ static const struct hvf_reg_match hvf_fpreg_match[] = { struct hvf_sreg_match { int reg; uint32_t key; + bool el2; uint32_t cp_idx; }; @@ -545,6 +546,27 @@ static struct hvf_sreg_match hvf_sreg_match[] = { { HV_SYS_REG_CNTV_CTL_EL0, HVF_SYSREG(14, 3, 3, 3, 1) }, { HV_SYS_REG_CNTV_CVAL_EL0, HVF_SYSREG(14, 3, 3, 3, 2) }, { HV_SYS_REG_SP_EL1, HVF_SYSREG(4, 1, 3, 4, 0) }, + /* EL2 */ + { HV_SYS_REG_CPTR_EL2, HVF_SYSREG(1, 1, 3, 4, 2), .el2 = true }, + { HV_SYS_REG_ELR_EL2, HVF_SYSREG(4, 0, 3, 4, 1), .el2 = true }, + { HV_SYS_REG_ESR_EL2, HVF_SYSREG(5, 2, 3, 4, 0), .el2 = true }, + { HV_SYS_REG_FAR_EL2, HVF_SYSREG(6, 0, 3, 4, 0), .el2 = true }, + { HV_SYS_REG_HCR_EL2, HVF_SYSREG(1, 1, 3, 4, 0), .el2 = true }, + { HV_SYS_REG_HPFAR_EL2, HVF_SYSREG(6, 0, 3, 4, 4), .el2 = true }, + { HV_SYS_REG_MAIR_EL2, HVF_SYSREG(10, 2, 3, 4, 0), .el2 = true }, + { HV_SYS_REG_MDCR_EL2, HVF_SYSREG(1, 1, 3, 4, 1), .el2 = true }, + { HV_SYS_REG_SCTLR_EL2, HVF_SYSREG(1, 0, 3, 4, 0), .el2 = true }, + { HV_SYS_REG_SPSR_EL2, HVF_SYSREG(4, 0, 3, 4, 0), .el2 = true }, + { HV_SYS_REG_SP_EL2, HVF_SYSREG(4, 1, 3, 6, 0), .el2 = true}, + { HV_SYS_REG_TCR_EL2, HVF_SYSREG(2, 0, 3, 4, 2), .el2 = true }, + { HV_SYS_REG_TPIDR_EL2, HVF_SYSREG(13, 0, 3, 4, 2), .el2 = true }, + { HV_SYS_REG_TTBR0_EL2, HVF_SYSREG(2, 0, 3, 4, 0), .el2 = true }, + { HV_SYS_REG_TTBR1_EL2, HVF_SYSREG(2, 0, 3, 4, 1), .el2 = true }, + { HV_SYS_REG_VBAR_EL2, HVF_SYSREG(12, 0, 3, 4, 0), .el2 = true }, + { HV_SYS_REG_VMPIDR_EL2, HVF_SYSREG(0, 0, 3, 4, 5), .el2 = true }, + { HV_SYS_REG_VPIDR_EL2, HVF_SYSREG(0, 0, 3, 4, 0), .el2 = true }, + { HV_SYS_REG_VTCR_EL2, HVF_SYSREG(2, 1, 3, 4, 2), .el2 = true }, + { HV_SYS_REG_VTTBR_EL2, HVF_SYSREG(2, 1, 3, 4, 0), .el2 = true }, }; int hvf_get_registers(CPUState *cpu) @@ -588,6 +610,12 @@ int hvf_get_registers(CPUState *cpu) continue; } + if (hvf_sreg_match[i].el2 + && arm_feature(env, ARM_FEATURE_EL2) + && !host_cpu_feature_supported(ARM_FEATURE_EL2, false)) { + continue; + } + if (cpu->accel->guest_debug_enabled) { /* Handle debug registers */ switch (hvf_sreg_match[i].reg) { @@ -725,6 +753,12 @@ int hvf_put_registers(CPUState *cpu) continue; } + if (hvf_sreg_match[i].el2 + && arm_feature(env, ARM_FEATURE_EL2) + && !host_cpu_feature_supported(ARM_FEATURE_EL2, false)) { + continue; + } + if (cpu->accel->guest_debug_enabled) { /* Handle debug registers */ switch (hvf_sreg_match[i].reg) { -- 2.49.0 Signed-off-by: Philippe Mathieu-Daudé --- Just a proof-of-concept... --- target/arm/hvf/hvf.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 778dc3cedf7..d74f576b103 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -1000,6 +1000,9 @@ uint32_t hvf_arm_get_max_ipa_bit_size(void) bool arm_hw_accel_cpu_feature_supported(enum arm_features feat, bool can_emulate) { + hv_return_t ret; + bool supported; + if (!hvf_enabled()) { return false; } @@ -1011,6 +1014,9 @@ bool arm_hw_accel_cpu_feature_supported(enum arm_features feat, bool can_emulate case ARM_FEATURE_GENERIC_TIMER: return true; case ARM_FEATURE_EL2: + ret = hv_vm_config_get_el2_supported(&supported); + assert_hvf_ok(ret); + return supported; case ARM_FEATURE_EL3: return false; default: -- 2.49.0 Signed-off-by: Philippe Mathieu-Daudé --- Another API PoC. --- target/arm/hvf/hvf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index d74f576b103..0519903c928 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -17,6 +17,7 @@ #include "system/hvf.h" #include "system/hvf_int.h" #include "system/hw_accel.h" +#include "system/tcg.h" #include "hvf_arm.h" #include "cpregs.h" #include "cpu-sysregs.h" @@ -1014,11 +1015,14 @@ bool arm_hw_accel_cpu_feature_supported(enum arm_features feat, bool can_emulate case ARM_FEATURE_GENERIC_TIMER: return true; case ARM_FEATURE_EL2: + if (can_emulate) { + return true; + } ret = hv_vm_config_get_el2_supported(&supported); assert_hvf_ok(ret); return supported; case ARM_FEATURE_EL3: - return false; + return can_emulate && tcg_enabled(); default: g_assert_not_reached(); } -- 2.49.0