mirror of https://github.com/xemu-project/xemu.git
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/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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
#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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
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 @@
|
||||||
#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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue