Hax: added HAXM non-UG platform support back 73/30073/4
authorDavid Chou <david.j.chou@intel.com>
Sat, 8 Nov 2014 01:11:56 +0000 (17:11 -0800)
committerKitae Kim <kt920.kim@samsung.com>
Fri, 14 Nov 2014 09:56:54 +0000 (18:56 +0900)
Added HAXM non-UG platform support back.
Skipped tcg initilization for UG platform with HAXM enabled.

Change-Id: If909b19b4e7c4d65cb35784f86ca90b462c3302a
Signed-off-by: David Chou <david.j.chou@intel.com>
cpus.c
hax-stub.c
include/qemu/tls.h
include/sysemu/hax.h
target-i386/hax-all.c
vl.c

diff --git a/cpus.c b/cpus.c
index b28a92a..0b3a7c5 100644 (file)
--- a/cpus.c
+++ b/cpus.c
@@ -512,7 +512,7 @@ void cpu_synchronize_all_post_reset(void)
     CPU_FOREACH(cpu) {
         cpu_synchronize_post_reset(cpu);
 #ifdef CONFIG_HAX
-        if (hax_enabled())
+        if (hax_enabled() && hax_ug_platform())
             hax_cpu_synchronize_post_reset(cpu);
 #endif
     }
@@ -525,7 +525,7 @@ void cpu_synchronize_all_post_init(void)
     CPU_FOREACH(cpu) {
         cpu_synchronize_post_init(cpu);
 #ifdef CONFIG_HAX
-        if (hax_enabled())
+        if (hax_enabled() && hax_ug_platform())
             hax_cpu_synchronize_post_init(cpu);
 #endif
     }
@@ -990,7 +990,6 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
 {
     CPUState *cpu = arg;
     int r;
-
     qemu_thread_get_self(cpu->thread);
     qemu_mutex_lock(&qemu_global_mutex);
 
@@ -1033,7 +1032,8 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
     if (!exit_request)
         cpu_signal(0);
 
-    cpu->exit_request = 1;
+        if (hax_enabled() && hax_ug_platform())
+            cpu->exit_request = 1;
 #endif
 #else /* _WIN32 */
     if (!qemu_cpu_is_self(cpu)) {
@@ -1054,7 +1054,8 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
         }
 
         cpu_signal(0);
-        cpu->exit_request = 1;
+        if(hax_enabled()  && hax_ug_platform())
+            cpu->exit_request = 1;
 
         if (ResumeThread(cpu->hThread) == (DWORD)-1) {
             fprintf(stderr, "qemu:%s: GetLastError:%lu\n", __func__,
@@ -1068,7 +1069,11 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
 void qemu_cpu_kick(CPUState *cpu)
 {
     qemu_cond_broadcast(cpu->halt_cond);
-    if ((hax_enabled() || !tcg_enabled()) && !cpu->thread_kicked) {
+#ifdef CONFIG_HAX
+    if (((hax_enabled()  && hax_ug_platform()) || !tcg_enabled()) && !cpu->thread_kicked) {
+#else
+    if (!tcg_enabled() && !cpu->thread_kicked) {
+#endif
         qemu_cpu_kick_thread(cpu);
         cpu->thread_kicked = true;
     }
@@ -1100,7 +1105,11 @@ static bool qemu_in_vcpu_thread(void)
 
 void qemu_mutex_lock_iothread(void)
 {
-    if (hax_enabled() || !tcg_enabled()) {
+#ifdef CONFIG_HAX
+    if ((hax_enabled() && hax_ug_platform()) || !tcg_enabled()) {
+#else
+    if (!tcg_enabled()) {
+#endif
         qemu_mutex_lock(&qemu_global_mutex);
     } else {
         iothread_requesting_mutex = true;
@@ -1273,10 +1282,11 @@ void qemu_init_vcpu(CPUState *cpu)
     cpu->nr_cores = smp_cores;
     cpu->nr_threads = smp_threads;
     cpu->stopped = true;
+
     if (kvm_enabled()) {
         qemu_kvm_start_vcpu(cpu);
 #ifdef CONFIG_HAX
-    } else if (hax_enabled()) {
+    } else if (hax_enabled() && hax_ug_platform()) {
         qemu_hax_start_vcpu(cpu);
 #endif
     } else if (tcg_enabled()) {
index 456caa8..1ec5594 100644 (file)
@@ -44,3 +44,9 @@ int hax_enabled(void)
 {
    return 0;
 }
+
+int hax_ug_platform(void)
+{
+    return 0;
+}
+
index f9f60c6..b92ea9d 100644 (file)
@@ -38,7 +38,7 @@
  * TODO: proper implementations via Win32 .tls sections and
  * POSIX pthread_getspecific.
  */
-#if defined (__linux__) || defined(_WIN32)
+#ifdef __linux__
 #define DECLARE_TLS(type, x) extern DEFINE_TLS(type, x)
 #define DEFINE_TLS(type, x)  __thread __typeof__(type) tls__##x
 #define tls_var(x)           tls__##x
index 3b67838..1e97ad2 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Authors:
  *  Anthony Liguori   <aliguori@us.ibm.com>
- * 
+ *
  * Copyright (c) 2011 Intel Corporation
  *  Written by:
  *  Jiang Yunhong<yunhong.jiang@intel.com>
 
 int hax_enabled(void);
 void hax_disable(int disable);
+int hax_ug_platform(void);
 int hax_pre_init(uint64_t ram_size);
 int hax_accel_init(void);
 int hax_sync_vcpus(void);
 
 #ifdef CONFIG_HAX
 
-#define dprint printf
+#define dprint printf
 
 #include "hw/hw.h"
 #include "qemu/bitops.h"
index 7b4bd46..05442ab 100644 (file)
@@ -40,6 +40,9 @@
 #define HAX_EMULATE_STATE_NONE  0x3
 #define HAX_EMULATE_STATE_INITIAL       0x4
 
+#define HAX_NON_UG_PLATFORM 0x0
+#define HAX_UG_PLATFORM     0x1
+
 static void hax_vcpu_sync_state(CPUArchState *env, int modified);
 static int hax_arch_get_registers(CPUArchState *env);
 static int hax_handle_io(CPUArchState *env, uint32_t df, uint16_t port, int dir, int size, int cnt, void *buf);
@@ -50,6 +53,7 @@ int ret_hax_init = 0;
 static int hax_disabled = 1;
 
 int hax_support = -1;
+int ug_support = 0;
 
 /* Called after hax_init */
 int hax_enabled(void)
@@ -62,16 +66,17 @@ void hax_disable(int disable)
     hax_disabled = disable;
 }
 
+/* Called after hax_init */
+int hax_ug_platform(void)
+{
+    return (ug_support);
+}
+
 /* Currently non-PG modes are emulated by QEMU */
 int hax_vcpu_emulation_mode(CPUState *cpu)
 {
-    // Tcg is single-thread, so we need haxm to run smp.
-    // If the host has no UG, we always run tcg.
-
-    if (hax_enabled())
-        return 0;
-    else
-        return 1;
+    CPUArchState *env = (CPUArchState *)(cpu->env_ptr);
+    return !(env->cr[0] & CR0_PG_MASK);
 }
 
 static int hax_prepare_emulation(CPUArchState *env)
@@ -181,11 +186,8 @@ static int hax_get_capability(struct hax_state *hax)
         return -ENXIO;
     }
 
-    if (!(cap->winfo & HAX_CAP_UG))
-    {
-        dprint("UG feature is not available on platform needed to support HAXM.\n");
-        return -ENXIO;
-    }
+    if ((cap->winfo & HAX_CAP_UG))
+        ug_support = 1;
 
     if (cap->wstatus & HAX_CAP_MEMQUOTA)
     {
@@ -646,11 +648,11 @@ static int hax_vcpu_interrupt(CPUArchState *env)
     {
         int irq;
 
-        irq = cpu_get_pic_interrupt(env);
+         irq = cpu_get_pic_interrupt(env);
         if (irq >= 0) {
             hax_inject_interrupt(env, irq);
             cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
-        }
+         }
     }
 
     /* If we have an interrupt but the guest is not ready to receive an
@@ -683,7 +685,7 @@ void hax_raise_event(CPUState *cpu)
  * 5. An unknown VMX exit happens
  */
 extern void qemu_system_reset_request(void);
-static int hax_vcpu_hax_exec(CPUArchState *env)
+static int hax_vcpu_hax_exec(CPUArchState *env, int ug_platform)
 {
     int ret = 0;
     CPUState *cpu = ENV_GET_CPU(env);
@@ -691,29 +693,48 @@ static int hax_vcpu_hax_exec(CPUArchState *env)
     struct hax_vcpu_state *vcpu = cpu->hax_vcpu;
     struct hax_tunnel *ht = vcpu->tunnel;
 
-    if (hax_vcpu_emulation_mode(cpu))
+    if(!ug_platform)
     {
-        dprint("Trying to vcpu execute at eip:%lx\n", env->eip);
-        return  HAX_EMUL_EXITLOOP;
-    }
+        if (hax_vcpu_emulation_mode(cpu))
+        {
+            dprint("Trying to vcpu execute at eip:%lx\n", env->eip);
+            return  HAX_EMUL_EXITLOOP;
+        }
 
-    cpu->halted = 0;
+        cpu->halted = 0;
 
-    if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
-        cpu->interrupt_request &= ~CPU_INTERRUPT_POLL;
-        apic_poll_irq(x86_cpu->apic_state);
+        if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
+            cpu->interrupt_request &= ~CPU_INTERRUPT_POLL;
+            apic_poll_irq(x86_cpu->apic_state);
+        }
     }
+    else  /* UG platform */
+    {
+        if (!hax_enabled())
+        {
+            dprint("Trying to vcpu execute at eip:%lx\n", env->eip);
+            return  HAX_EMUL_EXITLOOP;
+        }
 
-    if (cpu->interrupt_request & CPU_INTERRUPT_INIT) {
-        fprintf(stderr, "\nhax_vcpu_hax_exec: handling INIT for %d \n", cpu->cpu_index);
-        do_cpu_init(x86_cpu);
-        hax_vcpu_sync_state(env, 1);
-    }
-    if (cpu->interrupt_request & CPU_INTERRUPT_SIPI) {
-        fprintf(stderr, "hax_vcpu_hax_exec: handling SIPI for %d \n", cpu->cpu_index);
-        hax_vcpu_sync_state(env, 0);
-        do_cpu_sipi(x86_cpu);
-        hax_vcpu_sync_state(env, 1);
+        cpu->halted = 0;
+
+        if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
+            cpu->interrupt_request &= ~CPU_INTERRUPT_POLL;
+            apic_poll_irq(x86_cpu->apic_state);
+        }
+
+        if (cpu->interrupt_request & CPU_INTERRUPT_INIT) {
+            fprintf(stderr, "\nUG hax_vcpu_hax_exec: handling INIT for %d \n", cpu->cpu_index);
+            do_cpu_init(x86_cpu);
+            hax_vcpu_sync_state(env, 1);
+        }
+
+        if (cpu->interrupt_request & CPU_INTERRUPT_SIPI) {
+            fprintf(stderr, "UG hax_vcpu_hax_exec: handling SIPI for %d \n", cpu->cpu_index);
+            hax_vcpu_sync_state(env, 0);
+            do_cpu_sipi(x86_cpu);
+            hax_vcpu_sync_state(env, 1);
+        }
     }
 
     //hax_cpu_synchronize_state(cpu);
@@ -734,13 +755,18 @@ static int hax_vcpu_hax_exec(CPUArchState *env)
 #endif
 
         hax_vcpu_interrupt(env);
-        qemu_mutex_unlock_iothread();
-        hax_ret = hax_vcpu_run(vcpu);
-        qemu_mutex_lock_iothread();
+        if (!ug_platform)
+        {
+            hax_ret = hax_vcpu_run(vcpu);
+        }
+        else /* UG platform */
+        {
+            qemu_mutex_unlock_iothread();
+            hax_ret = hax_vcpu_run(vcpu);
+            qemu_mutex_lock_iothread();
+            current_cpu = cpu;
+        }
 
-#ifdef CONFIG_DARWIN
-        current_cpu = cpu;
-#endif
         /* Simply continue the vcpu_run if system call interrupted */
         if (hax_ret == -EINTR || hax_ret == -EAGAIN) {
             dprint("io window interrupted\n");
@@ -863,7 +889,7 @@ int hax_vcpu_exec(CPUState *cpu)
         return 1;
 
     vcpu = cpu->hax_vcpu;
-    next = hax_vcpu_hax_exec(env);
+    next = hax_vcpu_hax_exec(env, HAX_NON_UG_PLATFORM);
     switch (next)
     {
         case HAX_EMUL_ONE:
@@ -901,7 +927,7 @@ int hax_smp_cpu_exec(CPUState *cpu)
             break;
         }
 
-        why = hax_vcpu_hax_exec(env);
+        why = hax_vcpu_hax_exec(env, HAX_UG_PLATFORM);
 
         if ((why != HAX_EMUL_HLT) && (why != HAX_EMUL_EXITLOOP))
         {
diff --git a/vl.c b/vl.c
index 1ee1819..2b6f1a6 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -2747,8 +2747,9 @@ static MachineClass *machine_parse(const char *name)
 static int tcg_init(QEMUMachine *machine)
 {
     int ret = 0;
-    tcg_exec_init(tcg_tb_size * 1024 * 1024);
     ret = hax_accel_init();
+    if (!(hax_enabled() && hax_ug_platform()))
+        tcg_exec_init(tcg_tb_size * 1024 * 1024);
     return ret;
 }