mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2026-08-26 22:23:12 -04:00
system: Move runstate-related code from cpus.c to runstate.c
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é <philmd@oss.qualcomm.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20260812211708.92824-17-philmd@oss.qualcomm.com>
This commit is contained in:
parent
259c2aae8d
commit
f036b28896
2 changed files with 154 additions and 147 deletions
147
system/cpus.c
147
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue