From: David Chou Date: Sat, 8 Nov 2014 01:11:56 +0000 (-0800) Subject: Hax: added HAXM non-UG platform support back X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.2~632^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F73%2F30073%2F4;p=sdk%2Femulator%2Fqemu.git Hax: added HAXM non-UG platform support back Added HAXM non-UG platform support back. Skipped tcg initilization for UG platform with HAXM enabled. Change-Id: If909b19b4e7c4d65cb35784f86ca90b462c3302a Signed-off-by: David Chou --- diff --git a/cpus.c b/cpus.c index b28a92a0f0..0b3a7c5161 100644 --- 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()) { diff --git a/hax-stub.c b/hax-stub.c index 456caa8ef7..1ec5594473 100644 --- a/hax-stub.c +++ b/hax-stub.c @@ -44,3 +44,9 @@ int hax_enabled(void) { return 0; } + +int hax_ug_platform(void) +{ + return 0; +} + diff --git a/include/qemu/tls.h b/include/qemu/tls.h index f9f60c60cc..b92ea9d7da 100644 --- a/include/qemu/tls.h +++ b/include/qemu/tls.h @@ -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 diff --git a/include/sysemu/hax.h b/include/sysemu/hax.h index 3b6783867c..1e97ad2f4a 100644 --- a/include/sysemu/hax.h +++ b/include/sysemu/hax.h @@ -5,7 +5,7 @@ * * Authors: * Anthony Liguori - * + * * Copyright (c) 2011 Intel Corporation * Written by: * Jiang Yunhong @@ -29,13 +29,14 @@ 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" diff --git a/target-i386/hax-all.c b/target-i386/hax-all.c index 7b4bd46339..05442aba07 100644 --- a/target-i386/hax-all.c +++ b/target-i386/hax-all.c @@ -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 1ee1819b9e..2b6f1a66a4 100644 --- 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; }