xref: /qemu/system/runstate.c (revision e7bc0204e57836b3df611b73d2decc56ed698c4a)
1ba87e434SPaolo Bonzini /*
2ba87e434SPaolo Bonzini  * QEMU main system emulation loop
3ba87e434SPaolo Bonzini  *
4ba87e434SPaolo Bonzini  * Copyright (c) 2003-2020 QEMU contributors
5ba87e434SPaolo Bonzini  *
6ba87e434SPaolo Bonzini  * Permission is hereby granted, free of charge, to any person obtaining a copy
7ba87e434SPaolo Bonzini  * of this software and associated documentation files (the "Software"), to deal
8ba87e434SPaolo Bonzini  * in the Software without restriction, including without limitation the rights
9ba87e434SPaolo Bonzini  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10ba87e434SPaolo Bonzini  * copies of the Software, and to permit persons to whom the Software is
11ba87e434SPaolo Bonzini  * furnished to do so, subject to the following conditions:
12ba87e434SPaolo Bonzini  *
13ba87e434SPaolo Bonzini  * The above copyright notice and this permission notice shall be included in
14ba87e434SPaolo Bonzini  * all copies or substantial portions of the Software.
15ba87e434SPaolo Bonzini  *
16ba87e434SPaolo Bonzini  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17ba87e434SPaolo Bonzini  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18ba87e434SPaolo Bonzini  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19ba87e434SPaolo Bonzini  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20ba87e434SPaolo Bonzini  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21ba87e434SPaolo Bonzini  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22ba87e434SPaolo Bonzini  * THE SOFTWARE.
23ba87e434SPaolo Bonzini  */
24ba87e434SPaolo Bonzini 
25ba87e434SPaolo Bonzini #include "qemu/osdep.h"
26ba87e434SPaolo Bonzini #include "audio/audio.h"
27ba87e434SPaolo Bonzini #include "block/block.h"
281895b977SSergio Lopez #include "block/export.h"
29ba87e434SPaolo Bonzini #include "chardev/char.h"
30ba87e434SPaolo Bonzini #include "crypto/cipher.h"
31ba87e434SPaolo Bonzini #include "crypto/init.h"
32ba87e434SPaolo Bonzini #include "exec/cpu-common.h"
33c566080cSAlex Bennée #include "gdbstub/syscalls.h"
34ba87e434SPaolo Bonzini #include "hw/boards.h"
351b063fe2SJuraj Marcin #include "hw/resettable.h"
36ba87e434SPaolo Bonzini #include "migration/misc.h"
37ba87e434SPaolo Bonzini #include "migration/postcopy-ram.h"
38ba87e434SPaolo Bonzini #include "monitor/monitor.h"
39ba87e434SPaolo Bonzini #include "net/net.h"
40ba87e434SPaolo Bonzini #include "net/vhost_net.h"
41ba87e434SPaolo Bonzini #include "qapi/error.h"
42ba87e434SPaolo Bonzini #include "qapi/qapi-commands-run-state.h"
43ba87e434SPaolo Bonzini #include "qapi/qapi-events-run-state.h"
4493cbd6c9SPeter Maydell #include "qemu/accel.h"
45ba87e434SPaolo Bonzini #include "qemu/error-report.h"
46ba87e434SPaolo Bonzini #include "qemu/job.h"
47bc2fbf93SPhilippe Mathieu-Daudé #include "qemu/log.h"
48ba87e434SPaolo Bonzini #include "qemu/module.h"
49ba87e434SPaolo Bonzini #include "qemu/sockets.h"
50533206f0SRichard W.M. Jones #include "qemu/timer.h"
51ba87e434SPaolo Bonzini #include "qemu/thread.h"
52ba87e434SPaolo Bonzini #include "qom/object.h"
53ba87e434SPaolo Bonzini #include "qom/object_interfaces.h"
5432cad1ffSPhilippe Mathieu-Daudé #include "system/cpus.h"
5532cad1ffSPhilippe Mathieu-Daudé #include "system/qtest.h"
5632cad1ffSPhilippe Mathieu-Daudé #include "system/replay.h"
5732cad1ffSPhilippe Mathieu-Daudé #include "system/reset.h"
5832cad1ffSPhilippe Mathieu-Daudé #include "system/runstate.h"
5932cad1ffSPhilippe Mathieu-Daudé #include "system/runstate-action.h"
6032cad1ffSPhilippe Mathieu-Daudé #include "system/system.h"
6132cad1ffSPhilippe Mathieu-Daudé #include "system/tpm.h"
62ba87e434SPaolo Bonzini #include "trace.h"
63ba87e434SPaolo Bonzini 
64ba87e434SPaolo Bonzini static NotifierList exit_notifiers =
65ba87e434SPaolo Bonzini     NOTIFIER_LIST_INITIALIZER(exit_notifiers);
66ba87e434SPaolo Bonzini 
67ba87e434SPaolo Bonzini static RunState current_run_state = RUN_STATE_PRELAUNCH;
68ba87e434SPaolo Bonzini 
69ba87e434SPaolo Bonzini /* We use RUN_STATE__MAX but any invalid value will do */
70ba87e434SPaolo Bonzini static RunState vmstop_requested = RUN_STATE__MAX;
71ba87e434SPaolo Bonzini static QemuMutex vmstop_lock;
72ba87e434SPaolo Bonzini 
73ba87e434SPaolo Bonzini typedef struct {
74ba87e434SPaolo Bonzini     RunState from;
75ba87e434SPaolo Bonzini     RunState to;
76ba87e434SPaolo Bonzini } RunStateTransition;
77ba87e434SPaolo Bonzini 
78ba87e434SPaolo Bonzini static const RunStateTransition runstate_transitions_def[] = {
79ba87e434SPaolo Bonzini     { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
8058b10570SSteve Sistare     { RUN_STATE_PRELAUNCH, RUN_STATE_SUSPENDED },
81ba87e434SPaolo Bonzini 
82ba87e434SPaolo Bonzini     { RUN_STATE_DEBUG, RUN_STATE_RUNNING },
83ba87e434SPaolo Bonzini     { RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
84ba87e434SPaolo Bonzini     { RUN_STATE_DEBUG, RUN_STATE_PRELAUNCH },
85ba87e434SPaolo Bonzini 
86ba87e434SPaolo Bonzini     { RUN_STATE_INMIGRATE, RUN_STATE_INTERNAL_ERROR },
87ba87e434SPaolo Bonzini     { RUN_STATE_INMIGRATE, RUN_STATE_IO_ERROR },
88ba87e434SPaolo Bonzini     { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED },
89ba87e434SPaolo Bonzini     { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING },
90ba87e434SPaolo Bonzini     { RUN_STATE_INMIGRATE, RUN_STATE_SHUTDOWN },
91ba87e434SPaolo Bonzini     { RUN_STATE_INMIGRATE, RUN_STATE_SUSPENDED },
92ba87e434SPaolo Bonzini     { RUN_STATE_INMIGRATE, RUN_STATE_WATCHDOG },
93ba87e434SPaolo Bonzini     { RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED },
94ba87e434SPaolo Bonzini     { RUN_STATE_INMIGRATE, RUN_STATE_FINISH_MIGRATE },
95ba87e434SPaolo Bonzini     { RUN_STATE_INMIGRATE, RUN_STATE_PRELAUNCH },
96ba87e434SPaolo Bonzini     { RUN_STATE_INMIGRATE, RUN_STATE_POSTMIGRATE },
97ba87e434SPaolo Bonzini     { RUN_STATE_INMIGRATE, RUN_STATE_COLO },
98ba87e434SPaolo Bonzini 
99ba87e434SPaolo Bonzini     { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
100ba87e434SPaolo Bonzini     { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
101ba87e434SPaolo Bonzini     { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PRELAUNCH },
102ba87e434SPaolo Bonzini 
103ba87e434SPaolo Bonzini     { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },
104ba87e434SPaolo Bonzini     { RUN_STATE_IO_ERROR, RUN_STATE_FINISH_MIGRATE },
105ba87e434SPaolo Bonzini     { RUN_STATE_IO_ERROR, RUN_STATE_PRELAUNCH },
106ba87e434SPaolo Bonzini 
107ba87e434SPaolo Bonzini     { RUN_STATE_PAUSED, RUN_STATE_RUNNING },
108ba87e434SPaolo Bonzini     { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
109ba87e434SPaolo Bonzini     { RUN_STATE_PAUSED, RUN_STATE_POSTMIGRATE },
110ba87e434SPaolo Bonzini     { RUN_STATE_PAUSED, RUN_STATE_PRELAUNCH },
111ba87e434SPaolo Bonzini     { RUN_STATE_PAUSED, RUN_STATE_COLO},
112b9ae473dSSteve Sistare     { RUN_STATE_PAUSED, RUN_STATE_SUSPENDED},
113ba87e434SPaolo Bonzini 
114ba87e434SPaolo Bonzini     { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
115ba87e434SPaolo Bonzini     { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
116ba87e434SPaolo Bonzini     { RUN_STATE_POSTMIGRATE, RUN_STATE_PRELAUNCH },
117ba87e434SPaolo Bonzini 
118ba87e434SPaolo Bonzini     { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING },
119ba87e434SPaolo Bonzini     { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE },
120ba87e434SPaolo Bonzini     { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
121ba87e434SPaolo Bonzini 
122ba87e434SPaolo Bonzini     { RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING },
123ba87e434SPaolo Bonzini     { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PAUSED },
124ba87e434SPaolo Bonzini     { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
125ba87e434SPaolo Bonzini     { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PRELAUNCH },
126ba87e434SPaolo Bonzini     { RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO },
127a4c6275aSVladimir Sementsov-Ogievskiy     { RUN_STATE_FINISH_MIGRATE, RUN_STATE_INTERNAL_ERROR },
128a4c6275aSVladimir Sementsov-Ogievskiy     { RUN_STATE_FINISH_MIGRATE, RUN_STATE_IO_ERROR },
129a4c6275aSVladimir Sementsov-Ogievskiy     { RUN_STATE_FINISH_MIGRATE, RUN_STATE_SHUTDOWN },
130a4c6275aSVladimir Sementsov-Ogievskiy     { RUN_STATE_FINISH_MIGRATE, RUN_STATE_SUSPENDED },
131a4c6275aSVladimir Sementsov-Ogievskiy     { RUN_STATE_FINISH_MIGRATE, RUN_STATE_WATCHDOG },
132a4c6275aSVladimir Sementsov-Ogievskiy     { RUN_STATE_FINISH_MIGRATE, RUN_STATE_GUEST_PANICKED },
133ba87e434SPaolo Bonzini 
134ba87e434SPaolo Bonzini     { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING },
135ba87e434SPaolo Bonzini     { RUN_STATE_RESTORE_VM, RUN_STATE_PRELAUNCH },
13658b10570SSteve Sistare     { RUN_STATE_RESTORE_VM, RUN_STATE_SUSPENDED },
137ba87e434SPaolo Bonzini 
138ba87e434SPaolo Bonzini     { RUN_STATE_COLO, RUN_STATE_RUNNING },
139669846c5SZhang Chen     { RUN_STATE_COLO, RUN_STATE_PRELAUNCH },
140229620d5SRao, Lei     { RUN_STATE_COLO, RUN_STATE_SHUTDOWN},
141ba87e434SPaolo Bonzini 
142ba87e434SPaolo Bonzini     { RUN_STATE_RUNNING, RUN_STATE_DEBUG },
143ba87e434SPaolo Bonzini     { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
144ba87e434SPaolo Bonzini     { RUN_STATE_RUNNING, RUN_STATE_IO_ERROR },
145ba87e434SPaolo Bonzini     { RUN_STATE_RUNNING, RUN_STATE_PAUSED },
146ba87e434SPaolo Bonzini     { RUN_STATE_RUNNING, RUN_STATE_FINISH_MIGRATE },
147ba87e434SPaolo Bonzini     { RUN_STATE_RUNNING, RUN_STATE_RESTORE_VM },
148ba87e434SPaolo Bonzini     { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM },
149ba87e434SPaolo Bonzini     { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
150ba87e434SPaolo Bonzini     { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
151ba87e434SPaolo Bonzini     { RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
152ba87e434SPaolo Bonzini     { RUN_STATE_RUNNING, RUN_STATE_COLO},
153ba87e434SPaolo Bonzini 
154ba87e434SPaolo Bonzini     { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
15558b10570SSteve Sistare     { RUN_STATE_SAVE_VM, RUN_STATE_SUSPENDED },
156ba87e434SPaolo Bonzini 
157ba87e434SPaolo Bonzini     { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
158ba87e434SPaolo Bonzini     { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
159ba87e434SPaolo Bonzini     { RUN_STATE_SHUTDOWN, RUN_STATE_PRELAUNCH },
160ba87e434SPaolo Bonzini     { RUN_STATE_SHUTDOWN, RUN_STATE_COLO },
161ba87e434SPaolo Bonzini 
162ba87e434SPaolo Bonzini     { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
163ba87e434SPaolo Bonzini     { RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
164ba87e434SPaolo Bonzini     { RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
165ba87e434SPaolo Bonzini     { RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
166ba87e434SPaolo Bonzini     { RUN_STATE_SUSPENDED, RUN_STATE_PRELAUNCH },
167ba87e434SPaolo Bonzini     { RUN_STATE_SUSPENDED, RUN_STATE_COLO},
168b9ae473dSSteve Sistare     { RUN_STATE_SUSPENDED, RUN_STATE_PAUSED},
16958b10570SSteve Sistare     { RUN_STATE_SUSPENDED, RUN_STATE_SAVE_VM },
17058b10570SSteve Sistare     { RUN_STATE_SUSPENDED, RUN_STATE_RESTORE_VM },
17149a50206SSteve Sistare     { RUN_STATE_SUSPENDED, RUN_STATE_SHUTDOWN },
172ba87e434SPaolo Bonzini 
173ba87e434SPaolo Bonzini     { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
174ba87e434SPaolo Bonzini     { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
175ba87e434SPaolo Bonzini     { RUN_STATE_WATCHDOG, RUN_STATE_PRELAUNCH },
176ba87e434SPaolo Bonzini     { RUN_STATE_WATCHDOG, RUN_STATE_COLO},
177ba87e434SPaolo Bonzini 
178ba87e434SPaolo Bonzini     { RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING },
179ba87e434SPaolo Bonzini     { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
180ba87e434SPaolo Bonzini     { RUN_STATE_GUEST_PANICKED, RUN_STATE_PRELAUNCH },
181ba87e434SPaolo Bonzini 
182ba87e434SPaolo Bonzini     { RUN_STATE__MAX, RUN_STATE__MAX },
183ba87e434SPaolo Bonzini };
184ba87e434SPaolo Bonzini 
1859dbab31dSNicholas Piggin static const RunStateTransition replay_play_runstate_transitions_def[] = {
1869dbab31dSNicholas Piggin     { RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING},
1879dbab31dSNicholas Piggin 
1889dbab31dSNicholas Piggin     { RUN_STATE__MAX, RUN_STATE__MAX },
1899dbab31dSNicholas Piggin };
1909dbab31dSNicholas Piggin 
191ba87e434SPaolo Bonzini static bool runstate_valid_transitions[RUN_STATE__MAX][RUN_STATE__MAX];
192ba87e434SPaolo Bonzini 
runstate_check(RunState state)193ba87e434SPaolo Bonzini bool runstate_check(RunState state)
194ba87e434SPaolo Bonzini {
195ba87e434SPaolo Bonzini     return current_run_state == state;
196ba87e434SPaolo Bonzini }
197ba87e434SPaolo Bonzini 
transitions_set_valid(const RunStateTransition * rst)1989dbab31dSNicholas Piggin static void transitions_set_valid(const RunStateTransition *rst)
199ba87e434SPaolo Bonzini {
200ba87e434SPaolo Bonzini     const RunStateTransition *p;
201ba87e434SPaolo Bonzini 
2029dbab31dSNicholas Piggin     for (p = rst; p->from != RUN_STATE__MAX; p++) {
203ba87e434SPaolo Bonzini         runstate_valid_transitions[p->from][p->to] = true;
204ba87e434SPaolo Bonzini     }
2059dbab31dSNicholas Piggin }
2069dbab31dSNicholas Piggin 
runstate_replay_enable(void)2079dbab31dSNicholas Piggin void runstate_replay_enable(void)
2089dbab31dSNicholas Piggin {
2099dbab31dSNicholas Piggin     assert(replay_mode != REPLAY_MODE_NONE);
2109dbab31dSNicholas Piggin 
2119dbab31dSNicholas Piggin     if (replay_mode == REPLAY_MODE_PLAY) {
2129dbab31dSNicholas Piggin         /*
2139dbab31dSNicholas Piggin          * When reverse-debugging, it is possible to move state from
2149dbab31dSNicholas Piggin          * shutdown to running.
2159dbab31dSNicholas Piggin          */
2169dbab31dSNicholas Piggin         transitions_set_valid(&replay_play_runstate_transitions_def[0]);
2179dbab31dSNicholas Piggin     }
2189dbab31dSNicholas Piggin }
2199dbab31dSNicholas Piggin 
runstate_init(void)2209dbab31dSNicholas Piggin static void runstate_init(void)
2219dbab31dSNicholas Piggin {
2229dbab31dSNicholas Piggin     memset(&runstate_valid_transitions, 0, sizeof(runstate_valid_transitions));
2239dbab31dSNicholas Piggin 
2249dbab31dSNicholas Piggin     transitions_set_valid(&runstate_transitions_def[0]);
225ba87e434SPaolo Bonzini 
226ba87e434SPaolo Bonzini     qemu_mutex_init(&vmstop_lock);
227ba87e434SPaolo Bonzini }
228ba87e434SPaolo Bonzini 
229ba87e434SPaolo Bonzini /* This function will abort() on invalid state transitions */
runstate_set(RunState new_state)230ba87e434SPaolo Bonzini void runstate_set(RunState new_state)
231ba87e434SPaolo Bonzini {
232ba87e434SPaolo Bonzini     assert(new_state < RUN_STATE__MAX);
233ba87e434SPaolo Bonzini 
234ba87e434SPaolo Bonzini     trace_runstate_set(current_run_state, RunState_str(current_run_state),
235ba87e434SPaolo Bonzini                        new_state, RunState_str(new_state));
236ba87e434SPaolo Bonzini 
237ba87e434SPaolo Bonzini     if (current_run_state == new_state) {
238ba87e434SPaolo Bonzini         return;
239ba87e434SPaolo Bonzini     }
240ba87e434SPaolo Bonzini 
241ba87e434SPaolo Bonzini     if (!runstate_valid_transitions[current_run_state][new_state]) {
242ba87e434SPaolo Bonzini         error_report("invalid runstate transition: '%s' -> '%s'",
243ba87e434SPaolo Bonzini                      RunState_str(current_run_state),
244ba87e434SPaolo Bonzini                      RunState_str(new_state));
245ba87e434SPaolo Bonzini         abort();
246ba87e434SPaolo Bonzini     }
247ba87e434SPaolo Bonzini 
248ba87e434SPaolo Bonzini     current_run_state = new_state;
249ba87e434SPaolo Bonzini }
250ba87e434SPaolo Bonzini 
runstate_get(void)251242b74ebSVladimir Sementsov-Ogievskiy RunState runstate_get(void)
252242b74ebSVladimir Sementsov-Ogievskiy {
253242b74ebSVladimir Sementsov-Ogievskiy     return current_run_state;
254242b74ebSVladimir Sementsov-Ogievskiy }
255242b74ebSVladimir Sementsov-Ogievskiy 
runstate_is_running(void)2560a389509SPhilippe Mathieu-Daudé bool runstate_is_running(void)
257ba87e434SPaolo Bonzini {
258ba87e434SPaolo Bonzini     return runstate_check(RUN_STATE_RUNNING);
259ba87e434SPaolo Bonzini }
260ba87e434SPaolo Bonzini 
runstate_needs_reset(void)261ba87e434SPaolo Bonzini bool runstate_needs_reset(void)
262ba87e434SPaolo Bonzini {
263ba87e434SPaolo Bonzini     return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
264ba87e434SPaolo Bonzini         runstate_check(RUN_STATE_SHUTDOWN);
265ba87e434SPaolo Bonzini }
266ba87e434SPaolo Bonzini 
qmp_query_status(Error ** errp)267ba87e434SPaolo Bonzini StatusInfo *qmp_query_status(Error **errp)
268ba87e434SPaolo Bonzini {
269ba87e434SPaolo Bonzini     StatusInfo *info = g_malloc0(sizeof(*info));
270ba87e434SPaolo Bonzini 
271ba87e434SPaolo Bonzini     info->running = runstate_is_running();
272ba87e434SPaolo Bonzini     info->status = current_run_state;
273ba87e434SPaolo Bonzini 
274ba87e434SPaolo Bonzini     return info;
275ba87e434SPaolo Bonzini }
276ba87e434SPaolo Bonzini 
qemu_vmstop_requested(RunState * r)277ba87e434SPaolo Bonzini bool qemu_vmstop_requested(RunState *r)
278ba87e434SPaolo Bonzini {
279ba87e434SPaolo Bonzini     qemu_mutex_lock(&vmstop_lock);
280ba87e434SPaolo Bonzini     *r = vmstop_requested;
281ba87e434SPaolo Bonzini     vmstop_requested = RUN_STATE__MAX;
282ba87e434SPaolo Bonzini     qemu_mutex_unlock(&vmstop_lock);
283ba87e434SPaolo Bonzini     return *r < RUN_STATE__MAX;
284ba87e434SPaolo Bonzini }
285ba87e434SPaolo Bonzini 
qemu_system_vmstop_request_prepare(void)286ba87e434SPaolo Bonzini void qemu_system_vmstop_request_prepare(void)
287ba87e434SPaolo Bonzini {
288ba87e434SPaolo Bonzini     qemu_mutex_lock(&vmstop_lock);
289ba87e434SPaolo Bonzini }
290ba87e434SPaolo Bonzini 
qemu_system_vmstop_request(RunState state)291ba87e434SPaolo Bonzini void qemu_system_vmstop_request(RunState state)
292ba87e434SPaolo Bonzini {
293ba87e434SPaolo Bonzini     vmstop_requested = state;
294ba87e434SPaolo Bonzini     qemu_mutex_unlock(&vmstop_lock);
295ba87e434SPaolo Bonzini     qemu_notify_event();
296ba87e434SPaolo Bonzini }
297ba87e434SPaolo Bonzini struct VMChangeStateEntry {
298ba87e434SPaolo Bonzini     VMChangeStateHandler *cb;
2999d3103c8SAvihai Horon     VMChangeStateHandler *prepare_cb;
300ba87e434SPaolo Bonzini     void *opaque;
301ba87e434SPaolo Bonzini     QTAILQ_ENTRY(VMChangeStateEntry) entries;
302ba87e434SPaolo Bonzini     int priority;
303ba87e434SPaolo Bonzini };
304ba87e434SPaolo Bonzini 
305ba87e434SPaolo Bonzini static QTAILQ_HEAD(, VMChangeStateEntry) vm_change_state_head =
306ba87e434SPaolo Bonzini     QTAILQ_HEAD_INITIALIZER(vm_change_state_head);
307ba87e434SPaolo Bonzini 
308ba87e434SPaolo Bonzini /**
309ba87e434SPaolo Bonzini  * qemu_add_vm_change_state_handler_prio:
310ba87e434SPaolo Bonzini  * @cb: the callback to invoke
311ba87e434SPaolo Bonzini  * @opaque: user data passed to the callback
312ba87e434SPaolo Bonzini  * @priority: low priorities execute first when the vm runs and the reverse is
313ba87e434SPaolo Bonzini  *            true when the vm stops
314ba87e434SPaolo Bonzini  *
315ba87e434SPaolo Bonzini  * Register a callback function that is invoked when the vm starts or stops
316ba87e434SPaolo Bonzini  * running.
317ba87e434SPaolo Bonzini  *
318ba87e434SPaolo Bonzini  * Returns: an entry to be freed using qemu_del_vm_change_state_handler()
319ba87e434SPaolo Bonzini  */
qemu_add_vm_change_state_handler_prio(VMChangeStateHandler * cb,void * opaque,int priority)320ba87e434SPaolo Bonzini VMChangeStateEntry *qemu_add_vm_change_state_handler_prio(
321ba87e434SPaolo Bonzini         VMChangeStateHandler *cb, void *opaque, int priority)
322ba87e434SPaolo Bonzini {
3239d3103c8SAvihai Horon     return qemu_add_vm_change_state_handler_prio_full(cb, NULL, opaque,
3249d3103c8SAvihai Horon                                                       priority);
3259d3103c8SAvihai Horon }
3269d3103c8SAvihai Horon 
3279d3103c8SAvihai Horon /**
3289d3103c8SAvihai Horon  * qemu_add_vm_change_state_handler_prio_full:
3299d3103c8SAvihai Horon  * @cb: the main callback to invoke
3309d3103c8SAvihai Horon  * @prepare_cb: a callback to invoke before the main callback
3319d3103c8SAvihai Horon  * @opaque: user data passed to the callbacks
3329d3103c8SAvihai Horon  * @priority: low priorities execute first when the vm runs and the reverse is
3339d3103c8SAvihai Horon  *            true when the vm stops
3349d3103c8SAvihai Horon  *
3359d3103c8SAvihai Horon  * Register a main callback function and an optional prepare callback function
3369d3103c8SAvihai Horon  * that are invoked when the vm starts or stops running. The main callback and
3379d3103c8SAvihai Horon  * the prepare callback are called in two separate phases: First all prepare
3389d3103c8SAvihai Horon  * callbacks are called and only then all main callbacks are called. As its
3399d3103c8SAvihai Horon  * name suggests, the prepare callback can be used to do some preparatory work
3409d3103c8SAvihai Horon  * before invoking the main callback.
3419d3103c8SAvihai Horon  *
3429d3103c8SAvihai Horon  * Returns: an entry to be freed using qemu_del_vm_change_state_handler()
3439d3103c8SAvihai Horon  */
3449d3103c8SAvihai Horon VMChangeStateEntry *
qemu_add_vm_change_state_handler_prio_full(VMChangeStateHandler * cb,VMChangeStateHandler * prepare_cb,void * opaque,int priority)3459d3103c8SAvihai Horon qemu_add_vm_change_state_handler_prio_full(VMChangeStateHandler *cb,
3469d3103c8SAvihai Horon                                            VMChangeStateHandler *prepare_cb,
3479d3103c8SAvihai Horon                                            void *opaque, int priority)
3489d3103c8SAvihai Horon {
349ba87e434SPaolo Bonzini     VMChangeStateEntry *e;
350ba87e434SPaolo Bonzini     VMChangeStateEntry *other;
351ba87e434SPaolo Bonzini 
352ba87e434SPaolo Bonzini     e = g_malloc0(sizeof(*e));
353ba87e434SPaolo Bonzini     e->cb = cb;
3549d3103c8SAvihai Horon     e->prepare_cb = prepare_cb;
355ba87e434SPaolo Bonzini     e->opaque = opaque;
356ba87e434SPaolo Bonzini     e->priority = priority;
357ba87e434SPaolo Bonzini 
358ba87e434SPaolo Bonzini     /* Keep list sorted in ascending priority order */
359ba87e434SPaolo Bonzini     QTAILQ_FOREACH(other, &vm_change_state_head, entries) {
360ba87e434SPaolo Bonzini         if (priority < other->priority) {
361ba87e434SPaolo Bonzini             QTAILQ_INSERT_BEFORE(other, e, entries);
362ba87e434SPaolo Bonzini             return e;
363ba87e434SPaolo Bonzini         }
364ba87e434SPaolo Bonzini     }
365ba87e434SPaolo Bonzini 
366ba87e434SPaolo Bonzini     QTAILQ_INSERT_TAIL(&vm_change_state_head, e, entries);
367ba87e434SPaolo Bonzini     return e;
368ba87e434SPaolo Bonzini }
369ba87e434SPaolo Bonzini 
qemu_add_vm_change_state_handler(VMChangeStateHandler * cb,void * opaque)370ba87e434SPaolo Bonzini VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
371ba87e434SPaolo Bonzini                                                      void *opaque)
372ba87e434SPaolo Bonzini {
373ba87e434SPaolo Bonzini     return qemu_add_vm_change_state_handler_prio(cb, opaque, 0);
374ba87e434SPaolo Bonzini }
375ba87e434SPaolo Bonzini 
qemu_del_vm_change_state_handler(VMChangeStateEntry * e)376ba87e434SPaolo Bonzini void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
377ba87e434SPaolo Bonzini {
378ba87e434SPaolo Bonzini     QTAILQ_REMOVE(&vm_change_state_head, e, entries);
379ba87e434SPaolo Bonzini     g_free(e);
380ba87e434SPaolo Bonzini }
381ba87e434SPaolo Bonzini 
vm_state_notify(bool running,RunState state)382538f0497SPhilippe Mathieu-Daudé void vm_state_notify(bool running, RunState state)
383ba87e434SPaolo Bonzini {
384ba87e434SPaolo Bonzini     VMChangeStateEntry *e, *next;
385ba87e434SPaolo Bonzini 
386ba87e434SPaolo Bonzini     trace_vm_state_notify(running, state, RunState_str(state));
387ba87e434SPaolo Bonzini 
388ba87e434SPaolo Bonzini     if (running) {
389ba87e434SPaolo Bonzini         QTAILQ_FOREACH_SAFE(e, &vm_change_state_head, entries, next) {
3909d3103c8SAvihai Horon             if (e->prepare_cb) {
3919d3103c8SAvihai Horon                 e->prepare_cb(e->opaque, running, state);
3929d3103c8SAvihai Horon             }
3939d3103c8SAvihai Horon         }
3949d3103c8SAvihai Horon 
3959d3103c8SAvihai Horon         QTAILQ_FOREACH_SAFE(e, &vm_change_state_head, entries, next) {
396ba87e434SPaolo Bonzini             e->cb(e->opaque, running, state);
397ba87e434SPaolo Bonzini         }
398ba87e434SPaolo Bonzini     } else {
399ba87e434SPaolo Bonzini         QTAILQ_FOREACH_REVERSE_SAFE(e, &vm_change_state_head, entries, next) {
4009d3103c8SAvihai Horon             if (e->prepare_cb) {
4019d3103c8SAvihai Horon                 e->prepare_cb(e->opaque, running, state);
4029d3103c8SAvihai Horon             }
4039d3103c8SAvihai Horon         }
4049d3103c8SAvihai Horon 
4059d3103c8SAvihai Horon         QTAILQ_FOREACH_REVERSE_SAFE(e, &vm_change_state_head, entries, next) {
406ba87e434SPaolo Bonzini             e->cb(e->opaque, running, state);
407ba87e434SPaolo Bonzini         }
408ba87e434SPaolo Bonzini     }
409ba87e434SPaolo Bonzini }
410ba87e434SPaolo Bonzini 
411ba87e434SPaolo Bonzini static ShutdownCause reset_requested;
412ba87e434SPaolo Bonzini static ShutdownCause shutdown_requested;
4130386f39bSClément Chigot static int shutdown_exit_code = EXIT_SUCCESS;
414ba87e434SPaolo Bonzini static int shutdown_signal;
415ba87e434SPaolo Bonzini static pid_t shutdown_pid;
416ba87e434SPaolo Bonzini static int powerdown_requested;
417ba87e434SPaolo Bonzini static int debug_requested;
418ba87e434SPaolo Bonzini static int suspend_requested;
419ba87e434SPaolo Bonzini static WakeupReason wakeup_reason;
420ba87e434SPaolo Bonzini static NotifierList powerdown_notifiers =
421ba87e434SPaolo Bonzini     NOTIFIER_LIST_INITIALIZER(powerdown_notifiers);
422ba87e434SPaolo Bonzini static NotifierList suspend_notifiers =
423ba87e434SPaolo Bonzini     NOTIFIER_LIST_INITIALIZER(suspend_notifiers);
424ba87e434SPaolo Bonzini static NotifierList wakeup_notifiers =
425ba87e434SPaolo Bonzini     NOTIFIER_LIST_INITIALIZER(wakeup_notifiers);
426ba87e434SPaolo Bonzini static NotifierList shutdown_notifiers =
427ba87e434SPaolo Bonzini     NOTIFIER_LIST_INITIALIZER(shutdown_notifiers);
428ba87e434SPaolo Bonzini static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE);
429ba87e434SPaolo Bonzini 
qemu_shutdown_requested_get(void)430ba87e434SPaolo Bonzini ShutdownCause qemu_shutdown_requested_get(void)
431ba87e434SPaolo Bonzini {
432ba87e434SPaolo Bonzini     return shutdown_requested;
433ba87e434SPaolo Bonzini }
434ba87e434SPaolo Bonzini 
qemu_reset_requested_get(void)435ba87e434SPaolo Bonzini ShutdownCause qemu_reset_requested_get(void)
436ba87e434SPaolo Bonzini {
437ba87e434SPaolo Bonzini     return reset_requested;
438ba87e434SPaolo Bonzini }
439ba87e434SPaolo Bonzini 
qemu_shutdown_requested(void)440ba87e434SPaolo Bonzini static int qemu_shutdown_requested(void)
441ba87e434SPaolo Bonzini {
442ba87e434SPaolo Bonzini     return qatomic_xchg(&shutdown_requested, SHUTDOWN_CAUSE_NONE);
443ba87e434SPaolo Bonzini }
444ba87e434SPaolo Bonzini 
qemu_kill_report(void)445ba87e434SPaolo Bonzini static void qemu_kill_report(void)
446ba87e434SPaolo Bonzini {
447ba87e434SPaolo Bonzini     if (!qtest_driver() && shutdown_signal) {
448ba87e434SPaolo Bonzini         if (shutdown_pid == 0) {
449ba87e434SPaolo Bonzini             /* This happens for eg ^C at the terminal, so it's worth
450ba87e434SPaolo Bonzini              * avoiding printing an odd message in that case.
451ba87e434SPaolo Bonzini              */
452ba87e434SPaolo Bonzini             error_report("terminating on signal %d", shutdown_signal);
453ba87e434SPaolo Bonzini         } else {
454ba87e434SPaolo Bonzini             char *shutdown_cmd = qemu_get_pid_name(shutdown_pid);
455ba87e434SPaolo Bonzini 
456ba87e434SPaolo Bonzini             error_report("terminating on signal %d from pid " FMT_pid " (%s)",
457ba87e434SPaolo Bonzini                          shutdown_signal, shutdown_pid,
458ba87e434SPaolo Bonzini                          shutdown_cmd ? shutdown_cmd : "<unknown process>");
459ba87e434SPaolo Bonzini             g_free(shutdown_cmd);
460ba87e434SPaolo Bonzini         }
461ba87e434SPaolo Bonzini         shutdown_signal = 0;
462ba87e434SPaolo Bonzini     }
463ba87e434SPaolo Bonzini }
464ba87e434SPaolo Bonzini 
qemu_reset_requested(void)465ba87e434SPaolo Bonzini static ShutdownCause qemu_reset_requested(void)
466ba87e434SPaolo Bonzini {
467ba87e434SPaolo Bonzini     ShutdownCause r = reset_requested;
468ba87e434SPaolo Bonzini 
469ba87e434SPaolo Bonzini     if (r && replay_checkpoint(CHECKPOINT_RESET_REQUESTED)) {
470ba87e434SPaolo Bonzini         reset_requested = SHUTDOWN_CAUSE_NONE;
471ba87e434SPaolo Bonzini         return r;
472ba87e434SPaolo Bonzini     }
473ba87e434SPaolo Bonzini     return SHUTDOWN_CAUSE_NONE;
474ba87e434SPaolo Bonzini }
475ba87e434SPaolo Bonzini 
qemu_suspend_requested(void)476ba87e434SPaolo Bonzini static int qemu_suspend_requested(void)
477ba87e434SPaolo Bonzini {
478ba87e434SPaolo Bonzini     int r = suspend_requested;
479ba87e434SPaolo Bonzini     if (r && replay_checkpoint(CHECKPOINT_SUSPEND_REQUESTED)) {
480ba87e434SPaolo Bonzini         suspend_requested = 0;
481ba87e434SPaolo Bonzini         return r;
482ba87e434SPaolo Bonzini     }
483ba87e434SPaolo Bonzini     return false;
484ba87e434SPaolo Bonzini }
485ba87e434SPaolo Bonzini 
qemu_wakeup_requested(void)486ba87e434SPaolo Bonzini static WakeupReason qemu_wakeup_requested(void)
487ba87e434SPaolo Bonzini {
488ba87e434SPaolo Bonzini     return wakeup_reason;
489ba87e434SPaolo Bonzini }
490ba87e434SPaolo Bonzini 
qemu_powerdown_requested(void)491ba87e434SPaolo Bonzini static int qemu_powerdown_requested(void)
492ba87e434SPaolo Bonzini {
493ba87e434SPaolo Bonzini     int r = powerdown_requested;
494ba87e434SPaolo Bonzini     powerdown_requested = 0;
495ba87e434SPaolo Bonzini     return r;
496ba87e434SPaolo Bonzini }
497ba87e434SPaolo Bonzini 
qemu_debug_requested(void)498ba87e434SPaolo Bonzini static int qemu_debug_requested(void)
499ba87e434SPaolo Bonzini {
500ba87e434SPaolo Bonzini     int r = debug_requested;
501ba87e434SPaolo Bonzini     debug_requested = 0;
502ba87e434SPaolo Bonzini     return r;
503ba87e434SPaolo Bonzini }
504ba87e434SPaolo Bonzini 
505ba87e434SPaolo Bonzini /*
506ba87e434SPaolo Bonzini  * Reset the VM. Issue an event unless @reason is SHUTDOWN_CAUSE_NONE.
507ba87e434SPaolo Bonzini  */
qemu_system_reset(ShutdownCause reason)508ba87e434SPaolo Bonzini void qemu_system_reset(ShutdownCause reason)
509ba87e434SPaolo Bonzini {
510ba87e434SPaolo Bonzini     MachineClass *mc;
5111b063fe2SJuraj Marcin     ResetType type;
512ba87e434SPaolo Bonzini 
513ba87e434SPaolo Bonzini     mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
514ba87e434SPaolo Bonzini 
515ba87e434SPaolo Bonzini     cpu_synchronize_all_states();
516ba87e434SPaolo Bonzini 
5171b063fe2SJuraj Marcin     switch (reason) {
5181b063fe2SJuraj Marcin     case SHUTDOWN_CAUSE_SNAPSHOT_LOAD:
5191b063fe2SJuraj Marcin         type = RESET_TYPE_SNAPSHOT_LOAD;
5201b063fe2SJuraj Marcin         break;
5211b063fe2SJuraj Marcin     default:
5221b063fe2SJuraj Marcin         type = RESET_TYPE_COLD;
5231b063fe2SJuraj Marcin     }
524ba87e434SPaolo Bonzini     if (mc && mc->reset) {
5251b063fe2SJuraj Marcin         mc->reset(current_machine, type);
526ba87e434SPaolo Bonzini     } else {
5271b063fe2SJuraj Marcin         qemu_devices_reset(type);
528ba87e434SPaolo Bonzini     }
5297966d70fSJason A. Donenfeld     switch (reason) {
5307966d70fSJason A. Donenfeld     case SHUTDOWN_CAUSE_NONE:
5317966d70fSJason A. Donenfeld     case SHUTDOWN_CAUSE_SUBSYSTEM_RESET:
5327966d70fSJason A. Donenfeld     case SHUTDOWN_CAUSE_SNAPSHOT_LOAD:
5337966d70fSJason A. Donenfeld         break;
5347966d70fSJason A. Donenfeld     default:
535ba87e434SPaolo Bonzini         qapi_event_send_reset(shutdown_caused_by_guest(reason), reason);
536ba87e434SPaolo Bonzini     }
53708b2d15cSPaolo Bonzini 
53808b2d15cSPaolo Bonzini     /*
53908b2d15cSPaolo Bonzini      * Some boards use the machine reset callback to point CPUs to the firmware
54008b2d15cSPaolo Bonzini      * entry point.  Assume that this is not the case for boards that support
54108b2d15cSPaolo Bonzini      * non-resettable CPUs (currently used only for confidential guests), in
54208b2d15cSPaolo Bonzini      * which case cpu_synchronize_all_post_init() is enough because
54308b2d15cSPaolo Bonzini      * it does _more_  than cpu_synchronize_all_post_reset().
54408b2d15cSPaolo Bonzini      */
54508b2d15cSPaolo Bonzini     if (cpus_are_resettable()) {
546ba87e434SPaolo Bonzini         cpu_synchronize_all_post_reset();
54708b2d15cSPaolo Bonzini     } else {
54808b2d15cSPaolo Bonzini         assert(runstate_check(RUN_STATE_PRELAUNCH));
54908b2d15cSPaolo Bonzini     }
55008b2d15cSPaolo Bonzini 
551b9ae473dSSteve Sistare     vm_set_suspended(false);
552ba87e434SPaolo Bonzini }
553ba87e434SPaolo Bonzini 
554ba87e434SPaolo Bonzini /*
555ba87e434SPaolo Bonzini  * Wake the VM after suspend.
556ba87e434SPaolo Bonzini  */
qemu_system_wakeup(void)557ba87e434SPaolo Bonzini static void qemu_system_wakeup(void)
558ba87e434SPaolo Bonzini {
559ba87e434SPaolo Bonzini     MachineClass *mc;
560ba87e434SPaolo Bonzini 
561ba87e434SPaolo Bonzini     mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
562ba87e434SPaolo Bonzini 
563ba87e434SPaolo Bonzini     if (mc && mc->wakeup) {
564ba87e434SPaolo Bonzini         mc->wakeup(current_machine);
565ba87e434SPaolo Bonzini     }
566ba87e434SPaolo Bonzini }
567ba87e434SPaolo Bonzini 
qemu_system_guest_panicked(GuestPanicInformation * info)568ba87e434SPaolo Bonzini void qemu_system_guest_panicked(GuestPanicInformation *info)
569ba87e434SPaolo Bonzini {
570ba87e434SPaolo Bonzini     qemu_log_mask(LOG_GUEST_ERROR, "Guest crashed");
571ba87e434SPaolo Bonzini 
572ba87e434SPaolo Bonzini     if (current_cpu) {
573ba87e434SPaolo Bonzini         current_cpu->crash_occurred = true;
574ba87e434SPaolo Bonzini     }
575c753e8e7SAlejandro Jimenez     /*
576c753e8e7SAlejandro Jimenez      * TODO:  Currently the available panic actions are: none, pause, and
577c27025e0SPaolo Bonzini      * shutdown, but in principle debug and reset could be supported as well.
578c753e8e7SAlejandro Jimenez      * Investigate any potential use cases for the unimplemented actions.
579c753e8e7SAlejandro Jimenez      */
580c27025e0SPaolo Bonzini     if (panic_action == PANIC_ACTION_PAUSE
581c27025e0SPaolo Bonzini         || (panic_action == PANIC_ACTION_SHUTDOWN && shutdown_action == SHUTDOWN_ACTION_PAUSE)) {
5820ccc2c92SMarkus Armbruster         qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, info);
583ba87e434SPaolo Bonzini         vm_stop(RUN_STATE_GUEST_PANICKED);
5840882caf4SIlya Leoshkevich     } else if (panic_action == PANIC_ACTION_SHUTDOWN ||
5850882caf4SIlya Leoshkevich                panic_action == PANIC_ACTION_EXIT_FAILURE) {
5860ccc2c92SMarkus Armbruster         qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF, info);
587c753e8e7SAlejandro Jimenez         vm_stop(RUN_STATE_GUEST_PANICKED);
588ba87e434SPaolo Bonzini         qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
589c753e8e7SAlejandro Jimenez     } else {
5900ccc2c92SMarkus Armbruster         qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_RUN, info);
591ba87e434SPaolo Bonzini     }
592ba87e434SPaolo Bonzini 
593ba87e434SPaolo Bonzini     if (info) {
594ba87e434SPaolo Bonzini         if (info->type == GUEST_PANIC_INFORMATION_TYPE_HYPER_V) {
595ba87e434SPaolo Bonzini             qemu_log_mask(LOG_GUEST_ERROR, "\nHV crash parameters: (%#"PRIx64
596ba87e434SPaolo Bonzini                           " %#"PRIx64" %#"PRIx64" %#"PRIx64" %#"PRIx64")\n",
597ba87e434SPaolo Bonzini                           info->u.hyper_v.arg1,
598ba87e434SPaolo Bonzini                           info->u.hyper_v.arg2,
599ba87e434SPaolo Bonzini                           info->u.hyper_v.arg3,
600ba87e434SPaolo Bonzini                           info->u.hyper_v.arg4,
601ba87e434SPaolo Bonzini                           info->u.hyper_v.arg5);
602ba87e434SPaolo Bonzini         } else if (info->type == GUEST_PANIC_INFORMATION_TYPE_S390) {
603ba87e434SPaolo Bonzini             qemu_log_mask(LOG_GUEST_ERROR, " on cpu %d: %s\n"
604ba87e434SPaolo Bonzini                           "PSW: 0x%016" PRIx64 " 0x%016" PRIx64"\n",
605ba87e434SPaolo Bonzini                           info->u.s390.core,
606ba87e434SPaolo Bonzini                           S390CrashReason_str(info->u.s390.reason),
607ba87e434SPaolo Bonzini                           info->u.s390.psw_mask,
608ba87e434SPaolo Bonzini                           info->u.s390.psw_addr);
609ba87e434SPaolo Bonzini         }
610ba87e434SPaolo Bonzini         qapi_free_GuestPanicInformation(info);
611ba87e434SPaolo Bonzini     }
612ba87e434SPaolo Bonzini }
613ba87e434SPaolo Bonzini 
qemu_system_guest_crashloaded(GuestPanicInformation * info)614ba87e434SPaolo Bonzini void qemu_system_guest_crashloaded(GuestPanicInformation *info)
615ba87e434SPaolo Bonzini {
616ba87e434SPaolo Bonzini     qemu_log_mask(LOG_GUEST_ERROR, "Guest crash loaded");
6170ccc2c92SMarkus Armbruster     qapi_event_send_guest_crashloaded(GUEST_PANIC_ACTION_RUN, info);
618ba87e434SPaolo Bonzini     qapi_free_GuestPanicInformation(info);
619ba87e434SPaolo Bonzini }
620ba87e434SPaolo Bonzini 
qemu_system_guest_pvshutdown(void)6216269086bSThomas Weißschuh void qemu_system_guest_pvshutdown(void)
6226269086bSThomas Weißschuh {
6238db1f7beSAlejandro Jimenez     qapi_event_send_guest_pvshutdown();
6246269086bSThomas Weißschuh     qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
6256269086bSThomas Weißschuh }
6266269086bSThomas Weißschuh 
qemu_system_reset_request(ShutdownCause reason)627ba87e434SPaolo Bonzini void qemu_system_reset_request(ShutdownCause reason)
628ba87e434SPaolo Bonzini {
629e6dba048SAlejandro Jimenez     if (reboot_action == REBOOT_ACTION_SHUTDOWN &&
630e6dba048SAlejandro Jimenez         reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
631ba87e434SPaolo Bonzini         shutdown_requested = reason;
63292a5199bSTom Lendacky     } else if (!cpus_are_resettable()) {
63392a5199bSTom Lendacky         error_report("cpus are not resettable, terminating");
63492a5199bSTom Lendacky         shutdown_requested = reason;
635ba87e434SPaolo Bonzini     } else {
636ba87e434SPaolo Bonzini         reset_requested = reason;
637ba87e434SPaolo Bonzini     }
638ba87e434SPaolo Bonzini     cpu_stop_current();
639ba87e434SPaolo Bonzini     qemu_notify_event();
640ba87e434SPaolo Bonzini }
641ba87e434SPaolo Bonzini 
qemu_system_suspend(void)642ba87e434SPaolo Bonzini static void qemu_system_suspend(void)
643ba87e434SPaolo Bonzini {
644ba87e434SPaolo Bonzini     pause_all_vcpus();
645ba87e434SPaolo Bonzini     notifier_list_notify(&suspend_notifiers, NULL);
646ba87e434SPaolo Bonzini     runstate_set(RUN_STATE_SUSPENDED);
647ba87e434SPaolo Bonzini     qapi_event_send_suspend();
648ba87e434SPaolo Bonzini }
649ba87e434SPaolo Bonzini 
qemu_system_suspend_request(void)650ba87e434SPaolo Bonzini void qemu_system_suspend_request(void)
651ba87e434SPaolo Bonzini {
652ba87e434SPaolo Bonzini     if (runstate_check(RUN_STATE_SUSPENDED)) {
653ba87e434SPaolo Bonzini         return;
654ba87e434SPaolo Bonzini     }
655ba87e434SPaolo Bonzini     suspend_requested = 1;
656ba87e434SPaolo Bonzini     cpu_stop_current();
657ba87e434SPaolo Bonzini     qemu_notify_event();
658ba87e434SPaolo Bonzini }
659ba87e434SPaolo Bonzini 
qemu_register_suspend_notifier(Notifier * notifier)660ba87e434SPaolo Bonzini void qemu_register_suspend_notifier(Notifier *notifier)
661ba87e434SPaolo Bonzini {
662ba87e434SPaolo Bonzini     notifier_list_add(&suspend_notifiers, notifier);
663ba87e434SPaolo Bonzini }
664ba87e434SPaolo Bonzini 
qemu_system_wakeup_request(WakeupReason reason,Error ** errp)665ba87e434SPaolo Bonzini void qemu_system_wakeup_request(WakeupReason reason, Error **errp)
666ba87e434SPaolo Bonzini {
667ba87e434SPaolo Bonzini     trace_system_wakeup_request(reason);
668ba87e434SPaolo Bonzini 
669ba87e434SPaolo Bonzini     if (!runstate_check(RUN_STATE_SUSPENDED)) {
670ba87e434SPaolo Bonzini         error_setg(errp,
671ba87e434SPaolo Bonzini                    "Unable to wake up: guest is not in suspended state");
672ba87e434SPaolo Bonzini         return;
673ba87e434SPaolo Bonzini     }
674ba87e434SPaolo Bonzini     if (!(wakeup_reason_mask & (1 << reason))) {
675ba87e434SPaolo Bonzini         return;
676ba87e434SPaolo Bonzini     }
677ba87e434SPaolo Bonzini     runstate_set(RUN_STATE_RUNNING);
678ba87e434SPaolo Bonzini     wakeup_reason = reason;
679ba87e434SPaolo Bonzini     qemu_notify_event();
680ba87e434SPaolo Bonzini }
681ba87e434SPaolo Bonzini 
qemu_system_wakeup_enable(WakeupReason reason,bool enabled)682ba87e434SPaolo Bonzini void qemu_system_wakeup_enable(WakeupReason reason, bool enabled)
683ba87e434SPaolo Bonzini {
684ba87e434SPaolo Bonzini     if (enabled) {
685ba87e434SPaolo Bonzini         wakeup_reason_mask |= (1 << reason);
686ba87e434SPaolo Bonzini     } else {
687ba87e434SPaolo Bonzini         wakeup_reason_mask &= ~(1 << reason);
688ba87e434SPaolo Bonzini     }
689ba87e434SPaolo Bonzini }
690ba87e434SPaolo Bonzini 
qemu_register_wakeup_notifier(Notifier * notifier)691ba87e434SPaolo Bonzini void qemu_register_wakeup_notifier(Notifier *notifier)
692ba87e434SPaolo Bonzini {
693ba87e434SPaolo Bonzini     notifier_list_add(&wakeup_notifiers, notifier);
694ba87e434SPaolo Bonzini }
695ba87e434SPaolo Bonzini 
696ba87e434SPaolo Bonzini static bool wakeup_suspend_enabled;
697ba87e434SPaolo Bonzini 
qemu_register_wakeup_support(void)698ba87e434SPaolo Bonzini void qemu_register_wakeup_support(void)
699ba87e434SPaolo Bonzini {
700ba87e434SPaolo Bonzini     wakeup_suspend_enabled = true;
701ba87e434SPaolo Bonzini }
702ba87e434SPaolo Bonzini 
qemu_wakeup_suspend_enabled(void)703ba87e434SPaolo Bonzini bool qemu_wakeup_suspend_enabled(void)
704ba87e434SPaolo Bonzini {
705ba87e434SPaolo Bonzini     return wakeup_suspend_enabled;
706ba87e434SPaolo Bonzini }
707ba87e434SPaolo Bonzini 
qemu_system_killed(int signal,pid_t pid)708ba87e434SPaolo Bonzini void qemu_system_killed(int signal, pid_t pid)
709ba87e434SPaolo Bonzini {
710ba87e434SPaolo Bonzini     shutdown_signal = signal;
711ba87e434SPaolo Bonzini     shutdown_pid = pid;
712e6dba048SAlejandro Jimenez     shutdown_action = SHUTDOWN_ACTION_POWEROFF;
713ba87e434SPaolo Bonzini 
714ba87e434SPaolo Bonzini     /* Cannot call qemu_system_shutdown_request directly because
715ba87e434SPaolo Bonzini      * we are in a signal handler.
716ba87e434SPaolo Bonzini      */
717ba87e434SPaolo Bonzini     shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL;
718ba87e434SPaolo Bonzini     qemu_notify_event();
719ba87e434SPaolo Bonzini }
720ba87e434SPaolo Bonzini 
qemu_system_shutdown_request_with_code(ShutdownCause reason,int exit_code)7210386f39bSClément Chigot void qemu_system_shutdown_request_with_code(ShutdownCause reason,
7220386f39bSClément Chigot                                             int exit_code)
7230386f39bSClément Chigot {
7240386f39bSClément Chigot     shutdown_exit_code = exit_code;
7250386f39bSClément Chigot     qemu_system_shutdown_request(reason);
7260386f39bSClément Chigot }
7270386f39bSClément Chigot 
qemu_system_shutdown_request(ShutdownCause reason)728ba87e434SPaolo Bonzini void qemu_system_shutdown_request(ShutdownCause reason)
729ba87e434SPaolo Bonzini {
730ba87e434SPaolo Bonzini     trace_qemu_system_shutdown_request(reason);
731ba87e434SPaolo Bonzini     replay_shutdown_request(reason);
732ba87e434SPaolo Bonzini     shutdown_requested = reason;
733ba87e434SPaolo Bonzini     qemu_notify_event();
734ba87e434SPaolo Bonzini }
735ba87e434SPaolo Bonzini 
qemu_system_powerdown(void)736ba87e434SPaolo Bonzini static void qemu_system_powerdown(void)
737ba87e434SPaolo Bonzini {
738ba87e434SPaolo Bonzini     qapi_event_send_powerdown();
739ba87e434SPaolo Bonzini     notifier_list_notify(&powerdown_notifiers, NULL);
740ba87e434SPaolo Bonzini }
741ba87e434SPaolo Bonzini 
qemu_system_shutdown(ShutdownCause cause)742ba87e434SPaolo Bonzini static void qemu_system_shutdown(ShutdownCause cause)
743ba87e434SPaolo Bonzini {
744ba87e434SPaolo Bonzini     qapi_event_send_shutdown(shutdown_caused_by_guest(cause), cause);
745ba87e434SPaolo Bonzini     notifier_list_notify(&shutdown_notifiers, &cause);
746ba87e434SPaolo Bonzini }
747ba87e434SPaolo Bonzini 
qemu_system_powerdown_request(void)748ba87e434SPaolo Bonzini void qemu_system_powerdown_request(void)
749ba87e434SPaolo Bonzini {
750ba87e434SPaolo Bonzini     trace_qemu_system_powerdown_request();
751ba87e434SPaolo Bonzini     powerdown_requested = 1;
752ba87e434SPaolo Bonzini     qemu_notify_event();
753ba87e434SPaolo Bonzini }
754ba87e434SPaolo Bonzini 
qemu_register_powerdown_notifier(Notifier * notifier)755ba87e434SPaolo Bonzini void qemu_register_powerdown_notifier(Notifier *notifier)
756ba87e434SPaolo Bonzini {
757ba87e434SPaolo Bonzini     notifier_list_add(&powerdown_notifiers, notifier);
758ba87e434SPaolo Bonzini }
759ba87e434SPaolo Bonzini 
qemu_register_shutdown_notifier(Notifier * notifier)760ba87e434SPaolo Bonzini void qemu_register_shutdown_notifier(Notifier *notifier)
761ba87e434SPaolo Bonzini {
762ba87e434SPaolo Bonzini     notifier_list_add(&shutdown_notifiers, notifier);
763ba87e434SPaolo Bonzini }
764ba87e434SPaolo Bonzini 
qemu_system_debug_request(void)765ba87e434SPaolo Bonzini void qemu_system_debug_request(void)
766ba87e434SPaolo Bonzini {
767ba87e434SPaolo Bonzini     debug_requested = 1;
768ba87e434SPaolo Bonzini     qemu_notify_event();
769ba87e434SPaolo Bonzini }
770ba87e434SPaolo Bonzini 
main_loop_should_exit(int * status)7710882caf4SIlya Leoshkevich static bool main_loop_should_exit(int *status)
772ba87e434SPaolo Bonzini {
773ba87e434SPaolo Bonzini     RunState r;
774ba87e434SPaolo Bonzini     ShutdownCause request;
775ba87e434SPaolo Bonzini 
776ba87e434SPaolo Bonzini     if (qemu_debug_requested()) {
777ba87e434SPaolo Bonzini         vm_stop(RUN_STATE_DEBUG);
778ba87e434SPaolo Bonzini     }
779ba87e434SPaolo Bonzini     if (qemu_suspend_requested()) {
780ba87e434SPaolo Bonzini         qemu_system_suspend();
781ba87e434SPaolo Bonzini     }
782ba87e434SPaolo Bonzini     request = qemu_shutdown_requested();
783ba87e434SPaolo Bonzini     if (request) {
784ba87e434SPaolo Bonzini         qemu_kill_report();
785ba87e434SPaolo Bonzini         qemu_system_shutdown(request);
786e6dba048SAlejandro Jimenez         if (shutdown_action == SHUTDOWN_ACTION_PAUSE) {
787ba87e434SPaolo Bonzini             vm_stop(RUN_STATE_SHUTDOWN);
788ba87e434SPaolo Bonzini         } else {
7890386f39bSClément Chigot             if (shutdown_exit_code != EXIT_SUCCESS) {
7900386f39bSClément Chigot                 *status = shutdown_exit_code;
7910386f39bSClément Chigot             } else if (request == SHUTDOWN_CAUSE_GUEST_PANIC &&
7920882caf4SIlya Leoshkevich                 panic_action == PANIC_ACTION_EXIT_FAILURE) {
7930882caf4SIlya Leoshkevich                 *status = EXIT_FAILURE;
7940882caf4SIlya Leoshkevich             }
795ba87e434SPaolo Bonzini             return true;
796ba87e434SPaolo Bonzini         }
797ba87e434SPaolo Bonzini     }
798ba87e434SPaolo Bonzini     request = qemu_reset_requested();
799ba87e434SPaolo Bonzini     if (request) {
800ba87e434SPaolo Bonzini         pause_all_vcpus();
801ba87e434SPaolo Bonzini         qemu_system_reset(request);
802ba87e434SPaolo Bonzini         resume_all_vcpus();
803ba87e434SPaolo Bonzini         /*
804ba87e434SPaolo Bonzini          * runstate can change in pause_all_vcpus()
805ba87e434SPaolo Bonzini          * as iothread mutex is unlocked
806ba87e434SPaolo Bonzini          */
807ba87e434SPaolo Bonzini         if (!runstate_check(RUN_STATE_RUNNING) &&
808ba87e434SPaolo Bonzini                 !runstate_check(RUN_STATE_INMIGRATE) &&
809ba87e434SPaolo Bonzini                 !runstate_check(RUN_STATE_FINISH_MIGRATE)) {
810ba87e434SPaolo Bonzini             runstate_set(RUN_STATE_PRELAUNCH);
811ba87e434SPaolo Bonzini         }
812ba87e434SPaolo Bonzini     }
813ba87e434SPaolo Bonzini     if (qemu_wakeup_requested()) {
814ba87e434SPaolo Bonzini         pause_all_vcpus();
815ba87e434SPaolo Bonzini         qemu_system_wakeup();
816ba87e434SPaolo Bonzini         notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
817ba87e434SPaolo Bonzini         wakeup_reason = QEMU_WAKEUP_REASON_NONE;
818ba87e434SPaolo Bonzini         resume_all_vcpus();
819ba87e434SPaolo Bonzini         qapi_event_send_wakeup();
820ba87e434SPaolo Bonzini     }
821ba87e434SPaolo Bonzini     if (qemu_powerdown_requested()) {
822ba87e434SPaolo Bonzini         qemu_system_powerdown();
823ba87e434SPaolo Bonzini     }
824ba87e434SPaolo Bonzini     if (qemu_vmstop_requested(&r)) {
825ba87e434SPaolo Bonzini         vm_stop(r);
826ba87e434SPaolo Bonzini     }
827ba87e434SPaolo Bonzini     return false;
828ba87e434SPaolo Bonzini }
829ba87e434SPaolo Bonzini 
qemu_main_loop(void)8300882caf4SIlya Leoshkevich int qemu_main_loop(void)
831ba87e434SPaolo Bonzini {
8320882caf4SIlya Leoshkevich     int status = EXIT_SUCCESS;
8330882caf4SIlya Leoshkevich 
8340882caf4SIlya Leoshkevich     while (!main_loop_should_exit(&status)) {
835ba87e434SPaolo Bonzini         main_loop_wait(false);
836ba87e434SPaolo Bonzini     }
8370882caf4SIlya Leoshkevich 
8380882caf4SIlya Leoshkevich     return status;
839ba87e434SPaolo Bonzini }
840ba87e434SPaolo Bonzini 
qemu_add_exit_notifier(Notifier * notify)841ba87e434SPaolo Bonzini void qemu_add_exit_notifier(Notifier *notify)
842ba87e434SPaolo Bonzini {
843ba87e434SPaolo Bonzini     notifier_list_add(&exit_notifiers, notify);
844ba87e434SPaolo Bonzini }
845ba87e434SPaolo Bonzini 
qemu_remove_exit_notifier(Notifier * notify)846ba87e434SPaolo Bonzini void qemu_remove_exit_notifier(Notifier *notify)
847ba87e434SPaolo Bonzini {
848ba87e434SPaolo Bonzini     notifier_remove(notify);
849ba87e434SPaolo Bonzini }
850ba87e434SPaolo Bonzini 
qemu_run_exit_notifiers(void)851ba87e434SPaolo Bonzini static void qemu_run_exit_notifiers(void)
852ba87e434SPaolo Bonzini {
853*e7bc0204SPhil Dennis-Jordan     BQL_LOCK_GUARD();
854ba87e434SPaolo Bonzini     notifier_list_notify(&exit_notifiers, NULL);
855ba87e434SPaolo Bonzini }
856ba87e434SPaolo Bonzini 
qemu_init_subsystems(void)857ba87e434SPaolo Bonzini void qemu_init_subsystems(void)
858ba87e434SPaolo Bonzini {
8596e1da3d3SPeng Liang     Error *err = NULL;
860ba87e434SPaolo Bonzini 
861ba87e434SPaolo Bonzini     os_set_line_buffering();
862ba87e434SPaolo Bonzini 
863ba87e434SPaolo Bonzini     module_call_init(MODULE_INIT_TRACE);
864ba87e434SPaolo Bonzini 
865ba87e434SPaolo Bonzini     qemu_init_cpu_list();
866ba87e434SPaolo Bonzini     qemu_init_cpu_loop();
867195801d7SStefan Hajnoczi     bql_lock();
868ba87e434SPaolo Bonzini 
869ba87e434SPaolo Bonzini     atexit(qemu_run_exit_notifiers);
870ba87e434SPaolo Bonzini 
871ba87e434SPaolo Bonzini     module_call_init(MODULE_INIT_QOM);
872ba87e434SPaolo Bonzini     module_call_init(MODULE_INIT_MIGRATION);
873ba87e434SPaolo Bonzini 
874ba87e434SPaolo Bonzini     runstate_init();
875ba87e434SPaolo Bonzini     precopy_infrastructure_init();
876ba87e434SPaolo Bonzini     postcopy_infrastructure_init();
877ba87e434SPaolo Bonzini     monitor_init_globals();
878ba87e434SPaolo Bonzini 
879ba87e434SPaolo Bonzini     if (qcrypto_init(&err) < 0) {
880ba87e434SPaolo Bonzini         error_reportf_err(err, "cannot initialize crypto: ");
881ba87e434SPaolo Bonzini         exit(1);
882ba87e434SPaolo Bonzini     }
883ba87e434SPaolo Bonzini 
884ba87e434SPaolo Bonzini     os_setup_early_signal_handling();
885ba87e434SPaolo Bonzini 
886ba87e434SPaolo Bonzini     bdrv_init_with_whitelist();
887ba87e434SPaolo Bonzini     socket_init();
888ba87e434SPaolo Bonzini }
889ba87e434SPaolo Bonzini 
890ba87e434SPaolo Bonzini 
qemu_cleanup(int status)89166bbe3e9SClément Chigot void qemu_cleanup(int status)
892ba87e434SPaolo Bonzini {
89366bbe3e9SClément Chigot     gdb_exit(status);
894ba87e434SPaolo Bonzini 
895ba87e434SPaolo Bonzini     /*
896ba87e434SPaolo Bonzini      * cleaning up the migration object cancels any existing migration
897ba87e434SPaolo Bonzini      * try to do this early so that it also stops using devices.
898ba87e434SPaolo Bonzini      */
899ba87e434SPaolo Bonzini     migration_shutdown();
900ba87e434SPaolo Bonzini 
901ba87e434SPaolo Bonzini     /*
9021895b977SSergio Lopez      * Close the exports before draining the block layer. The export
9031895b977SSergio Lopez      * drivers may have coroutines yielding on it, so we need to clean
9041895b977SSergio Lopez      * them up before the drain, as otherwise they may be get stuck in
9051895b977SSergio Lopez      * blk_wait_while_drained().
9061895b977SSergio Lopez      */
9071895b977SSergio Lopez     blk_exp_close_all();
9081895b977SSergio Lopez 
909ba87e434SPaolo Bonzini 
910ba87e434SPaolo Bonzini     /* No more vcpu or device emulation activity beyond this point */
911ba87e434SPaolo Bonzini     vm_shutdown();
912ba87e434SPaolo Bonzini     replay_finish();
913ba87e434SPaolo Bonzini 
914ca2a5e63SFiona Ebner     /*
915ca2a5e63SFiona Ebner      * We must cancel all block jobs while the block layer is drained,
916ca2a5e63SFiona Ebner      * or cancelling will be affected by throttling and thus may block
917ca2a5e63SFiona Ebner      * for an extended period of time.
918ca2a5e63SFiona Ebner      * Begin the drained section after vm_shutdown() to avoid requests being
919ca2a5e63SFiona Ebner      * stuck in the BlockBackend's request queue.
920ca2a5e63SFiona Ebner      * We do not need to end this section, because we do not want any
921ca2a5e63SFiona Ebner      * requests happening from here on anyway.
922ca2a5e63SFiona Ebner      */
923ca2a5e63SFiona Ebner     bdrv_drain_all_begin();
924ba87e434SPaolo Bonzini     job_cancel_sync_all();
925ba87e434SPaolo Bonzini     bdrv_close_all();
926ba87e434SPaolo Bonzini 
927ba87e434SPaolo Bonzini     /* vhost-user must be cleaned up before chardevs.  */
928ba87e434SPaolo Bonzini     tpm_cleanup();
929ba87e434SPaolo Bonzini     net_cleanup();
930ba87e434SPaolo Bonzini     audio_cleanup();
931ba87e434SPaolo Bonzini     monitor_cleanup();
932ba87e434SPaolo Bonzini     qemu_chr_cleanup();
933ba87e434SPaolo Bonzini     user_creatable_cleanup();
934ba87e434SPaolo Bonzini     /* TODO: unref root container, check all devices are ok */
935ba87e434SPaolo Bonzini }
936