Add the WHPX acceleration enlightenments

Implements the WHPX accelerator cpu enlightenments to actually use the whpx-all
accelerator on Windows platforms.

Signed-off-by: Justin 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: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Justin Terry (VM) 2018-01-22 13:07:49 -08:00 committed by Paolo Bonzini
parent 812d49f2a3
commit 19306806ae
3 changed files with 82 additions and 2 deletions

69
cpus.c
View File

@ -38,6 +38,7 @@
#include "sysemu/kvm.h"
#include "sysemu/hax.h"
#include "sysemu/hvf.h"
#include "sysemu/whpx.h"
#include "qmp-commands.h"
#include "exec/exec-all.h"
@ -1545,6 +1546,49 @@ static void *qemu_hvf_cpu_thread_fn(void *arg)
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
static void CALLBACK dummy_apc_func(ULONG_PTR unused)
{
@ -1635,7 +1679,9 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
}
#else /* _WIN32 */
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",
__func__, GetLastError());
exit(1);
@ -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)
{
char thread_name[VCPU_THREAD_NAME_SIZE];
@ -1915,6 +1980,8 @@ void qemu_init_vcpu(CPUState *cpu)
qemu_hvf_start_vcpu(cpu);
} else if (tcg_enabled()) {
qemu_tcg_init_vcpu(cpu);
} else if (whpx_enabled()) {
qemu_whpx_start_vcpu(cpu);
} else {
qemu_dummy_start_vcpu(cpu);
}

View File

@ -14,6 +14,7 @@
#include "qom/cpu.h"
#include "sysemu/hax.h"
#include "sysemu/kvm.h"
#include "sysemu/whpx.h"
static inline void cpu_synchronize_state(CPUState *cpu)
{
@ -23,6 +24,9 @@ static inline void cpu_synchronize_state(CPUState *cpu)
if (hax_enabled()) {
hax_cpu_synchronize_state(cpu);
}
if (whpx_enabled()) {
whpx_cpu_synchronize_state(cpu);
}
}
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()) {
hax_cpu_synchronize_post_reset(cpu);
}
if (whpx_enabled()) {
whpx_cpu_synchronize_post_reset(cpu);
}
}
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()) {
hax_cpu_synchronize_post_init(cpu);
}
if (whpx_enabled()) {
whpx_cpu_synchronize_post_init(cpu);
}
}
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()) {
hax_cpu_synchronize_pre_loadvm(cpu);
}
if (whpx_enabled()) {
whpx_cpu_synchronize_pre_loadvm(cpu);
}
}
#endif /* QEMU_HW_ACCEL_H */

View File

@ -986,7 +986,7 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
X86CPU *cpu = x86_env_get_cpu(env);
CPUState *cs = CPU(cpu);
if (kvm_enabled()) {
if (kvm_enabled() || whpx_enabled()) {
env->tpr_access_type = access;
cpu_interrupt(cs, CPU_INTERRUPT_TPR);