}
}
+/*
+ * Handle the situation where @kvmidx is on destination but not
+ * in the incoming stream. This never fails the migration.
+ */
+static void handle_cpreg_missing_in_incoming_stream(ARMCPU *cpu, uint64_t kvmidx)
+{
+ g_autofree gchar *name = print_register_name(kvmidx);
+
+ warn_report("%s: %s "
+ "expected by the destination but not in the incoming stream: "
+ "skip it", __func__, name);
+}
+
+/*
+ * Handle the situation where @kvmidx is in the incoming stream
+ * but not on destination. This currently fails the migration but
+ * we plan to accomodate some exceptions, hence the boolean returned value.
+ */
+static bool handle_cpreg_only_in_incoming_stream(ARMCPU *cpu, uint64_t kvmidx)
+{
+ g_autofree gchar *name = print_register_name(kvmidx);
+ bool fail = true;
+
+ error_report("%s: %s in the incoming stream but unknown on the "
+ "destination: fail migration", __func__, name);
+
+ return fail;
+}
+
static int cpu_post_load(void *opaque, int version_id)
{
ARMCPU *cpu = opaque;
for (i = 0, v = 0; i < cpu->cpreg_array_len
&& v < cpu->cpreg_vmstate_array_len;) {
if (cpu->cpreg_vmstate_indexes[v] > cpu->cpreg_indexes[i]) {
- g_autofree gchar *name = print_register_name(cpu->cpreg_indexes[i]);
-
- warn_report("%s: %s "
- "expected by the destination but not in the incoming stream: "
- "skip it", __func__, name);
- i++;
+ handle_cpreg_missing_in_incoming_stream(cpu, cpu->cpreg_indexes[i++]);
continue;
}
if (cpu->cpreg_vmstate_indexes[v] < cpu->cpreg_indexes[i]) {
- g_autofree gchar *name = print_register_name(cpu->cpreg_vmstate_indexes[v]);
-
- error_report("%s: %s in the incoming stream but unknown on the destination: "
- "fail migration", __func__, name);
- v++;
- fail = true;
+ fail = handle_cpreg_only_in_incoming_stream(cpu,
+ cpu->cpreg_vmstate_indexes[v++]);
continue;
}
/* matching register, copy the value over */
i++;
v++;
}
+
+ /*
+ * if we have reached the end of the incoming array but there are
+ * still regs in cpreg, continue parsing the regs which are missing
+ * in the input stream
+ */
+ for ( ; i < cpu->cpreg_array_len; i++) {
+ handle_cpreg_missing_in_incoming_stream(cpu, cpu->cpreg_indexes[i]);
+ }
+ /*
+ * if we have reached the end of the cpreg array but there are
+ * still regs in the input stream, continue parsing the vmstate array
+ */
+ for ( ; v < cpu->cpreg_vmstate_array_len; v++) {
+ fail = handle_cpreg_only_in_incoming_stream(cpu,
+ cpu->cpreg_vmstate_indexes[v]);
+ }
if (fail) {
return -1;
}