diff mbox

[v3,05/14] hvf: add code to cpus.c and do refactoring in preparation for compiling

Message ID 20170905035457.3753-6-Sergio.G.DelReal@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

The files originally added from Google's repository in previous patches
won't compile cleanly unless some glue code is added to cpus.c and some
other reorganization is done. This patch adds that code and does some
general refactoring in preparation for compiling in subsequent patches.

Signed-off-by: Sergio Andres Gomez Del Real <Sergio.G.DelReal@gmail.com>
---
 cpus.c                            | 44 +++++++++++++++++++
 include/sysemu/hvf.h              | 22 ++++++----
 target/i386/hvf-all.c             | 89 +++++++++++++++------------------------
 target/i386/hvf-utils/x86.c       |  2 +-
 target/i386/hvf-utils/x86_cpuid.h |  2 +-
 target/i386/hvf-utils/x86_descr.h |  6 +++
 target/i386/hvf-utils/x86_emu.c   |  5 +--
 target/i386/hvf-utils/x86_emu.h   | 15 +++++++
 target/i386/hvf-utils/x86_flags.h |  2 +
 target/i386/hvf-utils/x86hvf.c    |  3 --
 target/i386/hvf-utils/x86hvf.h    |  2 +
 11 files changed, 120 insertions(+), 72 deletions(-)
diff mbox

Patch

diff --git a/cpus.c b/cpus.c
index a2cd9dfa5d..263d36aa64 100644
--- a/cpus.c
+++ b/cpus.c
@@ -37,6 +37,7 @@ 
 #include "sysemu/hw_accel.h"
 #include "sysemu/kvm.h"
 #include "sysemu/hax.h"
+#include "sysemu/hvf.h"
 #include "qmp-commands.h"
 #include "exec/exec-all.h"
 
@@ -900,6 +901,9 @@  void cpu_synchronize_all_states(void)
 
     CPU_FOREACH(cpu) {
         cpu_synchronize_state(cpu);
+        if (hvf_enabled()) {
+            hvf_cpu_synchronize_state(cpu);
+        }
     }
 }
 
@@ -909,6 +913,9 @@  void cpu_synchronize_all_post_reset(void)
 
     CPU_FOREACH(cpu) {
         cpu_synchronize_post_reset(cpu);
+        if (hvf_enabled()) {
+            hvf_cpu_synchronize_post_reset(cpu);
+        }
     }
 }
 
@@ -918,6 +925,9 @@  void cpu_synchronize_all_post_init(void)
 
     CPU_FOREACH(cpu) {
         cpu_synchronize_post_init(cpu);
+        if (hvf_enabled()) {
+            hvf_cpu_synchronize_post_init(cpu);
+        }
     }
 }
 
@@ -1098,6 +1108,14 @@  static void qemu_kvm_wait_io_event(CPUState *cpu)
     qemu_wait_io_event_common(cpu);
 }
 
+static void qemu_hvf_wait_io_event(CPUState *cpu)
+{
+    while (cpu_thread_is_idle(cpu)) {
+        qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
+    }
+    qemu_wait_io_event_common(cpu);
+}
+
 static void *qemu_kvm_cpu_thread_fn(void *arg)
 {
     CPUState *cpu = arg;
@@ -1564,6 +1582,9 @@  static void qemu_cpu_kick_thread(CPUState *cpu)
         fprintf(stderr, "qemu:%s: %s", __func__, strerror(err));
         exit(1);
     }
+    if (hvf_enabled()) {
+        cpu_exit(cpu);
+    }
 #else /* _WIN32 */
     if (!qemu_cpu_is_self(cpu)) {
         if (!QueueUserAPC(dummy_apc_func, cpu->hThread, 0)) {
@@ -1780,6 +1801,27 @@  static void qemu_kvm_start_vcpu(CPUState *cpu)
     }
 }
 
