[PATCH 07/15] hw/ide: restore the power-on device state before loading
"Denis V. Lunev" <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu.block,gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
From: Denis V. Lunev <[email protected]> Loading a snapshot reuses the IDEState of the machine it is loaded into: load_snapshot() resets the machine and then feeds the stream into the existing devices. The reset does not help, as ide_reset() restores the logical CHS translation only when the guest asked for power-on defaults to be reverted with SET FEATURES 0xCC. A guest that replaced the translation with INITIALIZE DEVICE PARAMETERS therefore keeps it across the load of a snapshot taken before it did, while the restored guest expects the geometry of that moment. Every CHS access then lands on a sector other than the one asked for, with no error reported. s->reset_reverts survives a load the same way. Add a pre_load restoring the defaults, which docs/devel/migration/main.rst recommends for state a stream need not carry, and which the following subsections rely on. The RESET_TYPE_SNAPSHOT_LOAD marking that reset would be another way to recognise the case, but no IDE controller can see it while they all use device_class_set_legacy_reset(). Cc: John Snow <[email protected]> Cc: Peter Maydell <[email protected]> Fixes: 176e4961bb33 ("hw/ide/core.c: Implement ATA INITIALIZE_DEVICE_PARAMETERS command") Signed-off-by: Denis V. Lunev <[email protected]> --- hw/ide/core.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/hw/ide/core.c b/hw/ide/core.c index 9959437a63..3b67409eb4 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2863,6 +2863,18 @@ static int transfer_end_table_idx(EndTransferFunc *fn) return -1; } +static int ide_drive_pre_load(void *opaque) +{ + IDEState *s = opaque; + + /* The subsections below are sent only where the guest replaced these */ + s->heads = s->drive_heads; + s->sectors = s->drive_sectors; + s->reset_reverts = false; + + return 0; +} + static int ide_drive_post_load(void *opaque, int version_id) { IDEState *s = opaque; @@ -2986,6 +2998,7 @@ const VMStateDescription vmstate_ide_drive = { .name = "ide_drive", .version_id = 3, .minimum_version_id = 0, + .pre_load = ide_drive_pre_load, .post_load = ide_drive_post_load, .fields = (const VMStateField[]) { VMSTATE_INT32(mult_sectors, IDEState), -- 2.53.0