35
35
#include "sysemu/dma.h"
36
36
#include "sysemu/hw_accel.h"
37
37
#include "sysemu/kvm.h"
38
+ #include "sysemu/hax.h"
38
39
#include "qmp-commands.h"
39
40
#include "exec/exec-all.h"
40
41
@@ -1221,6 +1222,46 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
1221
1222
return NULL ;
1222
1223
}
1223
1224
1225
+ static void * qemu_hax_cpu_thread_fn (void * arg )
1226
+ {
1227
+ CPUState * cpu = arg ;
1228
+ int r ;
1229
+ qemu_thread_get_self (cpu -> thread );
1230
+ qemu_mutex_lock (& qemu_global_mutex );
1231
+
1232
+ cpu -> thread_id = qemu_get_thread_id ();
1233
+ cpu -> created = true;
1234
+ cpu -> halted = 0 ;
1235
+ current_cpu = cpu ;
1236
+
1237
+ hax_init_vcpu (cpu );
1238
+ qemu_cond_signal (& qemu_cpu_cond );
1239
+
1240
+ while (1 ) {
1241
+ if (cpu_can_run (cpu )) {
1242
+ r = hax_smp_cpu_exec (cpu );
1243
+ if (r == EXCP_DEBUG ) {
1244
+ cpu_handle_guest_debug (cpu );
1245
+ }
1246
+ }
1247
+
1248
+ while (cpu_thread_is_idle (cpu )) {
1249
+ qemu_cond_wait (cpu -> halt_cond , & qemu_global_mutex );
1250
+ }
1251
+ #ifdef _WIN32
1252
+ SleepEx (0 , TRUE);
1253
+ #endif
1254
+ qemu_wait_io_event_common (cpu );
1255
+ }
1256
+ return NULL ;
1257
+ }
1258
+
1259
+ #ifdef _WIN32
1260
+ static void CALLBACK dummy_apc_func (ULONG_PTR unused )
1261
+ {
1262
+ }
1263
+ #endif
1264
+
1224
1265
static void qemu_cpu_kick_thread (CPUState * cpu )
1225
1266
{
1226
1267
#ifndef _WIN32
@@ -1236,7 +1277,13 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
1236
1277
exit (1 );
1237
1278
}
1238
1279
#else /* _WIN32 */
1239
- abort ();
1280
+ if (!qemu_cpu_is_self (cpu )) {
1281
+ if (!QueueUserAPC (dummy_apc_func , cpu -> hThread , 0 )) {
1282
+ fprintf (stderr , "%s: QueueUserAPC failed with error %lu\n" ,
1283
+ __func__ , GetLastError ());
1284
+ exit (1 );
1285
+ }
1286
+ }
1240
1287
#endif
1241
1288
}
1242
1289
@@ -1259,6 +1306,13 @@ void qemu_cpu_kick(CPUState *cpu)
1259
1306
if (tcg_enabled ()) {
1260
1307
qemu_cpu_kick_no_halt ();
1261
1308
} else {
1309
+ if (hax_enabled ()) {
1310
+ /*
1311
+ * FIXME: race condition with the exit_request check in
1312
+ * hax_vcpu_hax_exec
1313
+ */
1314
+ cpu -> exit_request = 1 ;
1315
+ }
1262
1316
qemu_cpu_kick_thread (cpu );
1263
1317
}
1264
1318
}
@@ -1419,6 +1473,26 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
1419
1473
}
1420
1474
}
1421
1475
1476
+ static void qemu_hax_start_vcpu (CPUState * cpu )
1477
+ {
1478
+ char thread_name [VCPU_THREAD_NAME_SIZE ];
1479
+
1480
+ cpu -> thread = g_malloc0 (sizeof (QemuThread ));
1481
+ cpu -> halt_cond = g_malloc0 (sizeof (QemuCond ));
1482
+ qemu_cond_init (cpu -> halt_cond );
1483
+
1484
+ snprintf (thread_name , VCPU_THREAD_NAME_SIZE , "CPU %d/HAX" ,
1485
+ cpu -> cpu_index );
1486
+ qemu_thread_create (cpu -> thread , thread_name , qemu_hax_cpu_thread_fn ,
1487
+ cpu , QEMU_THREAD_JOINABLE );
1488
+ #ifdef _WIN32
1489
+ cpu -> hThread = qemu_thread_get_handle (cpu -> thread );
1490
+ #endif
1491
+ while (!cpu -> created ) {
1492
+ qemu_cond_wait (& qemu_cpu_cond , & qemu_global_mutex );
1493
+ }
1494
+ }
1495
+
1422
1496
static void qemu_kvm_start_vcpu (CPUState * cpu )
1423
1497
{
1424
1498
char thread_name [VCPU_THREAD_NAME_SIZE ];
@@ -1469,6 +1543,8 @@ void qemu_init_vcpu(CPUState *cpu)
1469
1543
1470
1544
if (kvm_enabled ()) {
1471
1545
qemu_kvm_start_vcpu (cpu );
1546
+ } else if (hax_enabled ()) {
1547
+ qemu_hax_start_vcpu (cpu );
1472
1548
} else if (tcg_enabled ()) {
1473
1549
qemu_tcg_init_vcpu (cpu );
1474
1550
} else {
0 commit comments