qemu/softmmu/runstate.c
<<
>>
Prefs
   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}
 827