cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

runstate.c (23482B)


      1/*
      2 * QEMU main system emulation loop
      3 *
      4 * Copyright (c) 2003-2020 QEMU contributors
      5 *
      6 * Permission is hereby granted, free of charge, to any person obtaining a copy
      7 * of this software and associated documentation files (the "Software"), to deal
      8 * in the Software without restriction, including without limitation the rights
      9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10 * copies of the Software, and to permit persons to whom the Software is
     11 * furnished to do so, subject to the following conditions:
     12 *
     13 * The above copyright notice and this permission notice shall be included in
     14 * all copies or substantial portions of the Software.
     15 *
     16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22 * THE SOFTWARE.
     23 */
     24
     25#include "qemu/osdep.h"
     26#include "audio/audio.h"
     27#include "block/block.h"
     28#include "block/export.h"
     29#include "chardev/char.h"
     30#include "crypto/cipher.h"
     31#include "crypto/init.h"
     32#include "exec/cpu-common.h"
     33#include "exec/exec-all.h"
     34#include "exec/gdbstub.h"
     35#include "hw/boards.h"
     36#include "migration/misc.h"
     37#include "migration/postcopy-ram.h"
     38#include "monitor/monitor.h"
     39#include "net/net.h"
     40#include "net/vhost_net.h"
     41#include "qapi/error.h"
     42#include "qapi/qapi-commands-run-state.h"
     43#include "qapi/qapi-events-run-state.h"
     44#include "qemu-common.h"
     45#include "qemu/error-report.h"
     46#include "qemu/job.h"
     47#include "qemu/module.h"
     48#include "qemu/plugin.h"
     49#include "qemu/sockets.h"
     50#include "qemu/thread.h"
     51#include "qom/object.h"
     52#include "qom/object_interfaces.h"
     53#include "sysemu/cpus.h"
     54#include "sysemu/qtest.h"
     55#include "sysemu/replay.h"
     56#include "sysemu/reset.h"
     57#include "sysemu/runstate.h"
     58#include "sysemu/runstate-action.h"
     59#include "sysemu/sysemu.h"
     60#include "sysemu/tpm.h"
     61#include "trace.h"
     62
     63static NotifierList exit_notifiers =
     64    NOTIFIER_LIST_INITIALIZER(exit_notifiers);
     65
     66static RunState current_run_state = RUN_STATE_PRELAUNCH;
     67
     68/* We use RUN_STATE__MAX but any invalid value will do */
     69static RunState vmstop_requested = RUN_STATE__MAX;
     70static QemuMutex vmstop_lock;
     71
     72typedef struct {
     73    RunState from;
     74    RunState to;
     75} RunStateTransition;
     76
     77static const RunStateTransition runstate_transitions_def[] = {
     78    { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
     79
     80    { RUN_STATE_DEBUG, RUN_STATE_RUNNING },
     81    { RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
     82    { RUN_STATE_DEBUG, RUN_STATE_PRELAUNCH },
     83
     84    { RUN_STATE_INMIGRATE, RUN_STATE_INTERNAL_ERROR },
     85    { RUN_STATE_INMIGRATE, RUN_STATE_IO_ERROR },
     86    { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED },
     87    { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING },
     88    { RUN_STATE_INMIGRATE, RUN_STATE_SHUTDOWN },
     89    { RUN_STATE_INMIGRATE, RUN_STATE_SUSPENDED },
     90    { RUN_STATE_INMIGRATE, RUN_STATE_WATCHDOG },
     91    { RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED },
     92    { RUN_STATE_INMIGRATE, RUN_STATE_FINISH_MIGRATE },
     93    { RUN_STATE_INMIGRATE, RUN_STATE_PRELAUNCH },
     94    { RUN_STATE_INMIGRATE, RUN_STATE_POSTMIGRATE },
     95    { RUN_STATE_INMIGRATE, RUN_STATE_COLO },
     96
     97    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
     98    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
     99    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PRELAUNCH },
    100
    101    { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },
    102    { RUN_STATE_IO_ERROR, RUN_STATE_FINISH_MIGRATE },
    103    { RUN_STATE_IO_ERROR, RUN_STATE_PRELAUNCH },
    104
    105    { RUN_STATE_PAUSED, RUN_STATE_RUNNING },
    106    { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
    107    { RUN_STATE_PAUSED, RUN_STATE_POSTMIGRATE },
    108    { RUN_STATE_PAUSED, RUN_STATE_PRELAUNCH },
    109    { RUN_STATE_PAUSED, RUN_STATE_COLO},
    110
    111    { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
    112    { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
    113    { RUN_STATE_POSTMIGRATE, RUN_STATE_PRELAUNCH },
    114
    115    { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING },
    116    { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE },
    117    { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
    118
    119    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING },
    120    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PAUSED },
    121    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
    122    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PRELAUNCH },
    123    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO},
    124
    125    { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING },
    126    { RUN_STATE_RESTORE_VM, RUN_STATE_PRELAUNCH },
    127
    128    { RUN_STATE_COLO, RUN_STATE_RUNNING },
    129    { RUN_STATE_COLO, RUN_STATE_SHUTDOWN},
    130
    131    { RUN_STATE_RUNNING, RUN_STATE_DEBUG },
    132    { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
    133    { RUN_STATE_RUNNING, RUN_STATE_IO_ERROR },
    134    { RUN_STATE_RUNNING, RUN_STATE_PAUSED },
    135    { RUN_STATE_RUNNING, RUN_STATE_FINISH_MIGRATE },
    136    { RUN_STATE_RUNNING, RUN_STATE_RESTORE_VM },
    137    { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM },
    138    { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
    139    { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
    140    { RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
    141    { RUN_STATE_RUNNING, RUN_STATE_COLO},
    142
    143    { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
    144
    145    { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
    146    { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
    147    { RUN_STATE_SHUTDOWN, RUN_STATE_PRELAUNCH },
    148    { RUN_STATE_SHUTDOWN, RUN_STATE_COLO },
    149
    150    { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
    151    { RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
    152    { RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
    153    { RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
    154    { RUN_STATE_SUSPENDED, RUN_STATE_PRELAUNCH },
    155    { RUN_STATE_SUSPENDED, RUN_STATE_COLO},
    156
    157    { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
    158    { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
    159    { RUN_STATE_WATCHDOG, RUN_STATE_PRELAUNCH },
    160    { RUN_STATE_WATCHDOG, RUN_STATE_COLO},
    161
    162    { RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING },
    163    { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
    164    { RUN_STATE_GUEST_PANICKED, RUN_STATE_PRELAUNCH },
    165
    166    { RUN_STATE__MAX, RUN_STATE__MAX },
    167};
    168
    169static bool runstate_valid_transitions[RUN_STATE__MAX][RUN_STATE__MAX];
    170
    171bool runstate_check(RunState state)
    172{
    173    return current_run_state == state;
    174}
    175
    176bool runstate_store(char *str, size_t size)
    177{
    178    const char *state = RunState_str(current_run_state);
    179    size_t len = strlen(state) + 1;
    180
    181    if (len > size) {
    182        return false;
    183    }
    184    memcpy(str, state, len);
    185    return true;
    186}
    187
    188static void runstate_init(void)
    189{
    190    const RunStateTransition *p;
    191
    192    memset(&runstate_valid_transitions, 0, sizeof(runstate_valid_transitions));
    193    for (p = &runstate_transitions_def[0]; p->from != RUN_STATE__MAX; p++) {
    194        runstate_valid_transitions[p->from][p->to] = true;
    195    }
    196
    197    qemu_mutex_init(&vmstop_lock);
    198}
    199
    200/* This function will abort() on invalid state transitions */
    201void runstate_set(RunState new_state)
    202{
    203    assert(new_state < RUN_STATE__MAX);
    204
    205    trace_runstate_set(current_run_state, RunState_str(current_run_state),
    206                       new_state, RunState_str(new_state));
    207
    208    if (current_run_state == new_state) {
    209        return;
    210    }
    211
    212    if (!runstate_valid_transitions[current_run_state][new_state]) {
    213        error_report("invalid runstate transition: '%s' -> '%s'",
    214                     RunState_str(current_run_state),
    215                     RunState_str(new_state));
    216        abort();
    217    }
    218
    219    current_run_state = new_state;
    220}
    221
    222bool runstate_is_running(void)
    223{
    224    return runstate_check(RUN_STATE_RUNNING);
    225}
    226
    227bool runstate_needs_reset(void)
    228{
    229    return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
    230        runstate_check(RUN_STATE_SHUTDOWN);
    231}
    232
    233StatusInfo *qmp_query_status(Error **errp)
    234{
    235    StatusInfo *info = g_malloc0(sizeof(*info));
    236
    237    info->running = runstate_is_running();
    238    info->singlestep = singlestep;
    239    info->status = current_run_state;
    240
    241    return info;
    242}
    243
    244bool qemu_vmstop_requested(RunState *r)
    245{
    246    qemu_mutex_lock(&vmstop_lock);
    247    *r = vmstop_requested;
    248    vmstop_requested = RUN_STATE__MAX;
    249    qemu_mutex_unlock(&vmstop_lock);
    250    return *r < RUN_STATE__MAX;
    251}
    252
    253void qemu_system_vmstop_request_prepare(void)
    254{
    255    qemu_mutex_lock(&vmstop_lock);
    256}
    257
    258void qemu_system_vmstop_request(RunState state)
    259{
    260    vmstop_requested = state;
    261    qemu_mutex_unlock(&vmstop_lock);
    262    qemu_notify_event();
    263}
    264struct VMChangeStateEntry {
    265    VMChangeStateHandler *cb;
    266    void *opaque;
    267    QTAILQ_ENTRY(VMChangeStateEntry) entries;
    268    int priority;
    269};
    270
    271static QTAILQ_HEAD(, VMChangeStateEntry) vm_change_state_head =
    272    QTAILQ_HEAD_INITIALIZER(vm_change_state_head);
    273
    274/**
    275 * qemu_add_vm_change_state_handler_prio:
    276 * @cb: the callback to invoke
    277 * @opaque: user data passed to the callback
    278 * @priority: low priorities execute first when the vm runs and the reverse is
    279 *            true when the vm stops
    280 *
    281 * Register a callback function that is invoked when the vm starts or stops
    282 * running.
    283 *
    284 * Returns: an entry to be freed using qemu_del_vm_change_state_handler()
    285 */
    286VMChangeStateEntry *qemu_add_vm_change_state_handler_prio(
    287        VMChangeStateHandler *cb, void *opaque, int priority)
    288{
    289    VMChangeStateEntry *e;
    290    VMChangeStateEntry *other;
    291
    292    e = g_malloc0(sizeof(*e));
    293    e->cb = cb;
    294    e->opaque = opaque;
    295    e->priority = priority;
    296
    297    /* Keep list sorted in ascending priority order */
    298    QTAILQ_FOREACH(other, &vm_change_state_head, entries) {
    299        if (priority < other->priority) {
    300            QTAILQ_INSERT_BEFORE(other, e, entries);
    301            return e;
    302        }
    303    }
    304
    305    QTAILQ_INSERT_TAIL(&vm_change_state_head, e, entries);
    306    return e;
    307}
    308
    309VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
    310                                                     void *opaque)
    311{
    312    return qemu_add_vm_change_state_handler_prio(cb, opaque, 0);
    313}
    314
    315void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
    316{
    317    QTAILQ_REMOVE(&vm_change_state_head, e, entries);
    318    g_free(e);
    319}
    320
    321void vm_state_notify(bool running, RunState state)
    322{
    323    VMChangeStateEntry *e, *next;
    324
    325    trace_vm_state_notify(running, state, RunState_str(state));
    326
    327    if (running) {
    328        QTAILQ_FOREACH_SAFE(e, &vm_change_state_head, entries, next) {
    329            e->cb(e->opaque, running, state);
    330        }
    331    } else {
    332        QTAILQ_FOREACH_REVERSE_SAFE(e, &vm_change_state_head, entries, next) {
    333            e->cb(e->opaque, running, state);
    334        }
    335    }
    336}
    337
    338static ShutdownCause reset_requested;
    339static ShutdownCause shutdown_requested;
    340static int shutdown_signal;
    341static pid_t shutdown_pid;
    342static int powerdown_requested;
    343static int debug_requested;
    344static int suspend_requested;
    345static WakeupReason wakeup_reason;
    346static NotifierList powerdown_notifiers =
    347    NOTIFIER_LIST_INITIALIZER(powerdown_notifiers);
    348static NotifierList suspend_notifiers =
    349    NOTIFIER_LIST_INITIALIZER(suspend_notifiers);
    350static NotifierList wakeup_notifiers =
    351    NOTIFIER_LIST_INITIALIZER(wakeup_notifiers);
    352static NotifierList shutdown_notifiers =
    353    NOTIFIER_LIST_INITIALIZER(shutdown_notifiers);
    354static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE);
    355
    356ShutdownCause qemu_shutdown_requested_get(void)
    357{
    358    return shutdown_requested;
    359}
    360
    361ShutdownCause qemu_reset_requested_get(void)
    362{
    363    return reset_requested;
    364}
    365
    366static int qemu_shutdown_requested(void)
    367{
    368    return qatomic_xchg(&shutdown_requested, SHUTDOWN_CAUSE_NONE);
    369}
    370
    371static void qemu_kill_report(void)
    372{
    373    if (!qtest_driver() && shutdown_signal) {
    374        if (shutdown_pid == 0) {
    375            /* This happens for eg ^C at the terminal, so it's worth
    376             * avoiding printing an odd message in that case.
    377             */
    378            error_report("terminating on signal %d", shutdown_signal);
    379        } else {
    380            char *shutdown_cmd = qemu_get_pid_name(shutdown_pid);
    381
    382            error_report("terminating on signal %d from pid " FMT_pid " (%s)",
    383                         shutdown_signal, shutdown_pid,
    384                         shutdown_cmd ? shutdown_cmd : "<unknown process>");
    385            g_free(shutdown_cmd);
    386        }
    387        shutdown_signal = 0;
    388    }
    389}
    390
    391static ShutdownCause qemu_reset_requested(void)
    392{
    393    ShutdownCause r = reset_requested;
    394
    395    if (r && replay_checkpoint(CHECKPOINT_RESET_REQUESTED)) {
    396        reset_requested = SHUTDOWN_CAUSE_NONE;
    397        return r;
    398    }
    399    return SHUTDOWN_CAUSE_NONE;
    400}
    401
    402static int qemu_suspend_requested(void)
    403{
    404    int r = suspend_requested;
    405    if (r && replay_checkpoint(CHECKPOINT_SUSPEND_REQUESTED)) {
    406        suspend_requested = 0;
    407        return r;
    408    }
    409    return false;
    410}
    411
    412static WakeupReason qemu_wakeup_requested(void)
    413{
    414    return wakeup_reason;
    415}
    416
    417static int qemu_powerdown_requested(void)
    418{
    419    int r = powerdown_requested;
    420    powerdown_requested = 0;
    421    return r;
    422}
    423
    424static int qemu_debug_requested(void)
    425{
    426    int r = debug_requested;
    427    debug_requested = 0;
    428    return r;
    429}
    430
    431/*
    432 * Reset the VM. Issue an event unless @reason is SHUTDOWN_CAUSE_NONE.
    433 */
    434void qemu_system_reset(ShutdownCause reason)
    435{
    436    MachineClass *mc;
    437
    438    mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
    439
    440    cpu_synchronize_all_states();
    441
    442    if (mc && mc->reset) {
    443        mc->reset(current_machine);
    444    } else {
    445        qemu_devices_reset();
    446    }
    447    if (reason && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
    448        qapi_event_send_reset(shutdown_caused_by_guest(reason), reason);
    449    }
    450    cpu_synchronize_all_post_reset();
    451}
    452
    453/*
    454 * Wake the VM after suspend.
    455 */
    456static void qemu_system_wakeup(void)
    457{
    458    MachineClass *mc;
    459
    460    mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
    461
    462    if (mc && mc->wakeup) {
    463        mc->wakeup(current_machine);
    464    }
    465}
    466
    467void qemu_system_guest_panicked(GuestPanicInformation *info)
    468{
    469    qemu_log_mask(LOG_GUEST_ERROR, "Guest crashed");
    470
    471    if (current_cpu) {
    472        current_cpu->crash_occurred = true;
    473    }
    474    /*
    475     * TODO:  Currently the available panic actions are: none, pause, and
    476     * shutdown, but in principle debug and reset could be supported as well.
    477     * Investigate any potential use cases for the unimplemented actions.
    478     */
    479    if (panic_action == PANIC_ACTION_PAUSE
    480        || (panic_action == PANIC_ACTION_SHUTDOWN && shutdown_action == SHUTDOWN_ACTION_PAUSE)) {
    481        qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE,
    482                                        !!info, info);
    483        vm_stop(RUN_STATE_GUEST_PANICKED);
    484    } else if (panic_action == PANIC_ACTION_SHUTDOWN) {
    485        qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
    486                                       !!info, info);
    487        vm_stop(RUN_STATE_GUEST_PANICKED);
    488        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
    489    } else {
    490        qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_RUN,
    491                                        !!info, info);
    492    }
    493
    494    if (info) {
    495        if (info->type == GUEST_PANIC_INFORMATION_TYPE_HYPER_V) {
    496            qemu_log_mask(LOG_GUEST_ERROR, "\nHV crash parameters: (%#"PRIx64
    497                          " %#"PRIx64" %#"PRIx64" %#"PRIx64" %#"PRIx64")\n",
    498                          info->u.hyper_v.arg1,
    499                          info->u.hyper_v.arg2,
    500                          info->u.hyper_v.arg3,
    501                          info->u.hyper_v.arg4,
    502                          info->u.hyper_v.arg5);
    503        } else if (info->type == GUEST_PANIC_INFORMATION_TYPE_S390) {
    504            qemu_log_mask(LOG_GUEST_ERROR, " on cpu %d: %s\n"
    505                          "PSW: 0x%016" PRIx64 " 0x%016" PRIx64"\n",
    506                          info->u.s390.core,
    507                          S390CrashReason_str(info->u.s390.reason),
    508                          info->u.s390.psw_mask,
    509                          info->u.s390.psw_addr);
    510        }
    511        qapi_free_GuestPanicInformation(info);
    512    }
    513}
    514
    515void qemu_system_guest_crashloaded(GuestPanicInformation *info)
    516{
    517    qemu_log_mask(LOG_GUEST_ERROR, "Guest crash loaded");
    518
    519    qapi_event_send_guest_crashloaded(GUEST_PANIC_ACTION_RUN,
    520                                   !!info, info);
    521
    522    if (info) {
    523        qapi_free_GuestPanicInformation(info);
    524    }
    525}
    526
    527void qemu_system_reset_request(ShutdownCause reason)
    528{
    529    if (reboot_action == REBOOT_ACTION_SHUTDOWN &&
    530        reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
    531        shutdown_requested = reason;
    532    } else if (!cpus_are_resettable()) {
    533        error_report("cpus are not resettable, terminating");
    534        shutdown_requested = reason;
    535    } else {
    536        reset_requested = reason;
    537    }
    538    cpu_stop_current();
    539    qemu_notify_event();
    540}
    541
    542static void qemu_system_suspend(void)
    543{
    544    pause_all_vcpus();
    545    notifier_list_notify(&suspend_notifiers, NULL);
    546    runstate_set(RUN_STATE_SUSPENDED);
    547    qapi_event_send_suspend();
    548}
    549
    550void qemu_system_suspend_request(void)
    551{
    552    if (runstate_check(RUN_STATE_SUSPENDED)) {
    553        return;
    554    }
    555    suspend_requested = 1;
    556    cpu_stop_current();
    557    qemu_notify_event();
    558}
    559
    560void qemu_register_suspend_notifier(Notifier *notifier)
    561{
    562    notifier_list_add(&suspend_notifiers, notifier);
    563}
    564
    565void qemu_system_wakeup_request(WakeupReason reason, Error **errp)
    566{
    567    trace_system_wakeup_request(reason);
    568
    569    if (!runstate_check(RUN_STATE_SUSPENDED)) {
    570        error_setg(errp,
    571                   "Unable to wake up: guest is not in suspended state");
    572        return;
    573    }
    574    if (!(wakeup_reason_mask & (1 << reason))) {
    575        return;
    576    }
    577    runstate_set(RUN_STATE_RUNNING);
    578    wakeup_reason = reason;
    579    qemu_notify_event();
    580}
    581
    582void qemu_system_wakeup_enable(WakeupReason reason, bool enabled)
    583{
    584    if (enabled) {
    585        wakeup_reason_mask |= (1 << reason);
    586    } else {
    587        wakeup_reason_mask &= ~(1 << reason);
    588    }
    589}
    590
    591void qemu_register_wakeup_notifier(Notifier *notifier)
    592{
    593    notifier_list_add(&wakeup_notifiers, notifier);
    594}
    595
    596static bool wakeup_suspend_enabled;
    597
    598void qemu_register_wakeup_support(void)
    599{
    600    wakeup_suspend_enabled = true;
    601}
    602
    603bool qemu_wakeup_suspend_enabled(void)
    604{
    605    return wakeup_suspend_enabled;
    606}
    607
    608void qemu_system_killed(int signal, pid_t pid)
    609{
    610    shutdown_signal = signal;
    611    shutdown_pid = pid;
    612    shutdown_action = SHUTDOWN_ACTION_POWEROFF;
    613
    614    /* Cannot call qemu_system_shutdown_request directly because
    615     * we are in a signal handler.
    616     */
    617    shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL;
    618    qemu_notify_event();
    619}
    620
    621void qemu_system_shutdown_request(ShutdownCause reason)
    622{
    623    trace_qemu_system_shutdown_request(reason);
    624    replay_shutdown_request(reason);
    625    shutdown_requested = reason;
    626    qemu_notify_event();
    627}
    628
    629static void qemu_system_powerdown(void)
    630{
    631    qapi_event_send_powerdown();
    632    notifier_list_notify(&powerdown_notifiers, NULL);
    633}
    634
    635static void qemu_system_shutdown(ShutdownCause cause)
    636{
    637    qapi_event_send_shutdown(shutdown_caused_by_guest(cause), cause);
    638    notifier_list_notify(&shutdown_notifiers, &cause);
    639}
    640
    641void qemu_system_powerdown_request(void)
    642{
    643    trace_qemu_system_powerdown_request();
    644    powerdown_requested = 1;
    645    qemu_notify_event();
    646}
    647
    648void qemu_register_powerdown_notifier(Notifier *notifier)
    649{
    650    notifier_list_add(&powerdown_notifiers, notifier);
    651}
    652
    653void qemu_register_shutdown_notifier(Notifier *notifier)
    654{
    655    notifier_list_add(&shutdown_notifiers, notifier);
    656}
    657
    658void qemu_system_debug_request(void)
    659{
    660    debug_requested = 1;
    661    qemu_notify_event();
    662}
    663
    664static bool main_loop_should_exit(void)
    665{
    666    RunState r;
    667    ShutdownCause request;
    668
    669    if (qemu_debug_requested()) {
    670        vm_stop(RUN_STATE_DEBUG);
    671    }
    672    if (qemu_suspend_requested()) {
    673        qemu_system_suspend();
    674    }
    675    request = qemu_shutdown_requested();
    676    if (request) {
    677        qemu_kill_report();
    678        qemu_system_shutdown(request);
    679        if (shutdown_action == SHUTDOWN_ACTION_PAUSE) {
    680            vm_stop(RUN_STATE_SHUTDOWN);
    681        } else {
    682            return true;
    683        }
    684    }
    685    request = qemu_reset_requested();
    686    if (request) {
    687        pause_all_vcpus();
    688        qemu_system_reset(request);
    689        resume_all_vcpus();
    690        /*
    691         * runstate can change in pause_all_vcpus()
    692         * as iothread mutex is unlocked
    693         */
    694        if (!runstate_check(RUN_STATE_RUNNING) &&
    695                !runstate_check(RUN_STATE_INMIGRATE) &&
    696                !runstate_check(RUN_STATE_FINISH_MIGRATE)) {
    697            runstate_set(RUN_STATE_PRELAUNCH);
    698        }
    699    }
    700    if (qemu_wakeup_requested()) {
    701        pause_all_vcpus();
    702        qemu_system_wakeup();
    703        notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
    704        wakeup_reason = QEMU_WAKEUP_REASON_NONE;
    705        resume_all_vcpus();
    706        qapi_event_send_wakeup();
    707    }
    708    if (qemu_powerdown_requested()) {
    709        qemu_system_powerdown();
    710    }
    711    if (qemu_vmstop_requested(&r)) {
    712        vm_stop(r);
    713    }
    714    return false;
    715}
    716
    717void qemu_main_loop(void)
    718{
    719#ifdef CONFIG_PROFILER
    720    int64_t ti;
    721#endif
    722    while (!main_loop_should_exit()) {
    723#ifdef CONFIG_PROFILER
    724        ti = profile_getclock();
    725#endif
    726        main_loop_wait(false);
    727#ifdef CONFIG_PROFILER
    728        dev_time += profile_getclock() - ti;
    729#endif
    730    }
    731}
    732
    733void qemu_add_exit_notifier(Notifier *notify)
    734{
    735    notifier_list_add(&exit_notifiers, notify);
    736}
    737
    738void qemu_remove_exit_notifier(Notifier *notify)
    739{
    740    notifier_remove(notify);
    741}
    742
    743static void qemu_run_exit_notifiers(void)
    744{
    745    notifier_list_notify(&exit_notifiers, NULL);
    746}
    747
    748void qemu_init_subsystems(void)
    749{
    750    Error *err = NULL;
    751
    752    os_set_line_buffering();
    753
    754    module_call_init(MODULE_INIT_TRACE);
    755
    756    qemu_init_cpu_list();
    757    qemu_init_cpu_loop();
    758    qemu_mutex_lock_iothread();
    759
    760    atexit(qemu_run_exit_notifiers);
    761
    762    module_call_init(MODULE_INIT_QOM);
    763    module_call_init(MODULE_INIT_MIGRATION);
    764
    765    runstate_init();
    766    precopy_infrastructure_init();
    767    postcopy_infrastructure_init();
    768    monitor_init_globals();
    769
    770    if (qcrypto_init(&err) < 0) {
    771        error_reportf_err(err, "cannot initialize crypto: ");
    772        exit(1);
    773    }
    774
    775    os_setup_early_signal_handling();
    776
    777    bdrv_init_with_whitelist();
    778    socket_init();
    779}
    780
    781
    782void qemu_cleanup(void)
    783{
    784    gdb_exit(0);
    785
    786    /*
    787     * cleaning up the migration object cancels any existing migration
    788     * try to do this early so that it also stops using devices.
    789     */
    790    migration_shutdown();
    791
    792    /*
    793     * Close the exports before draining the block layer. The export
    794     * drivers may have coroutines yielding on it, so we need to clean
    795     * them up before the drain, as otherwise they may be get stuck in
    796     * blk_wait_while_drained().
    797     */
    798    blk_exp_close_all();
    799
    800    /*
    801     * We must cancel all block jobs while the block layer is drained,
    802     * or cancelling will be affected by throttling and thus may block
    803     * for an extended period of time.
    804     * vm_shutdown() will bdrv_drain_all(), so we may as well include
    805     * it in the drained section.
    806     * We do not need to end this section, because we do not want any
    807     * requests happening from here on anyway.
    808     */
    809    bdrv_drain_all_begin();
    810
    811    /* No more vcpu or device emulation activity beyond this point */
    812    vm_shutdown();
    813    replay_finish();
    814
    815    job_cancel_sync_all();
    816    bdrv_close_all();
    817
    818    /* vhost-user must be cleaned up before chardevs.  */
    819    tpm_cleanup();
    820    net_cleanup();
    821    audio_cleanup();
    822    monitor_cleanup();
    823    qemu_chr_cleanup();
    824    user_creatable_cleanup();
    825    /* TODO: unref root container, check all devices are ok */
    826}