This mechanism is used to handle more imperative partition-wide steps
that have to be taken as part of a migration routine.
Currently it's a skeleton that will just pause/resume the partition as
part of a migration. It will later be extended with more specific steps
like reference time and hypercall pages.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
accel/mshv/mshv-all.c | 75 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
index d1bf148bb8..365288b901 100644
--- a/accel/mshv/mshv-all.c
+++ b/accel/mshv/mshv-all.c
@@ -39,6 +39,8 @@
#include "system/mshv.h"
#include "system/mshv_int.h"
#include "system/reset.h"
+#include "migration/qemu-file-types.h"
+#include "migration/register.h"
#include "trace.h"
#include <err.h>
#include <sys/ioctl.h>
@@ -47,6 +49,9 @@ bool mshv_allowed;
MshvState *mshv_state;
+static int pause_vm(int vm_fd);
+static int resume_vm(int vm_fd);
+
static int init_mshv(int *mshv_fd)
{
int fd = open("/dev/mshv", O_RDWR | O_CLOEXEC);
@@ -80,6 +85,64 @@ static int set_time_freeze(int vm_fd, int freeze)
return 0;
}
+static void mshv_save_state(QEMUFile *f, void *opaque)
+{
+ return;
+}
+
+static int mshv_load_state(QEMUFile *f, void *opaque, int version_id)
+{
+ return 0;
+}
+
+static int mshv_save_prepare(void *opaque, Error **errp)
+{
+ MshvState *s = opaque;
+ int ret;
+
+ ret = pause_vm(s->vm);
+ if (ret < 0) {
+ error_setg(errp, "Failed to pause VM for migration");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void mshv_save_cleanup(void *opaque)
+{
+ MshvState *s = opaque;
+ int ret;
+
+ ret = resume_vm(s->vm);
+ if (ret < 0) {
+ error_report("Failed to resme VM after migration");
+ }
+}
+
+static int mshv_load_setup(QEMUFile *f, void *opaque, Error **errp)
+{
+ MshvState *s = opaque;
+ int ret;
+
+ ret = pause_vm(s->vm);
+ if (ret < 0) {
+ error_setg(errp, "Failed to pause VM for migration restore");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int mshv_load_cleanup(void *opaque)
+{
+ MshvState *s = opaque;
+
+ resume_vm(s->vm);
+
+ return 0;
+}
+
static int pause_vm(int vm_fd)
{
int ret;
@@ -454,6 +517,15 @@ static int mshv_init_vcpu(CPUState *cpu)
return 0;
}
+static SaveVMHandlers savevm_mshv = {
+ .save_prepare = mshv_save_prepare,
+ .save_state = mshv_save_state,
+ .save_cleanup = mshv_save_cleanup,
+ .load_setup = mshv_load_setup,
+ .load_state = mshv_load_state,
+ .load_cleanup = mshv_load_cleanup,
+};
+
static int mshv_init(AccelState *as, MachineState *ms)
{
MshvState *s;
@@ -509,6 +581,9 @@ static int mshv_init(AccelState *as, MachineState *ms)
0, "mshv-memory");
memory_listener_register(&mshv_io_listener, &address_space_io);
+ /* register custom handlers for migration events */
+ register_savevm_live("mshv", 0, 1, &savevm_mshv, s);
+
return 0;
}
--
2.34.1