>From 36538b4dfde5ccaa663d3d7c738fdef595027cb6 Mon Sep 17 00:00:00 2001 From: Claudio Fontana Date: Tue, 21 Jul 2020 10:10:29 +0200 Subject: [PATCH 2/2] XXX reproducer for backing file migration test issue do not commit. During a snapshot save, this changeset throws away all fields from the stream with the exception of "s390-skeys", which is added as a field for all architectures (renaming the real s390-skeys to something else). This allows to compare the reproducibility of the snapshot issue with all architectures. Signed-off-by: Claudio Fontana --- hw/s390x/s390-skeys.c | 2 +- migration/savevm.c | 31 +++++++++++++++++++++++ softmmu/cpus.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c index db2f49cb27..41116bdcc1 100644 --- a/hw/s390x/s390-skeys.c +++ b/hw/s390x/s390-skeys.c @@ -389,7 +389,7 @@ static inline void s390_skeys_set_migration_enabled(Object *obj, bool value, ss->migration_enabled = value; if (ss->migration_enabled) { - register_savevm_live(TYPE_S390_SKEYS, 0, 1, + register_savevm_live("s390-oldkeys", 0, 1, &savevm_s390_storage_keys, ss); } else { unregister_savevm(VMSTATE_IF(ss), TYPE_S390_SKEYS, ss); diff --git a/migration/savevm.c b/migration/savevm.c index 45c9dd9d8a..b63af07ccd 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1163,6 +1163,11 @@ void qemu_savevm_state_setup(QEMUFile *f) trace_savevm_state_setup(); QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { + + if (strcmp(se->idstr, "s390-skeys") != 0) { + /* only save keys */ + continue; + } if (!se->ops || !se->ops->save_setup) { continue; } @@ -1194,6 +1199,11 @@ int qemu_savevm_state_resume_prepare(MigrationState *s) trace_savevm_state_resume_prepare(); QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { + + if (strcmp(se->idstr, "s390-skeys") != 0) { + /* only save keys */ + continue; + } if (!se->ops || !se->ops->resume_prepare) { continue; } @@ -1224,6 +1234,11 @@ int qemu_savevm_state_iterate(QEMUFile *f, bool postcopy) trace_savevm_state_iterate(); QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { + + if (strcmp(se->idstr, "s390-skeys") != 0) { + /* only save keys */ + continue; + } if (!se->ops || !se->ops->save_live_iterate) { continue; } @@ -1325,6 +1340,12 @@ int qemu_savevm_state_complete_precopy_iterable(QEMUFile *f, bool in_postcopy) int ret; QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { + + if (strcmp(se->idstr, "s390-skeys") != 0) { + /* only save keys */ + continue; + } + if (!se->ops || (in_postcopy && se->ops->has_postcopy && se->ops->has_postcopy(se->opaque)) || @@ -1368,6 +1389,11 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, json_start_array(vmdesc, "devices"); QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { + if (strcmp(se->idstr, "s390-skeys") != 0) { + /* only save keys */ + continue; + } + if ((!se->ops || !se->ops->save_state) && !se->vmsd) { continue; } @@ -1583,6 +1609,11 @@ int qemu_save_device_state(QEMUFile *f) QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { int ret; + if (strcmp(se->idstr, "s390-skeys") != 0) { + /* only save keys */ + continue; + } + if (se->is_ram) { continue; } diff --git a/softmmu/cpus.c b/softmmu/cpus.c index a802e899ab..ae3ad0878c 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -63,6 +63,9 @@ #include "sysemu/cpu-throttle.h" +#include "migration/qemu-file-types.h" +#include "migration/register.h" + #ifdef CONFIG_LINUX #include @@ -732,11 +735,76 @@ static const VMStateDescription vmstate_timers = { } }; +static void s390_storage_keys_save(QEMUFile *f, void *opaque) +{ + uint64_t eos = 1, data = 2; + uint8_t *buf; + + buf = g_try_malloc(32768); + if (!buf) { + error_report("storage key save could not allocate memory"); + goto end_stream; + } + + qemu_put_be64(f, data); + qemu_put_be64(f, 32768); + + memset(buf, 0, 32768); + qemu_put_buffer(f, buf, 32768); + g_free(buf); + + end_stream: + qemu_put_be64(f, eos); +} + +static int s390_storage_keys_load(QEMUFile *f, void *opaque, int version_id) +{ + int ret = 0; + uint64_t data; + uint8_t *buf; + + while (ret == 0) { + data = qemu_get_be64(f); + + switch (data) { + case 2: { + const uint64_t total_count = qemu_get_be64(f); + buf = g_try_malloc(32768); + if (!buf) { + error_report("storage key load could not allocate memory"); + ret = -ENOMEM; + break; + } + qemu_get_buffer(f, buf, total_count); + g_free(buf); + break; + } + case 1: { + /* normal exit */ + return 0; + } + default: + error_report("Unexpected storage key data: %#lx", data); + ret = -EINVAL; + } + } + return ret; +} + +static SaveVMHandlers savevm_s390_storage_keys = { + .save_state = s390_storage_keys_save, + .load_state = s390_storage_keys_load, +}; + void cpu_ticks_init(void) { seqlock_init(&timers_state.vm_clock_seqlock); qemu_spin_init(&timers_state.vm_clock_lock); vmstate_register(NULL, 0, &vmstate_timers, &timers_state); + + register_savevm_live("s390-skeys", 0, 1, + &savevm_s390_storage_keys, NULL); + cpu_throttle_init(); } -- 2.16.4