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:
parent
812d49f2a3
commit
19306806ae
69
cpus.c
69
cpus.c
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user