Commit 33db64cf28 for qemu.org

commit 33db64cf28829103e6b60905666082a01d011fc8
Author: Denis V. Lunev <den@openvz.org>
Date:   Tue Aug 4 18:34:44 2026 +0200

    hw/ide: restore the power-on device state before loading

    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 <jsnow@redhat.com>
    Cc: Peter Maydell <peter.maydell@linaro.org>
    Cc: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
    Fixes: 176e4961bb33 ("hw/ide/core.c: Implement ATA INITIALIZE_DEVICE_PARAMETERS command")
    Signed-off-by: Denis V. Lunev <den@openvz.org>

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 048655b2d0..28219f5ef8 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),