提交 19306806 编写于 作者: J Justin Terry (VM) 提交者: Paolo Bonzini

Add the WHPX acceleration enlightenments

Implements the WHPX accelerator cpu enlightenments to actually use the whpx-all
accelerator on Windows platforms.
Signed-off-by: NJustin Terry (VM) <juterry@microsoft.com>
Message-Id: <1516655269-1785-5-git-send-email-juterry@microsoft.com>
[Register/unregister VCPU thread with RCU. - Paolo]
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
上级 812d49f2
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "sysemu/kvm.h" #include "sysemu/kvm.h"
#include "sysemu/hax.h" #include "sysemu/hax.h"
#include "sysemu/hvf.h" #include "sysemu/hvf.h"
#include "sysemu/whpx.h"
#include "qmp-commands.h" #include "qmp-commands.h"
#include "exec/exec-all.h" #include "exec/exec-all.h"
...@@ -1545,6 +1546,49 @@ static void *qemu_hvf_cpu_thread_fn(void *arg) ...@@ -1545,6 +1546,49 @@ static void *qemu_hvf_cpu_thread_fn(void *arg)
return NULL; return NULL;
} }
static void *qemu_whpx_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
int r;
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_thread_get_self(cpu->thread);
cpu->thread_id = qemu_get_thread_id();
current_cpu = cpu;
r = whpx_init_vcpu(cpu);
if (r < 0) {
fprintf(stderr, "whpx_init_vcpu failed: %s\n", strerror(-r));
exit(1);
}
/* signal CPU creation */
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
do {
if (cpu_can_run(cpu)) {
r = whpx_vcpu_exec(cpu);
if (r == EXCP_DEBUG) {
cpu_handle_guest_debug(cpu);
}
}
while (cpu_thread_is_idle(cpu)) {
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
}
qemu_wait_io_event_common(cpu);
} while (!cpu->unplug || cpu_can_run(cpu));
whpx_destroy_vcpu(cpu);
cpu->created = false;
qemu_cond_signal(&qemu_cpu_cond);
qemu_mutex_unlock_iothread();
rcu_unregister_thread();
return NULL;
}
#ifdef _WIN32 #ifdef _WIN32
static void CALLBACK dummy_apc_func(ULONG_PTR unused) static void CALLBACK dummy_apc_func(ULONG_PTR unused)
{ {
...@@ -1635,7 +1679,9 @@ static void qemu_cpu_kick_thread(CPUState *cpu) ...@@ -1635,7 +1679,9 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
} }
#else /* _WIN32 */ #else /* _WIN32 */
if (!qemu_cpu_is_self(cpu)) { if (!qemu_cpu_is_self(cpu)) {
if (!QueueUserAPC(dummy_apc_func, cpu->hThread, 0)) { if (whpx_enabled()) {
whpx_vcpu_kick(cpu);
} else if (!QueueUserAPC(dummy_apc_func, cpu->hThread, 0)) {
fprintf(stderr, "%s: QueueUserAPC failed with error %lu\n", fprintf(stderr, "%s: QueueUserAPC failed with error %lu\n",
__func__, GetLastError()); __func__, GetLastError());
exit(1); exit(1);
...@@ -1877,6 +1923,25 @@ static void qemu_hvf_start_vcpu(CPUState *cpu) ...@@ -1877,6 +1923,25 @@ static void qemu_hvf_start_vcpu(CPUState *cpu)
} }
} }
static void qemu_whpx_start_vcpu(CPUState *cpu)
{
char thread_name[VCPU_THREAD_NAME_SIZE];
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/WHPX",
cpu->cpu_index);
qemu_thread_create(cpu->thread, thread_name, qemu_whpx_cpu_thread_fn,
cpu, QEMU_THREAD_JOINABLE);
#ifdef _WIN32
cpu->hThread = qemu_thread_get_handle(cpu->thread);
#endif
while (!cpu->created) {
qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
}
}
static void qemu_dummy_start_vcpu(CPUState *cpu) static void qemu_dummy_start_vcpu(CPUState *cpu)
{ {
char thread_name[VCPU_THREAD_NAME_SIZE]; char thread_name[VCPU_THREAD_NAME_SIZE];
...@@ -1915,6 +1980,8 @@ void qemu_init_vcpu(CPUState *cpu) ...@@ -1915,6 +1980,8 @@ void qemu_init_vcpu(CPUState *cpu)
qemu_hvf_start_vcpu(cpu); qemu_hvf_start_vcpu(cpu);
} else if (tcg_enabled()) { } else if (tcg_enabled()) {
qemu_tcg_init_vcpu(cpu); qemu_tcg_init_vcpu(cpu);
} else if (whpx_enabled()) {
qemu_whpx_start_vcpu(cpu);
} else { } else {
qemu_dummy_start_vcpu(cpu); qemu_dummy_start_vcpu(cpu);
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "qom/cpu.h" #include "qom/cpu.h"
#include "sysemu/hax.h" #include "sysemu/hax.h"
#include "sysemu/kvm.h" #include "sysemu/kvm.h"
#include "sysemu/whpx.h"
static inline void cpu_synchronize_state(CPUState *cpu) static inline void cpu_synchronize_state(CPUState *cpu)
{ {
...@@ -23,6 +24,9 @@ static inline void cpu_synchronize_state(CPUState *cpu) ...@@ -23,6 +24,9 @@ static inline void cpu_synchronize_state(CPUState *cpu)
if (hax_enabled()) { if (hax_enabled()) {
hax_cpu_synchronize_state(cpu); hax_cpu_synchronize_state(cpu);
} }
if (whpx_enabled()) {
whpx_cpu_synchronize_state(cpu);
}
} }
static inline void cpu_synchronize_post_reset(CPUState *cpu) static inline void cpu_synchronize_post_reset(CPUState *cpu)
...@@ -33,6 +37,9 @@ static inline void cpu_synchronize_post_reset(CPUState *cpu) ...@@ -33,6 +37,9 @@ static inline void cpu_synchronize_post_reset(CPUState *cpu)
if (hax_enabled()) { if (hax_enabled()) {
hax_cpu_synchronize_post_reset(cpu); hax_cpu_synchronize_post_reset(cpu);
} }
if (whpx_enabled()) {
whpx_cpu_synchronize_post_reset(cpu);
}
} }
static inline void cpu_synchronize_post_init(CPUState *cpu) static inline void cpu_synchronize_post_init(CPUState *cpu)
...@@ -43,6 +50,9 @@ static inline void cpu_synchronize_post_init(CPUState *cpu) ...@@ -43,6 +50,9 @@ static inline void cpu_synchronize_post_init(CPUState *cpu)
if (hax_enabled()) { if (hax_enabled()) {
hax_cpu_synchronize_post_init(cpu); hax_cpu_synchronize_post_init(cpu);
} }
if (whpx_enabled()) {
whpx_cpu_synchronize_post_init(cpu);
}
} }
static inline void cpu_synchronize_pre_loadvm(CPUState *cpu) static inline void cpu_synchronize_pre_loadvm(CPUState *cpu)
...@@ -53,6 +63,9 @@ static inline void cpu_synchronize_pre_loadvm(CPUState *cpu) ...@@ -53,6 +63,9 @@ static inline void cpu_synchronize_pre_loadvm(CPUState *cpu)
if (hax_enabled()) { if (hax_enabled()) {
hax_cpu_synchronize_pre_loadvm(cpu); hax_cpu_synchronize_pre_loadvm(cpu);
} }
if (whpx_enabled()) {
whpx_cpu_synchronize_pre_loadvm(cpu);
}
} }
#endif /* QEMU_HW_ACCEL_H */ #endif /* QEMU_HW_ACCEL_H */
...@@ -986,7 +986,7 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) ...@@ -986,7 +986,7 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
X86CPU *cpu = x86_env_get_cpu(env); X86CPU *cpu = x86_env_get_cpu(env);
CPUState *cs = CPU(cpu); CPUState *cs = CPU(cpu);
if (kvm_enabled()) { if (kvm_enabled() || whpx_enabled()) {
env->tpr_access_type = access; env->tpr_access_type = access;
cpu_interrupt(cs, CPU_INTERRUPT_TPR); cpu_interrupt(cs, CPU_INTERRUPT_TPR);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册