From 76707bcc9926ef4c70f4783ed9ad31c5eeca6826 Mon Sep 17 00:00:00 2001 From: Matt Borgerson <contact@mborgerson.com> Date: Mon, 17 Feb 2020 23:50:02 -0700 Subject: [PATCH] hvf: Align with upstream and fix 32b --- cpus.c | 12 +++++++ include/sysemu/hvf.h | 46 ++++++++++++++++++++++++ include/sysemu/hw_accel.h | 10 ------ target/i386/hvf/hvf.c | 9 +++-- target/i386/hvf/hvf_int.h | 70 ------------------------------------ target/i386/hvf/x86_decode.c | 10 +++--- target/i386/hvf/x86_decode.h | 4 +-- 7 files changed, 71 insertions(+), 90 deletions(-) delete mode 100644 target/i386/hvf/hvf_int.h diff --git a/cpus.c b/cpus.c index c91818cb00..63bda152f5 100644 --- a/cpus.c +++ b/cpus.c @@ -1051,6 +1051,10 @@ void cpu_synchronize_all_states(void) CPU_FOREACH(cpu) { cpu_synchronize_state(cpu); + /* TODO: move to cpu_synchronize_state() */ + if (hvf_enabled()) { + hvf_cpu_synchronize_state(cpu); + } } } @@ -1060,6 +1064,10 @@ void cpu_synchronize_all_post_reset(void) CPU_FOREACH(cpu) { cpu_synchronize_post_reset(cpu); + /* TODO: move to cpu_synchronize_post_reset() */ + if (hvf_enabled()) { + hvf_cpu_synchronize_post_reset(cpu); + } } } @@ -1069,6 +1077,10 @@ void cpu_synchronize_all_post_init(void) CPU_FOREACH(cpu) { cpu_synchronize_post_init(cpu); + /* TODO: move to cpu_synchronize_post_init() */ + if (hvf_enabled()) { + hvf_cpu_synchronize_post_init(cpu); + } } } diff --git a/include/sysemu/hvf.h b/include/sysemu/hvf.h index a8f6f626c5..d211e808e9 100644 --- a/include/sysemu/hvf.h +++ b/include/sysemu/hvf.h @@ -32,6 +32,41 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx, #define hvf_get_supported_cpuid(func, idx, reg) 0 #endif +/* hvf_slot flags */ +#define HVF_SLOT_LOG (1 << 0) + +typedef struct hvf_slot { + uint64_t start; + uint64_t size; + uint8_t *mem; + int slot_id; + uint32_t flags; + MemoryRegion *region; +} hvf_slot; + +typedef struct hvf_vcpu_caps { + uint64_t vmx_cap_pinbased; + uint64_t vmx_cap_procbased; + uint64_t vmx_cap_procbased2; + uint64_t vmx_cap_entry; + uint64_t vmx_cap_exit; + uint64_t vmx_cap_preemption_timer; +} hvf_vcpu_caps; + +typedef struct HVFState { + AccelState parent; + hvf_slot slots[32]; + int num_slots; + + hvf_vcpu_caps *hvf_caps; +} HVFState; +extern HVFState *hvf_state; + +void hvf_set_phys_mem(MemoryRegionSection *, bool); +void hvf_handle_io(CPUArchState *, uint16_t, void *, + int, int, int); +hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t); + /* Disable HVF if |disable| is 1, otherwise, enable it iff it is supported by * the host CPU. Use hvf_enabled() after this to get the result. */ void hvf_disable(int disable); @@ -51,9 +86,20 @@ int hvf_smp_cpu_exec(CPUState *); void hvf_cpu_synchronize_state(CPUState *); void hvf_cpu_synchronize_post_reset(CPUState *); void hvf_cpu_synchronize_post_init(CPUState *); +void _hvf_cpu_synchronize_post_init(CPUState *, run_on_cpu_data); void hvf_vcpu_destroy(CPUState *); +void hvf_raise_event(CPUState *); +/* void hvf_reset_vcpu_state(void *opaque); */ void hvf_reset_vcpu(CPUState *); +void vmx_update_tpr(CPUState *); +void update_apic_tpr(CPUState *); int hvf_put_registers(CPUState *); +void vmx_clear_int_window_exiting(CPUState *cpu); + +#define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf") + +#define HVF_STATE(obj) \ + OBJECT_CHECK(HVFState, (obj), TYPE_HVF_ACCEL) #endif diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h index 61fe934cd4..0ec2372477 100644 --- a/include/sysemu/hw_accel.h +++ b/include/sysemu/hw_accel.h @@ -15,7 +15,6 @@ #include "sysemu/hax.h" #include "sysemu/kvm.h" #include "sysemu/whpx.h" -#include "sysemu/hvf.h" static inline void cpu_synchronize_state(CPUState *cpu) { @@ -28,9 +27,6 @@ static inline void cpu_synchronize_state(CPUState *cpu) if (whpx_enabled()) { whpx_cpu_synchronize_state(cpu); } - if (hvf_enabled()) { - hvf_cpu_synchronize_state(cpu); - } } static inline void cpu_synchronize_post_reset(CPUState *cpu) @@ -44,9 +40,6 @@ static inline void cpu_synchronize_post_reset(CPUState *cpu) if (whpx_enabled()) { whpx_cpu_synchronize_post_reset(cpu); } - if (hvf_enabled()) { - hvf_cpu_synchronize_post_reset(cpu); - } } static inline void cpu_synchronize_post_init(CPUState *cpu) @@ -60,9 +53,6 @@ static inline void cpu_synchronize_post_init(CPUState *cpu) if (whpx_enabled()) { whpx_cpu_synchronize_post_init(cpu); } - if (hvf_enabled()) { - hvf_cpu_synchronize_post_init(cpu); - } } static inline void cpu_synchronize_pre_loadvm(CPUState *cpu) diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index d72543dc31..93dd21e289 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -304,6 +304,7 @@ static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg { CPUState *cpu_state = cpu; hvf_put_registers(cpu_state); + wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_CTLS, 0); cpu_state->vcpu_dirty = false; } @@ -344,7 +345,7 @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual) if (slot->flags & HVF_SLOT_LOG) { memory_region_set_dirty(slot->region, gpa - slot->start, 1); hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size, - HV_MEMORY_READ | HV_MEMORY_WRITE); + HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC); } } @@ -380,12 +381,12 @@ static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on) if (on) { slot->flags |= HVF_SLOT_LOG; hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size, - HV_MEMORY_READ); + HV_MEMORY_READ | HV_MEMORY_EXEC); /* stop tracking region*/ } else { slot->flags &= ~HVF_SLOT_LOG; hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size, - HV_MEMORY_READ | HV_MEMORY_WRITE); + HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC); } } @@ -416,7 +417,9 @@ static void hvf_log_sync(MemoryListener *listener, * sync of dirty pages is handled elsewhere; just make sure we keep * tracking the region. */ +#ifndef XBOX hvf_set_dirty_tracking(section, 1); +#endif } static void hvf_region_add(MemoryListener *listener, diff --git a/target/i386/hvf/hvf_int.h b/target/i386/hvf/hvf_int.h deleted file mode 100644 index dc39de54d3..0000000000 --- a/target/i386/hvf/hvf_int.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * QEMU Hypervisor.framework (HVF) support - * - * Copyright Google Inc., 2017 - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - * - */ - -/* header to be included in HVF-specific code */ -#ifndef _HVF_INT_H -#define _HVF_INT_H - -#include "sysemu/hvf.h" - -#ifdef CONFIG_HVF -#include "target/i386/cpu.h" -#include <Hypervisor/hv.h> -#include <Hypervisor/hv_vmx.h> -#include <Hypervisor/hv_error.h> -#endif - -/* hvf_slot flags */ -#define HVF_SLOT_LOG (1 << 0) - -typedef struct hvf_slot { - uint64_t start; - uint64_t size; - uint8_t *mem; - int slot_id; - uint32_t flags; - MemoryRegion *region; -} hvf_slot; - -typedef struct hvf_vcpu_caps { - uint64_t vmx_cap_pinbased; - uint64_t vmx_cap_procbased; - uint64_t vmx_cap_procbased2; - uint64_t vmx_cap_entry; - uint64_t vmx_cap_exit; - uint64_t vmx_cap_preemption_timer; -} hvf_vcpu_caps; - -typedef struct HVFState { - AccelState parent; - hvf_slot slots[32]; - int num_slots; - - hvf_vcpu_caps *hvf_caps; -} HVFState; -extern HVFState *hvf_state; - -void hvf_set_phys_mem(MemoryRegionSection *, bool); -void hvf_handle_io(CPUArchState *, uint16_t, void *, - int, int, int); -hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t); - -void _hvf_cpu_synchronize_post_init(CPUState *, run_on_cpu_data); - -void vmx_update_tpr(CPUState *); -void update_apic_tpr(CPUState *); -void vmx_clear_int_window_exiting(CPUState *cpu); - -#define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf") - -#define HVF_STATE(obj) \ - OBJECT_CHECK(HVFState, (obj), TYPE_HVF_ACCEL) - -#endif diff --git a/target/i386/hvf/x86_decode.c b/target/i386/hvf/x86_decode.c index 77c346605f..e3d319c7c0 100644 --- a/target/i386/hvf/x86_decode.c +++ b/target/i386/hvf/x86_decode.c @@ -1688,10 +1688,10 @@ calc_addr: } } -target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present, +uintptr_t get_reg_ref(CPUX86State *env, int reg, int rex_present, int is_extended, int size) { - target_ulong ptr = 0; + uintptr_t ptr = 0; if (is_extended) { reg |= R_R8; @@ -1700,13 +1700,13 @@ target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present, switch (size) { case 1: if (is_extended || reg < 4 || rex_present) { - ptr = (target_ulong)&RL(env, reg); + ptr = (uintptr_t)&RL(env, reg); } else { - ptr = (target_ulong)&RH(env, reg - 4); + ptr = (uintptr_t)&RH(env, reg - 4); } break; default: - ptr = (target_ulong)&RRX(env, reg); + ptr = (uintptr_t)&RRX(env, reg); break; } return ptr; diff --git a/target/i386/hvf/x86_decode.h b/target/i386/hvf/x86_decode.h index ef7960113f..ff70871611 100644 --- a/target/i386/hvf/x86_decode.h +++ b/target/i386/hvf/x86_decode.h @@ -266,7 +266,7 @@ typedef struct x86_decode_op { int reg; target_ulong val; - target_ulong ptr; + uintptr_t ptr; } x86_decode_op; typedef struct x86_decode { @@ -303,7 +303,7 @@ uint64_t sign(uint64_t val, int size); uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode); -target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present, +uintptr_t get_reg_ref(CPUX86State *env, int reg, int rex_present, int is_extended, int size); target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present, int is_extended, int size);