summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Piggin2019-07-22 07:32:13 +0200
committerDavid Gibson2019-08-21 09:17:39 +0200
commit4b5e06c9465ece90b48cb0b978c0b898ea46e133 (patch)
treeb5d00067a99a3ee23e849b8a8ff808f4b964f689
parentppc/xive: Improve 'info pic' support (diff)
downloadqemu-4b5e06c9465ece90b48cb0b978c0b898ea46e133.tar.gz
qemu-4b5e06c9465ece90b48cb0b978c0b898ea46e133.tar.xz
qemu-4b5e06c9465ece90b48cb0b978c0b898ea46e133.zip
machine: Add wakeup method to MachineClass
Waking from suspend is not logically a machine reset on all machines, particularly in the paravirtualized case rather than hardware emulated. The ppc spapr machine for example just invokes hypervisor to suspend, and expects that call to return with the machine in the same state (modulo some possible migration and reconfiguration details). Implement a machine ->wakeup method and use that if it exists. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Message-Id: <20190722053215.20808-2-npiggin@gmail.com> Acked-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r--include/hw/boards.h1
-rw-r--r--vl.c18
2 files changed, 18 insertions, 1 deletions
diff --git a/include/hw/boards.h b/include/hw/boards.h
index aa35955f7f..60d69217b4 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -180,6 +180,7 @@ struct MachineClass {
void (*init)(MachineState *state);
void (*reset)(MachineState *state);
+ void (*wakeup)(MachineState *state);
void (*hot_add_cpu)(MachineState *state, const int64_t id, Error **errp);
int (*kvm_type)(MachineState *machine, const char *arg);
void (*smp_parse)(MachineState *ms, QemuOpts *opts);
diff --git a/vl.c b/vl.c
index edd5390110..09aa18cb35 100644
--- a/vl.c
+++ b/vl.c
@@ -1557,6 +1557,22 @@ void qemu_system_reset(ShutdownCause reason)
cpu_synchronize_all_post_reset();
}
+/*
+ * Wake the VM after suspend.
+ */
+static void qemu_system_wakeup(void)
+{
+ MachineClass *mc;
+
+ mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
+
+ if (mc && mc->wakeup) {
+ mc->wakeup(current_machine);
+ } else {
+ qemu_system_reset(SHUTDOWN_CAUSE_NONE);
+ }
+}
+
void qemu_system_guest_panicked(GuestPanicInformation *info)
{
qemu_log_mask(LOG_GUEST_ERROR, "Guest crashed");
@@ -1765,7 +1781,7 @@ static bool main_loop_should_exit(void)
}
if (qemu_wakeup_requested()) {
pause_all_vcpus();
- qemu_system_reset(SHUTDOWN_CAUSE_NONE);
+ qemu_system_wakeup();
notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
wakeup_reason = QEMU_WAKEUP_REASON_NONE;
resume_all_vcpus();