mirror of https://github.com/xqemu/xqemu.git
Plumb the HAXM-based hardware acceleration support
Use the Intel HAX is kernel-based hardware acceleration module for Windows (similar to KVM on Linux). Based on the "target/i386: Add Intel HAX to android emulator" patch from David Chou <david.j.chou@intel.com> Signed-off-by: Vincent Palatin <vpalatin@chromium.org> Message-Id: <7b9cae28a0c379ab459c7a8545c9a39762bd394f.1484045952.git.vpalatin@chromium.org> [Drop hax_populate_ram stub. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
47c1c8c12f
commit
b0cb0a66d6
|
@ -97,6 +97,7 @@ obj-y += target/$(TARGET_BASE_ARCH)/
|
||||||
obj-y += disas.o
|
obj-y += disas.o
|
||||||
obj-y += tcg-runtime.o
|
obj-y += tcg-runtime.o
|
||||||
obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
|
obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
|
||||||
|
obj-$(call lnot,$(CONFIG_HAX)) += hax-stub.o
|
||||||
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
|
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
|
||||||
|
|
||||||
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/decContext.o
|
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/decContext.o
|
||||||
|
|
|
@ -228,6 +228,7 @@ vhost_net="no"
|
||||||
vhost_scsi="no"
|
vhost_scsi="no"
|
||||||
vhost_vsock="no"
|
vhost_vsock="no"
|
||||||
kvm="no"
|
kvm="no"
|
||||||
|
hax="no"
|
||||||
rdma=""
|
rdma=""
|
||||||
gprof="no"
|
gprof="no"
|
||||||
debug_tcg="no"
|
debug_tcg="no"
|
||||||
|
@ -561,6 +562,7 @@ CYGWIN*)
|
||||||
;;
|
;;
|
||||||
MINGW32*)
|
MINGW32*)
|
||||||
mingw32="yes"
|
mingw32="yes"
|
||||||
|
hax="yes"
|
||||||
audio_possible_drivers="dsound sdl"
|
audio_possible_drivers="dsound sdl"
|
||||||
if check_include dsound.h; then
|
if check_include dsound.h; then
|
||||||
audio_drv_list="dsound"
|
audio_drv_list="dsound"
|
||||||
|
@ -610,6 +612,7 @@ OpenBSD)
|
||||||
Darwin)
|
Darwin)
|
||||||
bsd="yes"
|
bsd="yes"
|
||||||
darwin="yes"
|
darwin="yes"
|
||||||
|
hax="yes"
|
||||||
LDFLAGS_SHARED="-bundle -undefined dynamic_lookup"
|
LDFLAGS_SHARED="-bundle -undefined dynamic_lookup"
|
||||||
if [ "$cpu" = "x86_64" ] ; then
|
if [ "$cpu" = "x86_64" ] ; then
|
||||||
QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
|
QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
|
||||||
|
@ -919,6 +922,10 @@ for opt do
|
||||||
;;
|
;;
|
||||||
--enable-kvm) kvm="yes"
|
--enable-kvm) kvm="yes"
|
||||||
;;
|
;;
|
||||||
|
--disable-hax) hax="no"
|
||||||
|
;;
|
||||||
|
--enable-hax) hax="yes"
|
||||||
|
;;
|
||||||
--disable-tcg-interpreter) tcg_interpreter="no"
|
--disable-tcg-interpreter) tcg_interpreter="no"
|
||||||
;;
|
;;
|
||||||
--enable-tcg-interpreter) tcg_interpreter="yes"
|
--enable-tcg-interpreter) tcg_interpreter="yes"
|
||||||
|
@ -1367,6 +1374,7 @@ disabled with --disable-FEATURE, default is enabled if available:
|
||||||
fdt fdt device tree
|
fdt fdt device tree
|
||||||
bluez bluez stack connectivity
|
bluez bluez stack connectivity
|
||||||
kvm KVM acceleration support
|
kvm KVM acceleration support
|
||||||
|
hax HAX acceleration support
|
||||||
rdma RDMA-based migration support
|
rdma RDMA-based migration support
|
||||||
vde support for vde network
|
vde support for vde network
|
||||||
netmap support for netmap network
|
netmap support for netmap network
|
||||||
|
@ -5056,6 +5064,7 @@ echo "Linux AIO support $linux_aio"
|
||||||
echo "ATTR/XATTR support $attr"
|
echo "ATTR/XATTR support $attr"
|
||||||
echo "Install blobs $blobs"
|
echo "Install blobs $blobs"
|
||||||
echo "KVM support $kvm"
|
echo "KVM support $kvm"
|
||||||
|
echo "HAX support $hax"
|
||||||
echo "RDMA support $rdma"
|
echo "RDMA support $rdma"
|
||||||
echo "TCG interpreter $tcg_interpreter"
|
echo "TCG interpreter $tcg_interpreter"
|
||||||
echo "fdt support $fdt"
|
echo "fdt support $fdt"
|
||||||
|
@ -6039,6 +6048,15 @@ case "$target_name" in
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
esac
|
esac
|
||||||
|
if test "$hax" = "yes" ; then
|
||||||
|
if test "$target_softmmu" = "yes" ; then
|
||||||
|
case "$target_name" in
|
||||||
|
i386|x86_64)
|
||||||
|
echo "CONFIG_HAX=y" >> $config_target_mak
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if test "$target_bigendian" = "yes" ; then
|
if test "$target_bigendian" = "yes" ; then
|
||||||
echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak
|
echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak
|
||||||
fi
|
fi
|
||||||
|
|
78
cpus.c
78
cpus.c
|
@ -35,6 +35,7 @@
|
||||||
#include "sysemu/dma.h"
|
#include "sysemu/dma.h"
|
||||||
#include "sysemu/hw_accel.h"
|
#include "sysemu/hw_accel.h"
|
||||||
#include "sysemu/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
|
#include "sysemu/hax.h"
|
||||||
#include "qmp-commands.h"
|
#include "qmp-commands.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
|
@ -1221,6 +1222,46 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *qemu_hax_cpu_thread_fn(void *arg)
|
||||||
|
{
|
||||||
|
CPUState *cpu = arg;
|
||||||
|
int r;
|
||||||
|
qemu_thread_get_self(cpu->thread);
|
||||||
|
qemu_mutex_lock(&qemu_global_mutex);
|
||||||
|
|
||||||
|
cpu->thread_id = qemu_get_thread_id();
|
||||||
|
cpu->created = true;
|
||||||
|
cpu->halted = 0;
|
||||||
|
current_cpu = cpu;
|
||||||
|
|
||||||
|
hax_init_vcpu(cpu);
|
||||||
|
qemu_cond_signal(&qemu_cpu_cond);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (cpu_can_run(cpu)) {
|
||||||
|
r = hax_smp_cpu_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);
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
SleepEx(0, TRUE);
|
||||||
|
#endif
|
||||||
|
qemu_wait_io_event_common(cpu);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
static void CALLBACK dummy_apc_func(ULONG_PTR unused)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void qemu_cpu_kick_thread(CPUState *cpu)
|
static void qemu_cpu_kick_thread(CPUState *cpu)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
@ -1236,7 +1277,13 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
#else /* _WIN32 */
|
#else /* _WIN32 */
|
||||||
abort();
|
if (!qemu_cpu_is_self(cpu)) {
|
||||||
|
if (!QueueUserAPC(dummy_apc_func, cpu->hThread, 0)) {
|
||||||
|
fprintf(stderr, "%s: QueueUserAPC failed with error %lu\n",
|
||||||
|
__func__, GetLastError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1259,6 +1306,13 @@ void qemu_cpu_kick(CPUState *cpu)
|
||||||
if (tcg_enabled()) {
|
if (tcg_enabled()) {
|
||||||
qemu_cpu_kick_no_halt();
|
qemu_cpu_kick_no_halt();
|
||||||
} else {
|
} else {
|
||||||
|
if (hax_enabled()) {
|
||||||
|
/*
|
||||||
|
* FIXME: race condition with the exit_request check in
|
||||||
|
* hax_vcpu_hax_exec
|
||||||
|
*/
|
||||||
|
cpu->exit_request = 1;
|
||||||
|
}
|
||||||
qemu_cpu_kick_thread(cpu);
|
qemu_cpu_kick_thread(cpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1419,6 +1473,26 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qemu_hax_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/HAX",
|
||||||
|
cpu->cpu_index);
|
||||||
|
qemu_thread_create(cpu->thread, thread_name, qemu_hax_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_kvm_start_vcpu(CPUState *cpu)
|
static void qemu_kvm_start_vcpu(CPUState *cpu)
|
||||||
{
|
{
|
||||||
char thread_name[VCPU_THREAD_NAME_SIZE];
|
char thread_name[VCPU_THREAD_NAME_SIZE];
|
||||||
|
@ -1469,6 +1543,8 @@ void qemu_init_vcpu(CPUState *cpu)
|
||||||
|
|
||||||
if (kvm_enabled()) {
|
if (kvm_enabled()) {
|
||||||
qemu_kvm_start_vcpu(cpu);
|
qemu_kvm_start_vcpu(cpu);
|
||||||
|
} else if (hax_enabled()) {
|
||||||
|
qemu_hax_start_vcpu(cpu);
|
||||||
} else if (tcg_enabled()) {
|
} else if (tcg_enabled()) {
|
||||||
qemu_tcg_init_vcpu(cpu);
|
qemu_tcg_init_vcpu(cpu);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -23,11 +23,6 @@ int hax_sync_vcpus(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hax_populate_ram(uint64_t va, uint32_t size)
|
|
||||||
{
|
|
||||||
return -ENOSYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hax_init_vcpu(CPUState *cpu)
|
int hax_init_vcpu(CPUState *cpu)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "hw/i386/apic.h"
|
#include "hw/i386/apic.h"
|
||||||
#include "hw/i386/apic_internal.h"
|
#include "hw/i386/apic_internal.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
#include "sysemu/hax.h"
|
||||||
#include "sysemu/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
#include "hw/qdev.h"
|
#include "hw/qdev.h"
|
||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
|
@ -316,7 +317,7 @@ static void apic_common_realize(DeviceState *dev, Error **errp)
|
||||||
|
|
||||||
/* Note: We need at least 1M to map the VAPIC option ROM */
|
/* Note: We need at least 1M to map the VAPIC option ROM */
|
||||||
if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK &&
|
if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK &&
|
||||||
ram_size >= 1024 * 1024) {
|
!hax_enabled() && ram_size >= 1024 * 1024) {
|
||||||
vapic = sysbus_create_simple("kvmvapic", -1, NULL);
|
vapic = sysbus_create_simple("kvmvapic", -1, NULL);
|
||||||
}
|
}
|
||||||
s->vapic = vapic;
|
s->vapic = vapic;
|
||||||
|
|
|
@ -227,6 +227,8 @@ struct CPUWatchpoint {
|
||||||
struct KVMState;
|
struct KVMState;
|
||||||
struct kvm_run;
|
struct kvm_run;
|
||||||
|
|
||||||
|
struct hax_vcpu_state;
|
||||||
|
|
||||||
#define TB_JMP_CACHE_BITS 12
|
#define TB_JMP_CACHE_BITS 12
|
||||||
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
|
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
|
||||||
|
|
||||||
|
@ -392,6 +394,9 @@ struct CPUState {
|
||||||
(absolute value) offset as small as possible. This reduces code
|
(absolute value) offset as small as possible. This reduces code
|
||||||
size, especially for hosts without large memory offsets. */
|
size, especially for hosts without large memory offsets. */
|
||||||
uint32_t tcg_exit_req;
|
uint32_t tcg_exit_req;
|
||||||
|
|
||||||
|
bool hax_vcpu_dirty;
|
||||||
|
struct hax_vcpu_state *hax_vcpu;
|
||||||
};
|
};
|
||||||
|
|
||||||
QTAILQ_HEAD(CPUTailQ, CPUState);
|
QTAILQ_HEAD(CPUTailQ, CPUState);
|
||||||
|
|
|
@ -20,6 +20,9 @@ static inline void cpu_synchronize_state(CPUState *cpu)
|
||||||
if (kvm_enabled()) {
|
if (kvm_enabled()) {
|
||||||
kvm_cpu_synchronize_state(cpu);
|
kvm_cpu_synchronize_state(cpu);
|
||||||
}
|
}
|
||||||
|
if (hax_enabled()) {
|
||||||
|
hax_cpu_synchronize_state(cpu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cpu_synchronize_post_reset(CPUState *cpu)
|
static inline void cpu_synchronize_post_reset(CPUState *cpu)
|
||||||
|
@ -27,6 +30,9 @@ static inline void cpu_synchronize_post_reset(CPUState *cpu)
|
||||||
if (kvm_enabled()) {
|
if (kvm_enabled()) {
|
||||||
kvm_cpu_synchronize_post_reset(cpu);
|
kvm_cpu_synchronize_post_reset(cpu);
|
||||||
}
|
}
|
||||||
|
if (hax_enabled()) {
|
||||||
|
hax_cpu_synchronize_post_reset(cpu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cpu_synchronize_post_init(CPUState *cpu)
|
static inline void cpu_synchronize_post_init(CPUState *cpu)
|
||||||
|
@ -34,6 +40,9 @@ static inline void cpu_synchronize_post_init(CPUState *cpu)
|
||||||
if (kvm_enabled()) {
|
if (kvm_enabled()) {
|
||||||
kvm_cpu_synchronize_post_init(cpu);
|
kvm_cpu_synchronize_post_init(cpu);
|
||||||
}
|
}
|
||||||
|
if (hax_enabled()) {
|
||||||
|
hax_cpu_synchronize_post_init(cpu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* QEMU_HW_ACCEL_H */
|
#endif /* QEMU_HW_ACCEL_H */
|
||||||
|
|
|
@ -3280,6 +3280,17 @@ Enable KVM full virtualization support. This option is only available
|
||||||
if KVM support is enabled when compiling.
|
if KVM support is enabled when compiling.
|
||||||
ETEXI
|
ETEXI
|
||||||
|
|
||||||
|
DEF("enable-hax", 0, QEMU_OPTION_enable_hax, \
|
||||||
|
"-enable-hax enable HAX virtualization support\n", QEMU_ARCH_I386)
|
||||||
|
STEXI
|
||||||
|
@item -enable-hax
|
||||||
|
@findex -enable-hax
|
||||||
|
Enable HAX (Hardware-based Acceleration eXecution) support. This option
|
||||||
|
is only available if HAX support is enabled when compiling. HAX is only
|
||||||
|
applicable to MAC and Windows platform, and thus does not conflict with
|
||||||
|
KVM.
|
||||||
|
ETEXI
|
||||||
|
|
||||||
DEF("xen-domid", HAS_ARG, QEMU_OPTION_xen_domid,
|
DEF("xen-domid", HAS_ARG, QEMU_OPTION_xen_domid,
|
||||||
"-xen-domid id specify xen guest domain id\n", QEMU_ARCH_ALL)
|
"-xen-domid id specify xen guest domain id\n", QEMU_ARCH_ALL)
|
||||||
DEF("xen-create", 0, QEMU_OPTION_xen_create,
|
DEF("xen-create", 0, QEMU_OPTION_xen_create,
|
||||||
|
|
|
@ -5,3 +5,7 @@ obj-y += gdbstub.o
|
||||||
obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o monitor.o
|
obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o monitor.o
|
||||||
obj-$(CONFIG_KVM) += kvm.o hyperv.o
|
obj-$(CONFIG_KVM) += kvm.o hyperv.o
|
||||||
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
|
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
|
||||||
|
# HAX support
|
||||||
|
ifdef CONFIG_WIN32
|
||||||
|
obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-windows.o
|
||||||
|
endif
|
||||||
|
|
|
@ -497,8 +497,8 @@ HANDLE qemu_thread_get_handle(QemuThread *thread)
|
||||||
|
|
||||||
EnterCriticalSection(&data->cs);
|
EnterCriticalSection(&data->cs);
|
||||||
if (!data->exited) {
|
if (!data->exited) {
|
||||||
handle = OpenThread(SYNCHRONIZE | THREAD_SUSPEND_RESUME, FALSE,
|
handle = OpenThread(SYNCHRONIZE | THREAD_SUSPEND_RESUME |
|
||||||
thread->tid);
|
THREAD_SET_CONTEXT, FALSE, thread->tid);
|
||||||
} else {
|
} else {
|
||||||
handle = NULL;
|
handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
15
vl.c
15
vl.c
|
@ -93,6 +93,7 @@ int main(int argc, char **argv)
|
||||||
#include "sysemu/cpus.h"
|
#include "sysemu/cpus.h"
|
||||||
#include "migration/colo.h"
|
#include "migration/colo.h"
|
||||||
#include "sysemu/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
|
#include "sysemu/hax.h"
|
||||||
#include "qapi/qmp/qjson.h"
|
#include "qapi/qmp/qjson.h"
|
||||||
#include "qemu/option.h"
|
#include "qemu/option.h"
|
||||||
#include "qemu/config-file.h"
|
#include "qemu/config-file.h"
|
||||||
|
@ -1913,7 +1914,7 @@ static void main_loop(void)
|
||||||
int64_t ti;
|
int64_t ti;
|
||||||
#endif
|
#endif
|
||||||
do {
|
do {
|
||||||
nonblocking = !kvm_enabled() && !xen_enabled() && last_io > 0;
|
nonblocking = tcg_enabled() && last_io > 0;
|
||||||
#ifdef CONFIG_PROFILER
|
#ifdef CONFIG_PROFILER
|
||||||
ti = profile_getclock();
|
ti = profile_getclock();
|
||||||
#endif
|
#endif
|
||||||
|
@ -3679,6 +3680,10 @@ int main(int argc, char **argv, char **envp)
|
||||||
olist = qemu_find_opts("machine");
|
olist = qemu_find_opts("machine");
|
||||||
qemu_opts_parse_noisily(olist, "accel=kvm", false);
|
qemu_opts_parse_noisily(olist, "accel=kvm", false);
|
||||||
break;
|
break;
|
||||||
|
case QEMU_OPTION_enable_hax:
|
||||||
|
olist = qemu_find_opts("machine");
|
||||||
|
qemu_opts_parse_noisily(olist, "accel=hax", false);
|
||||||
|
break;
|
||||||
case QEMU_OPTION_M:
|
case QEMU_OPTION_M:
|
||||||
case QEMU_OPTION_machine:
|
case QEMU_OPTION_machine:
|
||||||
olist = qemu_find_opts("machine");
|
olist = qemu_find_opts("machine");
|
||||||
|
@ -4373,8 +4378,8 @@ int main(int argc, char **argv, char **envp)
|
||||||
|
|
||||||
cpu_ticks_init();
|
cpu_ticks_init();
|
||||||
if (icount_opts) {
|
if (icount_opts) {
|
||||||
if (kvm_enabled() || xen_enabled()) {
|
if (!tcg_enabled()) {
|
||||||
error_report("-icount is not allowed with kvm or xen");
|
error_report("-icount is not allowed with hardware virtualization");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
configure_icount(icount_opts, &error_abort);
|
configure_icount(icount_opts, &error_abort);
|
||||||
|
@ -4510,6 +4515,10 @@ int main(int argc, char **argv, char **envp)
|
||||||
|
|
||||||
numa_post_machine_init();
|
numa_post_machine_init();
|
||||||
|
|
||||||
|
if (hax_enabled()) {
|
||||||
|
hax_sync_vcpus();
|
||||||
|
}
|
||||||
|
|
||||||
if (qemu_opts_foreach(qemu_find_opts("fw_cfg"),
|
if (qemu_opts_foreach(qemu_find_opts("fw_cfg"),
|
||||||
parse_fw_cfg, fw_cfg_find(), NULL) != 0) {
|
parse_fw_cfg, fw_cfg_find(), NULL) != 0) {
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
Loading…
Reference in New Issue