Hello Marcelo, cc:qemu, Sorry for re-using this old thread, but I have a problem loading some saved state from qemu-kvm-1.1.2, which fails for piix4_pm. You following patch was committed as <http://git.qemu-project.org/?p=qemu.git;a=commitdiff;h=b0b873a07872f7ab7f66f259c73fb9dd42aa66a9>: Am 15.11.2012 um 01:11 schrieb Marcelo Tosatti: > Migrate 16 bytes for en/sts fields (which is the correct size), > increase version to 3, and document how to support incoming > migration from qemu-kvm 1.2. I my case qemu-kvm-1.1.2/hw/acpi_piix4.c:284 | VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), only saves 4 bytes, not 16 bytes. > Acked-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> > Signed-off-by: Marcelo Tosatti <mtosatti@xxxxxxxxxx> > --- > hw/acpi_piix4.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- > 1 files changed, 46 insertions(+), 4 deletions(-) > > diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c > index 15275cf..519269a 100644 > --- a/hw/acpi_piix4.c > +++ b/hw/acpi_piix4.c > @@ -235,10 +235,9 @@ static int vmstate_acpi_post_load(void *opaque, int version_id) > { \ > .name = (stringify(_field)), \ > .version_id = 0, \ > - .num = GPE_LEN, \ > .info = &vmstate_info_uint16, \ > .size = sizeof(uint16_t), \ > - .flags = VMS_ARRAY | VMS_POINTER, \ > + .flags = VMS_SINGLE | VMS_POINTER, \ > .offset = vmstate_offset_pointer(_state, _field, uint8_t), \ > } > > @@ -267,11 +266,54 @@ static const VMStateDescription vmstate_pci_status = { > } > }; On load qemu-2.8 uses this function > +static int acpi_load_old(QEMUFile *f, void *opaque, int version_id) > +{ > + PIIX4PMState *s = opaque; > + int ret, i; > + uint16_t temp; > + > + ret = pci_device_load(&s->dev, f); > + if (ret < 0) { > + return ret; > + } > + qemu_get_be16s(f, &s->ar.pm1.evt.sts); > + qemu_get_be16s(f, &s->ar.pm1.evt.en); > + qemu_get_be16s(f, &s->ar.pm1.cnt.cnt); > + > + ret = vmstate_load_state(f, &vmstate_apm, opaque, 1); > + if (ret) { > + return ret; > + } > + > + qemu_get_timer(f, s->ar.tmr.timer); > + qemu_get_sbe64s(f, &s->ar.tmr.overflow_time); > + > + qemu_get_be16s(f, (uint16_t *)s->ar.gpe.sts); > + for (i = 0; i < 3; i++) { > + qemu_get_be16s(f, &temp); > + } and the loop loads 6 extra bytes here > + > + qemu_get_be16s(f, (uint16_t *)s->ar.gpe.en); > + for (i = 0; i < 3; i++) { > + qemu_get_be16s(f, &temp); > + } and 6 here. So in total 12 bytes are read too much and qemu_loadvm_state() ends somewhere in the middle of the next device state section. (patch 0001 helped me to identify that offset) If I apply the attached 0002 patch, I can load the old VM state. > + > + ret = vmstate_load_state(f, &vmstate_pci_status, opaque, 1); > + return ret; > +} > + > +/* qemu-kvm 1.2 uses version 3 but advertised as 2 > + * To support incoming qemu-kvm 1.2 migration, change version_id > + * and minimum_version_id to 2 below (which breaks migration from > + * qemu 1.2). > + * > + */ > static const VMStateDescription vmstate_acpi = { > .name = "piix4_pm", > - .version_id = 2, > - .minimum_version_id = 1, > + .version_id = 3, > + .minimum_version_id = 3, > .minimum_version_id_old = 1, > + .load_state_old = acpi_load_old, > .post_load = vmstate_acpi_post_load, > .fields = (VMStateField []) { > VMSTATE_PCI_DEVICE(dev, PIIX4PMState), > Do you remember why 16 bytes were saved in your case? Thank you in advance. Philipp
From 4e43999b0f56975dbbd528e4956231b2ee64c071 Mon Sep 17 00:00:00 2001 Message-Id: <4e43999b0f56975dbbd528e4956231b2ee64c071.1490011194.git.hahn@xxxxxxxxxxxxx> In-Reply-To: <1313efdc0ac664169c5c271f832264efe6659743.1490011194.git.hahn@xxxxxxxxxxxxx> References: <1313efdc0ac664169c5c271f832264efe6659743.1490011194.git.hahn@xxxxxxxxxxxxx> From: Philipp Hahn <hahn@xxxxxxxxxxxxx> Date: Mon, 20 Mar 2017 12:36:53 +0100 Subject: [PATCH 2/2] 0007-Bug-38877-fix-qemu-kvm-1.1-piix4_pm-incompatibility Organization: Univention GmbH, Bremen, Germany To: qemu-devel@xxxxxxxxxx qemu-kvm-1.1 only saves 2*uint16, but qemu-2.8 tries to load 2*4*uint16. The code was added by b0b873a07872f7ab7f66f259c73fb9dd42aa66a9 and the commit message claims 16 bytes are the supposed size, but as UCS never used qemu-kvm-1.2, fix the case for qemu-kvm-1.1 Gbp: Topic UCS Signed-off-by: Philipp Hahn <hahn@xxxxxxxxxxxxx> --- hw/acpi/piix4.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 17d36bd..c756d18 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -232,14 +232,18 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id) qemu_get_sbe64s(f, &s->ar.tmr.overflow_time); qemu_get_be16s(f, (uint16_t *)s->ar.gpe.sts); +#if 0 // Bug #38877 for (i = 0; i < 3; i++) { qemu_get_be16s(f, &temp); } +#endif qemu_get_be16s(f, (uint16_t *)s->ar.gpe.en); +#if 0 // Bug #38877 for (i = 0; i < 3; i++) { qemu_get_be16s(f, &temp); } +#endif ret = vmstate_load_state(f, &vmstate_pci_status, &s->acpi_pci_hotplug.acpi_pcihp_pci_status[ACPI_PCIHP_BSEL_DEFAULT], 1); -- 2.1.4
From 1313efdc0ac664169c5c271f832264efe6659743 Mon Sep 17 00:00:00 2001 Message-Id: <1313efdc0ac664169c5c271f832264efe6659743.1490011194.git.hahn@xxxxxxxxxxxxx> From: Philipp Hahn <hahn@xxxxxxxxxxxxx> Date: Fri, 17 Mar 2017 12:51:01 +0100 Subject: [PATCH 1/2] 0006-Bug-38877-debug-loadvm-offset Organization: Univention GmbH, Bremen, Germany To: qemu-devel@xxxxxxxxxx debug: Print offset on section error: 30143@1489751176.344102:qemu_loadvm_state_section 48@0x364da2 Gbp: Topic debug Signed-off-by: Philipp Hahn <hahn@xxxxxxxxxxxxx> --- include/migration/qemu-file.h | 1 + migration/qemu-file.c | 5 +++++ migration/savevm.c | 2 +- migration/trace-events | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h index abedd46..a570836 100644 --- a/include/migration/qemu-file.h +++ b/include/migration/qemu-file.h @@ -126,6 +126,7 @@ int qemu_get_fd(QEMUFile *f); int qemu_fclose(QEMUFile *f); int64_t qemu_ftell(QEMUFile *f); int64_t qemu_ftell_fast(QEMUFile *f); +int64_t qemu_ftell_internal(QEMUFile *f); void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size); void qemu_put_byte(QEMUFile *f, int v); /* diff --git a/migration/qemu-file.c b/migration/qemu-file.c index e9fae31..862b8c7 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -543,6 +543,11 @@ int64_t qemu_ftell(QEMUFile *f) return f->pos; } +int64_t qemu_ftell_internal(QEMUFile *f) +{ + return f->pos - f->buf_size + f->buf_index; +} + int qemu_file_rate_limit(QEMUFile *f) { if (qemu_file_get_error(f)) { diff --git a/migration/savevm.c b/migration/savevm.c index 0363372..da2a98b 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1882,7 +1882,7 @@ static int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis) while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) { ret = 0; - trace_qemu_loadvm_state_section(section_type); + trace_qemu_loadvm_state_section(section_type, qemu_ftell_internal(f) - 1); switch (section_type) { case QEMU_VM_SECTION_START: case QEMU_VM_SECTION_FULL: diff --git a/migration/trace-events b/migration/trace-events index 94134f7..49f8458 100644 --- a/migration/trace-events +++ b/migration/trace-events @@ -1,7 +1,7 @@ # See docs/tracing.txt for syntax documentation. # migration/savevm.c -qemu_loadvm_state_section(unsigned int section_type) "%d" +qemu_loadvm_state_section(unsigned int section_type, uint64_t offset) "%d@0x%" PRIx64 qemu_loadvm_state_section_command(int ret) "%d" qemu_loadvm_state_section_partend(uint32_t section_id) "%u" qemu_loadvm_state_main(void) "" -- 2.1.4