Keep cpus.c focused on vCPUs handling, move code related to VM state to runstate.c where similar code lives.
Fix few checkpatch.pl warnings: WARNING: Block comments use a leading /* on a separate line WARNING: Block comments use * on subsequent lines #327: FILE: system/runstate.c:541: +/* does a state transition even if the VM is already stopped, + current state is forgotten forever */ Signed-off-by: Philippe Mathieu-Daudé <[email protected]> --- system/cpus.c | 147 ------------------------------------------- system/runstate.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 147 deletions(-) diff --git a/system/cpus.c b/system/cpus.c index 43ff10cf008..f37e215c586 100644 --- a/system/cpus.c +++ b/system/cpus.c @@ -25,7 +25,6 @@ #include "qemu/osdep.h" #include "qemu/coroutine-tls.h" #include "qapi/error.h" -#include "qapi/qapi-events-run-state.h" #include "exec/gdbstub.h" #include "accel/accel-cpu-ops.h" #include "system/hw_accel.h" @@ -272,58 +271,6 @@ void cpu_interrupt(CPUState *cpu, int mask) cpus_accel->handle_interrupt(cpu, mask); } -/* - * True if the vm was previously suspended, and has not been woken or reset. - */ -static int vm_was_suspended; - -void vm_set_suspended(bool suspended) -{ - vm_was_suspended = suspended; -} - -bool vm_get_suspended(void) -{ - return vm_was_suspended; -} - -static int do_vm_stop(RunState state, bool send_stop) -{ - int ret = 0; - RunState oldstate = runstate_get(); - - if (runstate_is_live(oldstate)) { - vm_was_suspended = (oldstate == RUN_STATE_SUSPENDED); - runstate_set(state); - cpu_disable_ticks(); - if (oldstate == RUN_STATE_RUNNING) { - pause_all_vcpus(); - } - ret = vm_state_notify(0, state); - if (send_stop) { - qapi_event_send_stop(); - } - } - - bdrv_drain_all(); - /* - * Even if vm_state_notify() return failure, - * it would be better to flush as before. - */ - ret |= bdrv_flush_all(); - trace_vm_stop_flush_all(ret); - - return ret; -} - -/* Special vm_stop() variant for terminating the process. Historically clients - * did not expect a QMP STOP event and so we need to retain compatibility. - */ -int vm_shutdown(void) -{ - return do_vm_stop(RUN_STATE_SHUTDOWN, false); -} - bool cpu_can_run(CPUState *cpu) { if (cpu->stop) { @@ -734,97 +681,3 @@ void cpu_stop_current(void) cpu_exit(current_cpu); } } - -int vm_stop(RunState state) -{ - if (qemu_in_vcpu_thread()) { - qemu_system_vmstop_request_prepare(); - qemu_system_vmstop_request(state); - /* - * FIXME: should not return to device code in case - * vm_stop() has been requested. - */ - cpu_stop_current(); - return 0; - } - - return do_vm_stop(state, true); -} - -/** - * Prepare for (re)starting the VM. - * Returns 0 if the vCPUs should be restarted, -1 on an error condition, - * and 1 otherwise. - */ -int vm_prepare_start(bool step_pending) -{ - int ret = vm_was_suspended ? 1 : 0; - RunState state = vm_was_suspended ? RUN_STATE_SUSPENDED : RUN_STATE_RUNNING; - RunState requested; - - qemu_vmstop_requested(&requested); - if (runstate_is_running() && requested == RUN_STATE__MAX) { - return -1; - } - - /* Ensure that a STOP/RESUME pair of events is emitted if a - * vmstop request was pending. The BLOCK_IO_ERROR event, for - * example, according to documentation is always followed by - * the STOP event. - */ - if (runstate_is_running()) { - qapi_event_send_stop(); - qapi_event_send_resume(); - return -1; - } - - /* - * WHPX accelerator needs to know whether we are going to step - * any CPUs, before starting the first one. - */ - accel_pre_resume(MACHINE(qdev_get_machine()), step_pending); - - /* We are sending this now, but the CPUs will be resumed shortly later */ - qapi_event_send_resume(); - - cpu_enable_ticks(); - runstate_set(state); - vm_state_notify(1, state); - vm_was_suspended = false; - return ret; -} - -void vm_start(void) -{ - if (!vm_prepare_start(false)) { - resume_all_vcpus(); - } -} - -void vm_resume(RunState state) -{ - if (runstate_is_live(state)) { - vm_start(); - } else { - runstate_set(state); - } -} - -/* does a state transition even if the VM is already stopped, - current state is forgotten forever */ -int vm_stop_force_state(RunState state) -{ - if (runstate_is_live(runstate_get())) { - return vm_stop(state); - } else { - int ret; - runstate_set(state); - - bdrv_drain_all(); - /* Make sure to return an error if the flush in a previous vm_stop() - * failed. */ - ret = bdrv_flush_all(); - trace_vm_stop_flush_all(ret); - return ret; - } -} diff --git a/system/runstate.c b/system/runstate.c index 08acf801b0e..d3e64d2b625 100644 --- a/system/runstate.c +++ b/system/runstate.c @@ -52,6 +52,7 @@ #include "qemu/thread.h" #include "qom/object.h" #include "qom/object_interfaces.h" +#include "system/cpu-timers.h" #include "system/cpus.h" #include "system/qtest.h" #include "system/replay.h" @@ -408,6 +409,159 @@ int vm_state_notify(bool running, RunState state) return ret; } +/* + * True if the vm was previously suspended, and has not been woken or reset. + */ +static int vm_was_suspended; + +void vm_set_suspended(bool suspended) +{ + vm_was_suspended = suspended; +} + +bool vm_get_suspended(void) +{ + return vm_was_suspended; +} + +static int do_vm_stop(RunState state, bool send_stop) +{ + int ret = 0; + RunState oldstate = runstate_get(); + + if (runstate_is_live(oldstate)) { + vm_was_suspended = (oldstate == RUN_STATE_SUSPENDED); + runstate_set(state); + cpu_disable_ticks(); + if (oldstate == RUN_STATE_RUNNING) { + pause_all_vcpus(); + } + ret = vm_state_notify(0, state); + if (send_stop) { + qapi_event_send_stop(); + } + } + + bdrv_drain_all(); + /* + * Even if vm_state_notify() return failure, + * it would be better to flush as before. + */ + ret |= bdrv_flush_all(); + trace_vm_stop_flush_all(ret); + + return ret; +} + +/* + * Special vm_stop() variant for terminating the process. Historically clients + * did not expect a QMP STOP event and so we need to retain compatibility. + */ +int vm_shutdown(void) +{ + return do_vm_stop(RUN_STATE_SHUTDOWN, false); +} + + +int vm_stop(RunState state) +{ + if (qemu_in_vcpu_thread()) { + qemu_system_vmstop_request_prepare(); + qemu_system_vmstop_request(state); + /* + * FIXME: should not return to device code in case + * vm_stop() has been requested. + */ + cpu_stop_current(); + return 0; + } + + return do_vm_stop(state, true); +} + +/** + * Prepare for (re)starting the VM. + * Returns 0 if the vCPUs should be restarted, -1 on an error condition, + * and 1 otherwise. + */ +int vm_prepare_start(bool step_pending) +{ + int ret = vm_was_suspended ? 1 : 0; + RunState state = vm_was_suspended ? RUN_STATE_SUSPENDED : RUN_STATE_RUNNING; + RunState requested; + + qemu_vmstop_requested(&requested); + if (runstate_is_running() && requested == RUN_STATE__MAX) { + return -1; + } + + /* + * Ensure that a STOP/RESUME pair of events is emitted if a + * vmstop request was pending. The BLOCK_IO_ERROR event, for + * example, according to documentation is always followed by + * the STOP event. + */ + if (runstate_is_running()) { + qapi_event_send_stop(); + qapi_event_send_resume(); + return -1; + } + + /* + * WHPX accelerator needs to know whether we are going to step + * any CPUs, before starting the first one. + */ + accel_pre_resume(MACHINE(qdev_get_machine()), step_pending); + + /* We are sending this now, but the CPUs will be resumed shortly later */ + qapi_event_send_resume(); + + cpu_enable_ticks(); + runstate_set(state); + vm_state_notify(1, state); + vm_was_suspended = false; + return ret; +} + +void vm_start(void) +{ + if (!vm_prepare_start(false)) { + resume_all_vcpus(); + } +} + +void vm_resume(RunState state) +{ + if (runstate_is_live(state)) { + vm_start(); + } else { + runstate_set(state); + } +} + +/* + * does a state transition even if the VM is already stopped, + * current state is forgotten forever + */ +int vm_stop_force_state(RunState state) +{ + if (runstate_is_live(runstate_get())) { + return vm_stop(state); + } else { + int ret; + runstate_set(state); + + bdrv_drain_all(); + /* + * Make sure to return an error if the flush in a previous vm_stop() + * failed. + */ + ret = bdrv_flush_all(); + trace_vm_stop_flush_all(ret); + return ret; + } +} + static ShutdownCause reset_requested; static ShutdownCause shutdown_requested; static int shutdown_exit_code = EXIT_SUCCESS; -- 2.53.0
