Signed-off-by: Mohamed Mediouni <moha...@unpredictable.fr> --- hw/arm/virt.c | 9 ++++++--- target/arm/hvf-stub.c | 15 +++++++++++++++ target/arm/hvf/hvf.c | 41 +++++++++++++++++++++++++++++++++++++++-- target/arm/hvf_arm.h | 3 +++ 4 files changed, 63 insertions(+), 5 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 7da1176cda..7348d55104 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -817,8 +817,7 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem) g_assert_not_reached(); } - if (kvm_enabled() && vms->virt && - (revision != 3 || !kvm_irqchip_in_kernel())) { + if (kvm_enabled() && vms->virt && (revision != 3 || !kvm_irqchip_in_kernel())) { error_report("KVM EL2 is only supported with in-kernel GICv3"); exit(1); } @@ -2279,7 +2278,8 @@ static void machvirt_init(MachineState *machine) exit(1); } - if (vms->virt && !kvm_enabled() && !tcg_enabled() && !qtest_enabled()) { + if (vms->virt && !kvm_enabled() && !tcg_enabled() + && !hvf_enabled() && !qtest_enabled()) { error_report("mach-virt: %s does not support providing " "Virtualization extensions to the guest CPU", current_accel_name()); @@ -2549,6 +2549,9 @@ static void virt_set_virt(Object *obj, bool value, Error **errp) VirtMachineState *vms = VIRT_MACHINE(obj); vms->virt = value; +#if defined(CONFIG_HVF) && defined(__aarch64__) + hvf_arm_el2_enable(value); +#endif } static bool virt_get_highmem(Object *obj, Error **errp) diff --git a/target/arm/hvf-stub.c b/target/arm/hvf-stub.c index ff137267a0..95ec4ea62f 100644 --- a/target/arm/hvf-stub.c +++ b/target/arm/hvf-stub.c @@ -18,3 +18,18 @@ uint32_t hvf_arm_get_max_ipa_bit_size(void) { g_assert_not_reached(); } + +bool hvf_arm_el2_supported(void) +{ + g_assert_not_reached(); +} + +bool hvf_arm_el2_enabled(void) +{ + g_assert_not_reached(); +} + +void hvf_arm_el2_enable(bool) +{ + g_assert_not_reached(); +} diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 5ee0df17e3..4ac42bda32 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -26,6 +26,7 @@ #include "system/address-spaces.h" #include "system/memory.h" #include "hw/boards.h" +#include "hw/arm/virt.h" #include "hw/irq.h" #include "qemu/main-loop.h" #include "system/cpus.h" @@ -891,6 +892,10 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) (1ULL << ARM_FEATURE_PMU) | (1ULL << ARM_FEATURE_GENERIC_TIMER); + if (hvf_arm_el2_enabled()) { + ahcf->features |= 1ULL << ARM_FEATURE_EL2; + } + for (i = 0; i < ARRAY_SIZE(regs); i++) { r |= hv_vcpu_config_get_feature_reg(hv_vcpu_config, regs[i].reg, regs[i].val); } @@ -957,6 +962,25 @@ uint32_t hvf_arm_get_max_ipa_bit_size(void) return round_down_to_parange_bit_size(max_ipa_size); } +bool hvf_arm_el2_supported(void) +{ + bool is_nested_virt_supported; + hv_return_t ret = hv_vm_config_get_el2_supported(&is_nested_virt_supported); + assert_hvf_ok(ret); + return is_nested_virt_supported; +} + +static bool is_nested_virt_enabled = false; +bool hvf_arm_el2_enabled(void) +{ + return is_nested_virt_enabled; +} + +void hvf_arm_el2_enable(bool enable) +{ + is_nested_virt_enabled = enable; +} + void hvf_arm_set_cpu_features_from_host(ARMCPU *cpu) { if (!arm_host_cpu_features.dtb_compatible) { @@ -993,6 +1017,13 @@ hv_return_t hvf_arch_vm_create(MachineState *ms, uint32_t pa_range) } chosen_ipa_bit_size = pa_range; + if (hvf_arm_el2_enabled()) { + ret = hv_vm_config_set_el2_enabled(config, true); + if (ret != HV_SUCCESS) { + goto cleanup; + } + } + ret = hv_vm_create(config); cleanup: @@ -1100,6 +1131,13 @@ static void hvf_psci_cpu_off(ARMCPU *arm_cpu) assert(ret == QEMU_ARM_POWERCTL_RET_SUCCESS); } +static int hvf_psci_get_target_el(void) +{ + if (hvf_arm_el2_enabled()) { + return 2; + } + return 1; +} /* * Handle a PSCI call. * @@ -1121,7 +1159,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], @@ -1175,7 +1212,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: diff --git a/target/arm/hvf_arm.h b/target/arm/hvf_arm.h index ea82f2691d..bf55e7ae28 100644 --- a/target/arm/hvf_arm.h +++ b/target/arm/hvf_arm.h @@ -24,5 +24,8 @@ void hvf_arm_set_cpu_features_from_host(ARMCPU *cpu); uint32_t hvf_arm_get_default_ipa_bit_size(void); uint32_t hvf_arm_get_max_ipa_bit_size(void); +bool hvf_arm_el2_supported(void); +bool hvf_arm_el2_enabled(void); +void hvf_arm_el2_enable(bool); #endif -- 2.39.5 (Apple Git-154)