+static void qemu_hvf_start_vcpu(CPUState *cpu)
+{
+    char thread_name[VCPU_THREAD_NAME_SIZE];
+
+    /* HVF currently does not support TCG, and only runs in
+     * unrestricted-guest mode. */
+    assert(hvf_enabled());
+
+    cpu->thread = g_malloc0(sizeof(QemuThread));
+    cpu->halt_cond = g_malloc0(sizeof(QemuCond));
+    qemu_cond_init(cpu->halt_cond);
+
+    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HVF",
+             cpu->cpu_index);
+    qemu_thread_create(cpu->thread, thread_name, qemu_hvf_cpu_thread_fn,
+                       cpu, QEMU_THREAD_JOINABLE);
+    while (!cpu->created) {
+        qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
+    }
+}
+
 static void qemu_dummy_start_vcpu(CPUState *cpu)
 {
     char thread_name[VCPU_THREAD_NAME_SIZE];
@@ -1816,6 +1858,8 @@  void qemu_init_vcpu(CPUState *cpu)
         qemu_kvm_start_vcpu(cpu);
     } else if (hax_enabled()) {
         qemu_hax_start_vcpu(cpu);
+    } else if (hvf_enabled()) {
+        qemu_hvf_start_vcpu(cpu);
     } else if (tcg_enabled()) {
         qemu_tcg_init_vcpu(cpu);
     } else {
diff --git a/include/sysemu/hvf.h b/include/sysemu/hvf.h
index d068a95e93..944b014596 100644
--- a/include/sysemu/hvf.h
+++ b/include/sysemu/hvf.h
@@ -15,15 +15,24 @@ 
 #include "config-host.h"
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "hw/hw.h"
-#include "target/i386/cpu.h"
 #include "qemu/bitops.h"
 #include "exec/memory.h"
 #include "sysemu/accel.h"
+
+extern int hvf_disabled;
+#ifdef CONFIG_HVF
 #include <Hypervisor/hv.h>
 #include <Hypervisor/hv_vmx.h>
 #include <Hypervisor/hv_error.h>
-
+#include "target/i386/cpu.h"
+#include "hw/hw.h"
+uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
+                                 int reg);
+#define hvf_enabled() !hvf_disabled
+#else
+#define hvf_enabled() 0
+#define hvf_get_supported_cpuid(func, idx, reg) 0
+#endif
 
 typedef struct hvf_slot {
     uint64_t start;
@@ -41,7 +50,6 @@  struct hvf_vcpu_caps {
     uint64_t vmx_cap_preemption_timer;
 };
 
-int __hvf_set_memory(hvf_slot *);
 typedef struct HVFState {
     AccelState parent;
     hvf_slot slots[32];
@@ -56,8 +64,6 @@  void hvf_handle_io(CPUArchState *, uint16_t, void *,
                   int, int, int);
 hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
 
-/* Returns 1 if HVF is available and enabled, 0 otherwise. */
-int hvf_enabled(void);
 /* 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);
@@ -83,12 +89,10 @@  void hvf_vcpu_destroy(CPUState *);
 void hvf_raise_event(CPUState *);
 /* void hvf_reset_vcpu_state(void *opaque); */
 void vmx_reset_vcpu(CPUState *);
-void __hvf_cpu_synchronize_state(CPUState *, run_on_cpu_data);
-void __hvf_cpu_synchronize_post_reset(CPUState *, run_on_cpu_data);
 void vmx_update_tpr(CPUState *);
 void update_apic_tpr(CPUState *);
-int apic_get_highest_priority_irr(DeviceState *);
 int hvf_put_registers(CPUState *);
+void vmx_clear_int_window_exiting(CPUState *cpu);
 
 #define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf")
 
diff --git a/target/i386/hvf-all.c b/target/i386/hvf-all.c
index 9b871c2aa0..ade5e9ab46 100644
--- a/target/i386/hvf-all.c
+++ b/target/i386/hvf-all.c
@@ -53,7 +53,7 @@ 
 
 pthread_rwlock_t mem_lock = PTHREAD_RWLOCK_INITIALIZER;
 HVFState *hvf_state;
-static int hvf_disabled = 1;
+int hvf_disabled = 1;
 
 static void assert_hvf_ok(hv_return_t ret)
 {
@@ -62,26 +62,26 @@  static void assert_hvf_ok(hv_return_t ret)
     }
 
     switch (ret) {
-        case HV_ERROR:
-            fprintf(stderr, "Error: HV_ERROR\n");
-            break;
-        case HV_BUSY:
-            fprintf(stderr, "Error: HV_BUSY\n");
-            break;
-        case HV_BAD_ARGUMENT:
-            fprintf(stderr, "Error: HV_BAD_ARGUMENT\n");
-            break;
-        case HV_NO_RESOURCES:
-            fprintf(stderr, "Error: HV_NO_RESOURCES\n");
-            break;
-        case HV_NO_DEVICE:
-            fprintf(stderr, "Error: HV_NO_DEVICE\n");
-            break;
-        case HV_UNSUPPORTED:
-            fprintf(stderr, "Error: HV_UNSUPPORTED\n");
-            break;
-        default:
-            fprintf(stderr, "Unknown Error\n");
+    case HV_ERROR:
+        error_report("Error: HV_ERROR\n");
+        break;
+    case HV_BUSY:
+        error_report("Error: HV_BUSY\n");
+        break;
+    case HV_BAD_ARGUMENT:
+        error_report("Error: HV_BAD_ARGUMENT\n");
+        break;
+    case HV_NO_RESOURCES:
+        error_report("Error: HV_NO_RESOURCES\n");
+        break;
+    case HV_NO_DEVICE:
+        error_report("Error: HV_NO_DEVICE\n");
+        break;
+    case HV_UNSUPPORTED:
+        error_report("Error: HV_UNSUPPORTED\n");
+        break;
+    default:
+        error_report("Unknown Error\n");
     }
 
     abort();
@@ -112,11 +112,10 @@  struct mac_slot {
 struct mac_slot mac_slots[32];
 #define ALIGN(x, y)  (((x) + (y) - 1) & ~((y) - 1))
 
-int __hvf_set_memory(hvf_slot *slot)
+static int do_hvf_set_memory(hvf_slot *slot)
 {
     struct mac_slot *macslot;
     hv_memory_flags_t flags;
-    pthread_rwlock_wrlock(&mem_lock);
     hv_return_t ret;
 
     macslot = &mac_slots[slot->slot_id];
@@ -130,7 +129,6 @@  int __hvf_set_memory(hvf_slot *slot)
     }
 
     if (!slot->size) {
-        pthread_rwlock_unlock(&mem_lock);
         return 0;
     }
 
@@ -141,7 +139,6 @@  int __hvf_set_memory(hvf_slot *slot)
     macslot->size = slot->size;
     ret = hv_vm_map((hv_uvaddr_t)slot->mem, slot->start, slot->size, flags);
     assert_hvf_ok(ret);
-    pthread_rwlock_unlock(&mem_lock);
     return 0;
 }
 
@@ -170,8 +167,8 @@  void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
     /* Region needs to be reset. set the size to 0 and remap it. */
     if (mem) {
         mem->size = 0;
-        if (__hvf_set_memory(mem)) {
-            fprintf(stderr, "Failed to reset overlapping slot\n");
+        if (do_hvf_set_memory(mem)) {
+            error_report("Failed to reset overlapping slot\n");
             abort();
         }
     }
@@ -191,7 +188,7 @@  void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
     }
 
     if (x == hvf_state->num_slots) {
-        fprintf(stderr, "No free slots\n");
+        error_report("No free slots\n");
         abort();
     }
 
@@ -199,24 +196,12 @@  void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
     mem->mem = memory_region_get_ram_ptr(area) + section->offset_within_region;
     mem->start = section->offset_within_address_space;
 
-    if (__hvf_set_memory(mem)) {
-        fprintf(stderr, "Error registering new memory slot\n");
+    if (do_hvf_set_memory(mem)) {
+        error_report("Error registering new memory slot\n");
         abort();
     }
 }
 
-/* return -1 if no bit is set */
-static int get_highest_priority_int(uint32_t *tab)
-{
-    int i;
-    for (i = 7; i >= 0; i--) {
-        if (tab[i] != 0) {
-            return i * 32 + apic_fls_bit(tab[i]);
-        }
-    }
-    return -1;
-}
-
 void vmx_update_tpr(CPUState *cpu)
 {
     /* TODO: need integrate APIC handling */
@@ -263,11 +248,11 @@  void hvf_handle_io(CPUArchState *env, uint16_t port, void *buffer,
         ptr += size;
     }
 }
-void __hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
 
 /* TODO: synchronize vcpu state */
+static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
 {
-    CPUState *cpu_state = cpu;//(CPUState *)data;
+    CPUState *cpu_state = cpu;
     if (cpu_state->hvf_vcpu_dirty == 0) {
         hvf_get_registers(cpu_state);
     }
@@ -277,12 +262,12 @@  void __hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
 
 void hvf_cpu_synchronize_state(CPUState *cpu_state)
 {
-        run_on_cpu(cpu_state, __hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
     if (cpu_state->hvf_vcpu_dirty == 0) {
+        run_on_cpu(cpu_state, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
     }
 }
 
-void __hvf_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
+static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
 {
     CPUState *cpu_state = cpu;
     hvf_put_registers(cpu_state);
@@ -291,7 +276,7 @@  void __hvf_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
 
 void hvf_cpu_synchronize_post_reset(CPUState *cpu_state)
 {
-    run_on_cpu(cpu_state, __hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
+    run_on_cpu(cpu_state, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
 }
 
 void _hvf_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg)
@@ -354,12 +339,11 @@  static MemoryListener hvf_memory_listener = {
     .region_del = hvf_region_del,
 };
 
-static MemoryListener hvf_io_listener = {
-    .priority = 10,
-};
-
 void vmx_reset_vcpu(CPUState *cpu) {
 
+    /* TODO: this shouldn't be needed; there is already a call to
+     * cpu_synchronize_all_post_reset in vl.c
+     */
     wvmcs(cpu->hvf_fd, VMCS_ENTRY_CTLS, 0);
     wvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER, 0);
     macvm_set_cr0(cpu->hvf_fd, 0x60000010);
@@ -588,8 +572,6 @@  int hvf_vcpu_exec(CPUState *cpu)
         RFLAGS(cpu) = rreg(cpu->hvf_fd, HV_X86_RFLAGS);
         env->eflags = RFLAGS(cpu);
 
-        trace_hvf_vm_exit(exit_reason, exit_qual);
-
         qemu_mutex_lock_iothread();
 
         update_apic_tpr(cpu);
@@ -846,7 +828,6 @@  static int hvf_accel_init(MachineState *ms)
     hvf_state = s;
     cpu_interrupt_handler = hvf_handle_interrupt;
     memory_listener_register(&hvf_memory_listener, &address_space_memory);
-    memory_listener_register(&hvf_io_listener, &address_space_io);
     return 0;
 }
 
diff --git a/target/i386/hvf-utils/x86.c b/target/i386/hvf-utils/x86.c
index 045b520425..1f68287830 100644
--- a/target/i386/hvf-utils/x86.c
+++ b/target/i386/hvf-utils/x86.c
@@ -26,7 +26,7 @@ 
 #include "x86_mmu.h"
 #include "x86_descr.h"
 
-static uint32_t x86_segment_access_rights(struct x86_segment_descriptor *var)
+/* static uint32_t x86_segment_access_rights(struct x86_segment_descriptor *var)
 {
    uint32_t ar;
 
diff --git a/target/i386/hvf-utils/x86_cpuid.h b/target/i386/hvf-utils/x86_cpuid.h
index 45d27c457a..da13ea8aca 100644
--- a/target/i386/hvf-utils/x86_cpuid.h
+++ b/target/i386/hvf-utils/x86_cpuid.h
@@ -35,7 +35,7 @@  struct x86_cpuid {
     uint32_t features, ext_features, ext2_features, ext3_features;
     uint32_t kvm_features, svm_features;
     uint32_t xlevel;
-    char model_id[48];
+    char model_id[50];
     int vendor_override;
     uint32_t flags;
     uint32_t xlevel2;
diff --git a/target/i386/hvf-utils/x86_descr.h b/target/i386/hvf-utils/x86_descr.h
index e2d3f75054..1285dd3897 100644
--- a/target/i386/hvf-utils/x86_descr.h
+++ b/target/i386/hvf-utils/x86_descr.h
@@ -47,3 +47,9 @@  void x86_segment_descriptor_to_vmx(struct CPUState *cpu,
                                    x68_segment_selector selector,
                                    struct x86_segment_descriptor *desc,
                                    struct vmx_segment *vmx_desc);
+
+uint32_t vmx_read_segment_limit(CPUState *cpu, x86_reg_segment seg);
+uint32_t vmx_read_segment_ar(CPUState *cpu, x86_reg_segment seg);
+void vmx_segment_to_x86_descriptor(struct CPUState *cpu,
+                                   struct vmx_segment *vmx_desc,
+                                   struct x86_segment_descriptor *desc);
diff --git a/target/i386/hvf-utils/x86_emu.c b/target/i386/hvf-utils/x86_emu.c
index f53d1b1995..861319d17e 100644
--- a/target/i386/hvf-utils/x86_emu.c
+++ b/target/i386/hvf-utils/x86_emu.c
@@ -45,7 +45,6 @@ 
 #include "vmcs.h"
 #include "vmx.h"
 
-static void print_debug(struct CPUState *cpu);
 void hvf_handle_io(struct CPUState *cpu, uint16_t port, void *data,
                    int direction, int size, uint32_t count);
 
@@ -1473,13 +1472,11 @@  void load_regs(struct CPUState *cpu)
     RRX(cpu, REG_RBP) = rreg(cpu->hvf_fd, HV_X86_RBP);
     for (i = 8; i < 16; i++) {
         RRX(cpu, i) = rreg(cpu->hvf_fd, HV_X86_RAX + i);
-    
     }
+
     RFLAGS(cpu) = rreg(cpu->hvf_fd, HV_X86_RFLAGS);
     rflags_to_lflags(cpu);
     RIP(cpu) = rreg(cpu->hvf_fd, HV_X86_RIP);
-
-    //print_debug(cpu);
 }
 
 void store_regs(struct CPUState *cpu)
diff --git a/target/i386/hvf-utils/x86_emu.h b/target/i386/hvf-utils/x86_emu.h
index f6feff5553..be80350ed8 100644
--- a/target/i386/hvf-utils/x86_emu.h
+++ b/target/i386/hvf-utils/x86_emu.h
@@ -30,4 +30,19 @@  void store_regs(struct CPUState *cpu);
 void simulate_rdmsr(struct CPUState *cpu);
 void simulate_wrmsr(struct CPUState *cpu);
 
+addr_t read_reg(struct CPUState *cpu, int reg, int size);
+void write_reg(struct CPUState *cpu, int reg, addr_t val, int size);
+addr_t read_val_from_reg(addr_t reg_ptr, int size);
+void write_val_to_reg(addr_t reg_ptr, addr_t val, int size);
+void write_val_ext(struct CPUState *cpu, addr_t ptr, addr_t val, int size);
+uint8_t *read_mmio(struct CPUState *cpu, addr_t ptr, int bytes);
+addr_t read_val_ext(struct CPUState *cpu, addr_t ptr, int size);
+
+void exec_movzx(struct CPUState *cpu, struct x86_decode *decode);
+void exec_shl(struct CPUState *cpu, struct x86_decode *decode);
+void exec_movsx(struct CPUState *cpu, struct x86_decode *decode);
+void exec_ror(struct CPUState *cpu, struct x86_decode *decode);
+void exec_rol(struct CPUState *cpu, struct x86_decode *decode);
+void exec_rcl(struct CPUState *cpu, struct x86_decode *decode);
+void exec_rcr(struct CPUState *cpu, struct x86_decode *decode);
 #endif
diff --git a/target/i386/hvf-utils/x86_flags.h b/target/i386/hvf-utils/x86_flags.h
index 87a694b408..68a0c10b90 100644
--- a/target/i386/hvf-utils/x86_flags.h
+++ b/target/i386/hvf-utils/x86_flags.h
@@ -242,4 +242,6 @@  void SET_FLAGS_SHL32(struct CPUState *cpu, uint32_t v, int count, uint32_t res);
 void SET_FLAGS_SHL16(struct CPUState *cpu, uint16_t v, int count, uint16_t res);
 void SET_FLAGS_SHL8(struct CPUState *cpu, uint8_t v, int count, uint8_t res);
 
+bool _get_OF(struct CPUState *cpu);
+bool _get_CF(struct CPUState *cpu);
 #endif /* __X86_FLAGS_H__ */
diff --git a/target/i386/hvf-utils/x86hvf.c b/target/i386/hvf-utils/x86hvf.c
index 1d2c49d50a..c920064659 100644
--- a/target/i386/hvf-utils/x86hvf.c
+++ b/target/i386/hvf-utils/x86hvf.c
@@ -35,8 +35,6 @@ 
 #include <Hypervisor/hv_vmx.h>
 #include <stdint.h>
 
-void hvf_cpu_synchronize_state(struct CPUState* cpu_state);
-
 void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
                      SegmentCache *qseg, bool is_tr)
 {
@@ -112,7 +110,6 @@  void hvf_put_xsave(CPUState *cpu_state)
     }
 }
 
-void vmx_update_tpr(CPUState *cpu);
 void hvf_put_segments(CPUState *cpu_state)
 {
     CPUX86State *env = &X86_CPU(cpu_state)->env;
diff --git a/target/i386/hvf-utils/x86hvf.h b/target/i386/hvf-utils/x86hvf.h
index ddc73ed114..26da3dab57 100644
--- a/target/i386/hvf-utils/x86hvf.h
+++ b/target/i386/hvf-utils/x86hvf.h
@@ -34,4 +34,6 @@  void hvf_get_xsave(CPUState *cpu_state);
 void hvf_get_msrs(CPUState *cpu_state);
 void vmx_clear_int_window_exiting(CPUState *cpu);
 void hvf_get_segments(CPUState *cpu_state);
+void vmx_update_tpr(CPUState *cpu);
+void hvf_cpu_synchronize_state(CPUState *cpu_state);
 #endif