@ -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 ) ;
}