Message ID | 1688132988-314397-2-git-send-email-steven.sistare@oracle.com |
---|---|
State | New |
Headers | show |
Series | fix migration of suspended runstate | expand |
Steve Sistare <steven.sistare@oracle.com> writes: > If qemu starts and loads a VM in the suspended state, then a later wakeup > request directly sets the state to running. This skips vm_start() and its > initialization steps, which is fatal for the guest. See > qemu_system_wakeup_request(), and qemu_system_wakeup() in > main_loop_should_exit(). > > Remember if vm_start has been called. If not, then call vm_start from > qemu_system_wakeup_request. > > Signed-off-by: Steve Sistare <steven.sistare@oracle.com> Reviewed-by: Fabiano Rosas <farosas@suse.de>
diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h index 7beb29c..42ddf83 100644 --- a/include/sysemu/runstate.h +++ b/include/sysemu/runstate.h @@ -34,6 +34,7 @@ static inline bool shutdown_caused_by_guest(ShutdownCause cause) } void vm_start(void); +void vm_wakeup(void); /** * vm_prepare_start: Prepare for starting/resuming the VM diff --git a/softmmu/cpus.c b/softmmu/cpus.c index fed20ff..fa9e5ba 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -66,6 +66,7 @@ #endif /* CONFIG_LINUX */ static QemuMutex qemu_global_mutex; +static bool vm_started; /* * The chosen accelerator is supposed to register this. @@ -264,6 +265,7 @@ static int do_vm_stop(RunState state, bool send_stop) if (send_stop) { qapi_event_send_stop(); } + vm_started = false; } bdrv_drain_all(); @@ -722,6 +724,16 @@ void vm_start(void) { if (!vm_prepare_start(false)) { resume_all_vcpus(); + vm_started = true; + } +} + +void vm_wakeup(void) +{ + if (!vm_started) { + vm_start(); + } else { + runstate_set(RUN_STATE_RUNNING); } } diff --git a/softmmu/runstate.c b/softmmu/runstate.c index 1957caf..5bbb22a 100644 --- a/softmmu/runstate.c +++ b/softmmu/runstate.c @@ -580,7 +580,7 @@ void qemu_system_wakeup_request(WakeupReason reason, Error **errp) if (!(wakeup_reason_mask & (1 << reason))) { return; } - runstate_set(RUN_STATE_RUNNING); + vm_wakeup(); wakeup_reason = reason; qemu_notify_event(); }
If qemu starts and loads a VM in the suspended state, then a later wakeup request directly sets the state to running. This skips vm_start() and its initialization steps, which is fatal for the guest. See qemu_system_wakeup_request(), and qemu_system_wakeup() in main_loop_should_exit(). Remember if vm_start has been called. If not, then call vm_start from qemu_system_wakeup_request. Signed-off-by: Steve Sistare <steven.sistare@oracle.com> --- include/sysemu/runstate.h | 1 + softmmu/cpus.c | 12 ++++++++++++ softmmu/runstate.c | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-)