All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/30] move to new migration APIs
@ 2026-08-25 21:37 Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 01/30] tests/unit/test-vmstate: " Vladimir Sementsov-Ogievskiy
                   ` (30 more replies)
  0 siblings, 31 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov

Hi all!

That's a new version for old

[RFC 00/22] migration: convert vmstate_load/save_state

after the core patches converting migration code
are already merged into master.

Let's now convert the whole code base.

Vladimir Sementsov-Ogievskiy (30):
  tests/unit/test-vmstate: move to new migration APIs
  ui/vdagent: move to new migration APIs
  hw/virtio: extra state: move to new migration APIs
  hw/virtio: config save/load: move to new migration APIs
  hw/virtio: make virtio_save() and virtio_load() static
  hw/virtio: remaining: move to new migration APIs
  hw/s390x/virtio-ccw.c: move to new migration APIs
  hw/scsi/spapr_vscsi: move to new migration APIs
  hw/scsi/scsi-bus.c: use new migration APIs
  hw/vfio/pci: move to new migration APIs
  hw/pci/pci: move to new migration APIs
  hw/pci/msix.c: use new migration APIs
  hw/pci/shpc.c: use new migration APIs
  hw/display/virtio-gpu: move to new migration APIs
  hw/net/virtio-net.c: use new migration APIs
  hw/nvram/eeprom93xx.c: use new migration APIs
  hw/nvram/fw_cfg.c: use new migration APIs
  hw/usb/redirect.c: move to new migration APIs
  alpha/machine: move to new migration APIs
  avr/machine: move to new migration APIs
  or1k/machine: move to new migration APIs
  microblaze/machine: move to new migration APIs
  hppa/machine: move to new migration APIs
  sparc/machine: move to new migration APIs
  ppc/machine: move to new migration APIs
  mips/machine: move to new migration APIs
  arm/machine: move to new migration APIs
  migration/vmstate-types: convert vmstate_info_g_byte_array to new APIs
  migration: VMStateInfo: remove old .get / .set handlers
  migration: finally drop vmstate_save/load_state() functions

 hw/display/virtio-gpu.c        |  99 +++++++++++----------
 hw/net/virtio-net.c            | 133 ++++++++++++++--------------
 hw/nvram/eeprom93xx.c          |  17 ++--
 hw/nvram/fw_cfg.c              |  24 ++---
 hw/pci/msix.c                  |  17 ++--
 hw/pci/pci.c                   |  85 +++++++++---------
 hw/pci/shpc.c                  |  20 +++--
 hw/s390x/virtio-ccw.c          |  40 ++++-----
 hw/scsi/scsi-bus.c             |  17 ++--
 hw/scsi/spapr_vscsi.c          |   9 +-
 hw/usb/redirect.c              |  59 +++++++------
 hw/vfio/pci.c                  |  14 ++-
 hw/virtio/vhost-user-fs.c      |  68 +++++++-------
 hw/virtio/virtio-mmio.c        |  31 +++----
 hw/virtio/virtio-pci.c         |  45 +++++-----
 hw/virtio/virtio.c             | 157 +++++++++++++++++----------------
 include/hw/pci/pci.h           |   4 +-
 include/hw/virtio/virtio-bus.h |   8 +-
 include/hw/virtio/virtio.h     |   4 -
 include/migration/vmstate.h    |  17 ----
 migration/vmstate-types.c      |  17 ++--
 migration/vmstate.c            |  32 +------
 target/alpha/machine.c         |  17 ++--
 target/arm/machine.c           | 107 +++++++++++-----------
 target/avr/machine.c           |  50 ++++++-----
 target/hppa/machine.c          |  34 +++----
 target/microblaze/machine.c    |  17 ++--
 target/mips/system/machine.c   |  49 +++++-----
 target/or1k/machine.c          |  17 ++--
 target/ppc/machine.c           |  80 ++++++++---------
 target/sparc/machine.c         |  68 +++++++-------
 tests/unit/test-vmstate.c      | 118 +++++++------------------
 ui/vdagent.c                   |  38 ++++----
 33 files changed, 710 insertions(+), 802 deletions(-)

-- 
2.43.0



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 01/30] tests/unit/test-vmstate: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-29  5:55   ` Akihiko Odaki
  2026-09-03 17:12   ` Fabiano Rosas
  2026-08-25 21:37 ` [PATCH 02/30] ui/vdagent: " Vladimir Sementsov-Ogievskiy
                   ` (29 subsequent siblings)
  30 siblings, 2 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx
  Cc: farosas, qemu-devel, vsementsov, Juraj Marcin,
	Alexander Mikhalitsyn, Akihiko Odaki

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 tests/unit/test-vmstate.c | 118 ++++++++++----------------------------
 1 file changed, 30 insertions(+), 88 deletions(-)

diff --git a/tests/unit/test-vmstate.c b/tests/unit/test-vmstate.c
index df1fb4c7780..23f31730703 100644
--- a/tests/unit/test-vmstate.c
+++ b/tests/unit/test-vmstate.c
@@ -67,14 +67,9 @@ static QEMUFile *open_test_file(bool write)
 static void save_vmstate(const VMStateDescription *desc, void *obj)
 {
     QEMUFile *f = open_test_file(true);
-    Error *local_err = NULL;
 
     /* Save file with vmstate */
-    int ret = vmstate_save_state(f, desc, obj, NULL, &local_err);
-    if (ret) {
-        error_report_err(local_err);
-    }
-    g_assert(!ret);
+    vmstate_save_vmsd(f, desc, obj, NULL, &error_abort);
     qemu_put_byte(f, QEMU_VM_EOF);
     g_assert(!qemu_file_get_error(f));
     qemu_fclose(f);
@@ -112,7 +107,6 @@ static int load_vmstate_one(const VMStateDescription *desc, void *obj,
                             int version, const uint8_t *wire, size_t size)
 {
     QEMUFile *f;
-    int ret;
     Error *local_err = NULL;
 
     f = open_test_file(true);
@@ -120,15 +114,16 @@ static int load_vmstate_one(const VMStateDescription *desc, void *obj,
     qemu_fclose(f);
 
     f = open_test_file(false);
-    ret = vmstate_load_state(f, desc, obj, version, &local_err);
-    if (ret) {
+    if (!vmstate_load_vmsd(f, desc, obj, version, &local_err)) {
         error_report_err(local_err);
         g_assert(qemu_file_get_error(f));
-    } else{
-        g_assert(!qemu_file_get_error(f));
+        qemu_fclose(f);
+        return -EINVAL;
     }
+
+    g_assert(!qemu_file_get_error(f));
     qemu_fclose(f);
-    return ret;
+    return 0;
 }
 
 
@@ -362,8 +357,6 @@ static const VMStateDescription vmstate_versioned = {
 
 static void test_load_v1(void)
 {
-    Error *local_err = NULL;
-    int ret;
     uint8_t buf[] = {
         0, 0, 0, 10,             /* a */
         0, 0, 0, 30,             /* c */
@@ -374,10 +367,7 @@ static void test_load_v1(void)
 
     QEMUFile *loading = open_test_file(false);
     TestStruct obj = { .b = 200, .e = 500, .f = 600 };
-    ret = vmstate_load_state(loading, &vmstate_versioned, &obj, 1, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
+    vmstate_load_vmsd(loading, &vmstate_versioned, &obj, 1, &error_abort);
     g_assert(!qemu_file_get_error(loading));
     g_assert_cmpint(obj.a, ==, 10);
     g_assert_cmpint(obj.b, ==, 200);
@@ -390,8 +380,6 @@ static void test_load_v1(void)
 
 static void test_load_v2(void)
 {
-    Error *local_err = NULL;
-    int ret;
     uint8_t buf[] = {
         0, 0, 0, 10,             /* a */
         0, 0, 0, 20,             /* b */
@@ -405,10 +393,7 @@ static void test_load_v2(void)
 
     QEMUFile *loading = open_test_file(false);
     TestStruct obj;
-    ret = vmstate_load_state(loading, &vmstate_versioned, &obj, 2, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
+    vmstate_load_vmsd(loading, &vmstate_versioned, &obj, 2, &error_abort);
     g_assert_cmpint(obj.a, ==, 10);
     g_assert_cmpint(obj.b, ==, 20);
     g_assert_cmpint(obj.c, ==, 30);
@@ -442,16 +427,10 @@ static const VMStateDescription vmstate_skipping = {
 
 static void test_save_noskip(void)
 {
-    Error *local_err = NULL;
     QEMUFile *fsave = open_test_file(true);
     TestStruct obj = { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6,
                        .skip_c_e = false };
-    int ret = vmstate_save_state(fsave, &vmstate_skipping, &obj, NULL,
-                                 &local_err);
-    if (ret) {
-        error_report_err(local_err);
-    }
-    g_assert(!ret);
+    vmstate_save_vmsd(fsave, &vmstate_skipping, &obj, NULL, &error_abort);
     g_assert(!qemu_file_get_error(fsave));
 
     uint8_t expected[] = {
@@ -469,16 +448,10 @@ static void test_save_noskip(void)
 
 static void test_save_skip(void)
 {
-    Error *local_err = NULL;
     QEMUFile *fsave = open_test_file(true);
     TestStruct obj = { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6,
                        .skip_c_e = true };
-    int ret = vmstate_save_state(fsave, &vmstate_skipping, &obj, NULL,
-                                 &local_err);
-    if (ret) {
-        error_report_err(local_err);
-    }
-    g_assert(!ret);
+    vmstate_save_vmsd(fsave, &vmstate_skipping, &obj, NULL, &error_abort);
     g_assert(!qemu_file_get_error(fsave));
 
     uint8_t expected[] = {
@@ -494,8 +467,6 @@ static void test_save_skip(void)
 
 static void test_load_noskip(void)
 {
-    Error *local_err = NULL;
-    int ret;
     uint8_t buf[] = {
         0, 0, 0, 10,             /* a */
         0, 0, 0, 20,             /* b */
@@ -509,10 +480,7 @@ static void test_load_noskip(void)
 
     QEMUFile *loading = open_test_file(false);
     TestStruct obj = { .skip_c_e = false };
-    ret = vmstate_load_state(loading, &vmstate_skipping, &obj, 2, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
+    vmstate_load_vmsd(loading, &vmstate_skipping, &obj, 2, &error_abort);
     g_assert(!qemu_file_get_error(loading));
     g_assert_cmpint(obj.a, ==, 10);
     g_assert_cmpint(obj.b, ==, 20);
@@ -525,8 +493,6 @@ static void test_load_noskip(void)
 
 static void test_load_skip(void)
 {
-    Error *local_err = NULL;
-    int ret;
     uint8_t buf[] = {
         0, 0, 0, 10,             /* a */
         0, 0, 0, 20,             /* b */
@@ -538,10 +504,7 @@ static void test_load_skip(void)
 
     QEMUFile *loading = open_test_file(false);
     TestStruct obj = { .skip_c_e = true, .c = 300, .e = 500 };
-    ret = vmstate_load_state(loading, &vmstate_skipping, &obj, 2, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
+    vmstate_load_vmsd(loading, &vmstate_skipping, &obj, 2, &error_abort);
     g_assert(!qemu_file_get_error(loading));
     g_assert_cmpint(obj.a, ==, 10);
     g_assert_cmpint(obj.b, ==, 20);
@@ -863,8 +826,6 @@ static void test_save_q(void)
 
 static void test_load_q(void)
 {
-    int ret;
-    Error *local_err = NULL;
     TestQtailq obj_q = {
         .i16 = -512,
         .i32 = 70000,
@@ -894,10 +855,7 @@ static void test_load_q(void)
     TestQtailq tgt;
 
     QTAILQ_INIT(&tgt.q);
-    ret = vmstate_load_state(fload, &vmstate_q, &tgt, 1, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
+    vmstate_load_vmsd(fload, &vmstate_q, &tgt, 1, &error_abort);
     char eof = qemu_get_byte(fload);
     g_assert(!qemu_file_get_error(fload));
     g_assert_cmpint(tgt.i16, ==, obj_q.i16);
@@ -1015,29 +973,29 @@ static void destroy_domain(gpointer data)
     g_free(domain);
 }
 
-static int domain_preload(void *opaque)
+static bool domain_preload(void *opaque, Error **errp)
 {
     TestGTreeDomain *domain = opaque;
 
     domain->mappings = g_tree_new_full((GCompareDataFunc)interval_cmp,
                                        NULL, g_free, g_free);
-    return 0;
+    return true;
 }
 
-static int iommu_preload(void *opaque)
+static bool iommu_preload(void *opaque, Error **errp)
 {
     TestGTreeIOMMU *iommu = opaque;
 
     iommu->domains = g_tree_new_full((GCompareDataFunc)int_cmp,
                                      NULL, NULL, destroy_domain);
-    return 0;
+    return true;
 }
 
 static const VMStateDescription vmstate_domain = {
     .name = "domain",
     .version_id = 1,
     .minimum_version_id = 1,
-    .pre_load = domain_preload,
+    .pre_load_errp = domain_preload,
     .fields = (const VMStateField[]) {
         VMSTATE_INT32(id, TestGTreeDomain),
         VMSTATE_GTREE_V(mappings, TestGTreeDomain, 1,
@@ -1073,7 +1031,7 @@ static const VMStateDescription vmstate_iommu = {
     .name = "iommu",
     .version_id = 1,
     .minimum_version_id = 1,
-    .pre_load = iommu_preload,
+    .pre_load_errp = iommu_preload,
     .fields = (const VMStateField[]) {
         VMSTATE_INT32(id, TestGTreeIOMMU),
         VMSTATE_GTREE_DIRECT_KEY_V(domains, TestGTreeIOMMU, 1,
@@ -1239,8 +1197,6 @@ static void diff_iommu(TestGTreeIOMMU *iommu1, TestGTreeIOMMU *iommu2)
 
 static void test_gtree_load_domain(void)
 {
-    Error *local_err = NULL;
-    int ret;
     TestGTreeDomain *dest_domain = g_new0(TestGTreeDomain, 1);
     TestGTreeDomain *orig_domain = create_first_domain();
     QEMUFile *fload, *fsave;
@@ -1253,11 +1209,7 @@ static void test_gtree_load_domain(void)
 
     fload = open_test_file(false);
 
-    ret = vmstate_load_state(fload, &vmstate_domain, dest_domain, 1,
-                             &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
+    vmstate_load_vmsd(fload, &vmstate_domain, dest_domain, 1, &error_abort);
     eof = qemu_get_byte(fload);
     g_assert(!qemu_file_get_error(fload));
     g_assert_cmpint(orig_domain->id, ==, dest_domain->id);
@@ -1360,8 +1312,6 @@ static void test_gtree_save_iommu(void)
 
 static void test_gtree_load_iommu(void)
 {
-    Error *local_err = NULL;
-    int ret;
     TestGTreeIOMMU *dest_iommu = g_new0(TestGTreeIOMMU, 1);
     TestGTreeIOMMU *orig_iommu = create_iommu();
     QEMUFile *fsave, *fload;
@@ -1373,10 +1323,7 @@ static void test_gtree_load_iommu(void)
     qemu_fclose(fsave);
 
     fload = open_test_file(false);
-    ret = vmstate_load_state(fload, &vmstate_iommu, dest_iommu, 1, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
+    vmstate_load_vmsd(fload, &vmstate_iommu, dest_iommu, 1, &error_abort);
     eof = qemu_get_byte(fload);
     g_assert(!qemu_file_get_error(fload));
     g_assert_cmpint(orig_iommu->id, ==, dest_iommu->id);
@@ -1498,8 +1445,6 @@ static void test_save_qlist(void)
 
 static void test_load_qlist(void)
 {
-    Error *local_err = NULL;
-    int ret;
     QEMUFile *fsave, *fload;
     TestQListContainer *orig_container = alloc_container();
     TestQListContainer *dest_container = g_new0(TestQListContainer, 1);
@@ -1513,11 +1458,8 @@ static void test_load_qlist(void)
     qemu_fclose(fsave);
 
     fload = open_test_file(false);
-    ret = vmstate_load_state(fload, &vmstate_container, dest_container, 1,
-                             &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
+    vmstate_load_vmsd(fload, &vmstate_container, dest_container, 1,
+                      &error_abort);
     eof = qemu_get_byte(fload);
     g_assert(!qemu_file_get_error(fload));
     g_assert_cmpint(eof, ==, QEMU_VM_EOF);
@@ -1534,22 +1476,22 @@ typedef struct TmpTestStruct {
     int64_t diff;
 } TmpTestStruct;
 
-static int tmp_child_pre_save(void *opaque)
+static bool tmp_child_pre_save(void *opaque, Error **errp)
 {
     struct TmpTestStruct *tts = opaque;
 
     tts->diff = tts->parent->b - tts->parent->a;
 
-    return 0;
+    return true;
 }
 
-static int tmp_child_post_load(void *opaque, int version_id)
+static bool tmp_child_post_load(void *opaque, int version_id, Error **errp)
 {
     struct TmpTestStruct *tts = opaque;
 
     tts->parent->b = tts->parent->a + tts->diff;
 
-    return 0;
+    return true;
 }
 
 static const VMStateDescription vmstate_tmp_back_to_parent = {
@@ -1562,8 +1504,8 @@ static const VMStateDescription vmstate_tmp_back_to_parent = {
 
 static const VMStateDescription vmstate_tmp_child = {
     .name = "test/tmp_child",
-    .pre_save = tmp_child_pre_save,
-    .post_load = tmp_child_post_load,
+    .pre_save_errp = tmp_child_pre_save,
+    .post_load_errp = tmp_child_post_load,
     .fields = (const VMStateField[]) {
         VMSTATE_INT64(diff, TmpTestStruct),
         VMSTATE_STRUCT_POINTER(parent, TmpTestStruct,
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 02/30] ui/vdagent: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 01/30] tests/unit/test-vmstate: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 03/30] hw/virtio: extra state: " Vladimir Sementsov-Ogievskiy
                   ` (28 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Marc-André Lureau

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 ui/vdagent.c | 38 +++++++++++++++++---------------------
 1 file changed, 17 insertions(+), 21 deletions(-)

diff --git a/ui/vdagent.c b/ui/vdagent.c
index b9784d4d9b9..a3a1be30404 100644
--- a/ui/vdagent.c
+++ b/ui/vdagent.c
@@ -938,7 +938,7 @@ static void vdagent_chr_class_init(ObjectClass *oc, const void *data)
                                    set_migration_blocked);
 }
 
-static int post_load(void *opaque, int version_id)
+static bool post_load(void *opaque, int version_id, Error **errp)
 {
     VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(opaque);
 
@@ -950,7 +950,7 @@ static int post_load(void *opaque, int version_id)
         vdagent_clipboard_peer_register(vd);
     }
 
-    return 0;
+    return true;
 }
 
 static const VMStateDescription vmstate_chunk = {
@@ -979,15 +979,16 @@ static const VMStateDescription vmstate_cbinfo_array = {
     }
 };
 
-static int put_cbinfo(QEMUFile *f, void *pv, size_t size,
-                      const VMStateField *field, JSONWriter *vmdesc)
+static bool save_cbinfo(QEMUFile *f, void *pv, size_t size,
+                        const VMStateField *field, JSONWriter *vmdesc,
+                        Error **errp)
 {
     VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(pv);
     struct CBInfoArray cbinfo = {};
     int i;
 
     if (!have_clipboard(vd)) {
-        return 0;
+        return true;
     }
 
     for (i = 0; i < QEMU_CLIPBOARD_SELECTION__COUNT; i++) {
@@ -996,29 +997,24 @@ static int put_cbinfo(QEMUFile *f, void *pv, size_t size,
         }
     }
 
-    return vmstate_save_state(f, &vmstate_cbinfo_array, &cbinfo, vmdesc,
-                              &error_fatal);
+    return vmstate_save_vmsd(f, &vmstate_cbinfo_array, &cbinfo, vmdesc, errp);
 }
 
-static int get_cbinfo(QEMUFile *f, void *pv, size_t size,
-                      const VMStateField *field)
+static bool load_cbinfo(QEMUFile *f, void *pv, size_t size,
+                        const VMStateField *field, Error **errp)
 {
     VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(pv);
     struct CBInfoArray cbinfo = {};
-    int i, ret;
-    Error *local_err = NULL;
+    int i;
 
     if (!have_clipboard(vd)) {
-        return 0;
+        return true;
     }
 
     vdagent_clipboard_peer_register(vd);
 
-    ret = vmstate_load_state(f, &vmstate_cbinfo_array, &cbinfo, 0,
-                             &local_err);
-    if (ret) {
-        error_report_err(local_err);
-        return ret;
+    if (!vmstate_load_vmsd(f, &vmstate_cbinfo_array, &cbinfo, 0, errp)) {
+        return false;
     }
 
     for (i = 0; i < cbinfo.n; i++) {
@@ -1029,20 +1025,20 @@ static int get_cbinfo(QEMUFile *f, void *pv, size_t size,
         qemu_clipboard_update(info);
     }
 
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_cbinfos = {
     .name = "vdagent/cbinfos",
-    .get  = get_cbinfo,
-    .put  = put_cbinfo,
+    .load  = load_cbinfo,
+    .save  = save_cbinfo,
 };
 
 static const VMStateDescription vmstate_vdagent = {
     .name = "vdagent",
     .version_id = 0,
     .minimum_version_id = 0,
-    .post_load = post_load,
+    .post_load_errp = post_load,
     .fields = (const VMStateField[]) {
         VMSTATE_BOOL(connected, VDAgentChardev),
         VMSTATE_UINT32(caps, VDAgentChardev),
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 03/30] hw/virtio: extra state: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 01/30] tests/unit/test-vmstate: " Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 02/30] ui/vdagent: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 04/30] hw/virtio: config save/load: " Vladimir Sementsov-Ogievskiy
                   ` (27 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Michael S. Tsirkin

Stop ignoring the error on save path.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/virtio/virtio-mmio.c        | 21 ++++++---------------
 hw/virtio/virtio-pci.c         | 21 ++++++---------------
 hw/virtio/virtio.c             | 24 +++++++++++++-----------
 include/hw/virtio/virtio-bus.h |  4 ++--
 4 files changed, 27 insertions(+), 43 deletions(-)

diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 55ceaeef5fc..559363e4438 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -606,29 +606,20 @@ static const VMStateDescription vmstate_virtio_mmio = {
     }
 };
 
-static void virtio_mmio_save_extra_state(DeviceState *opaque, QEMUFile *f)
+static bool virtio_mmio_save_extra_state(DeviceState *opaque, QEMUFile *f,
+                                         Error **errp)
 {
     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
-    Error *local_err = NULL;
-    int ret;
 
-    ret = vmstate_save_state(f, &vmstate_virtio_mmio, proxy, NULL, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
+    return vmstate_save_vmsd(f, &vmstate_virtio_mmio, proxy, NULL, errp);
 }
 
-static int virtio_mmio_load_extra_state(DeviceState *opaque, QEMUFile *f)
+static bool virtio_mmio_load_extra_state(DeviceState *opaque, QEMUFile *f,
+                                         Error **errp)
 {
     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
-    Error *local_err = NULL;
-    int ret;
 
-    ret = vmstate_load_state(f, &vmstate_virtio_mmio, proxy, 1, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
-    return ret;
+    return vmstate_load_vmsd(f, &vmstate_virtio_mmio, proxy, 1, errp);
 }
 
 static bool virtio_mmio_has_extra_state(DeviceState *opaque)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 6f5db5fc42b..7a5d4f35e33 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -184,29 +184,20 @@ static bool virtio_pci_has_extra_state(DeviceState *d)
     return true;
 }
 
-static void virtio_pci_save_extra_state(DeviceState *d, QEMUFile *f)
+static bool virtio_pci_save_extra_state(DeviceState *d, QEMUFile *f,
+                                        Error **errp)
 {
     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
-    Error *local_err = NULL;
-    int ret;
 
-    ret = vmstate_save_state(f, &vmstate_virtio_pci, proxy, NULL, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
+    return vmstate_save_vmsd(f, &vmstate_virtio_pci, proxy, NULL, errp);
 }
 
-static int virtio_pci_load_extra_state(DeviceState *d, QEMUFile *f)
+static bool virtio_pci_load_extra_state(DeviceState *d, QEMUFile *f,
+                                        Error **errp)
 {
     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
-    Error *local_err = NULL;
-    int ret;
 
-    ret = vmstate_load_state(f, &vmstate_virtio_pci, proxy, 1, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
-    return ret;
+    return vmstate_load_vmsd(f, &vmstate_virtio_pci, proxy, 1, errp);
 }
 
 static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index daa5607338c..8230a383aff 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2914,35 +2914,37 @@ static const VMStateDescription vmstate_virtio_ringsize = {
     }
 };
 
-static int get_extra_state(QEMUFile *f, void *pv, size_t size,
-                           const VMStateField *field)
+static bool load_extra_state(QEMUFile *f, void *pv, size_t size,
+                             const VMStateField *field,
+                             Error **errp)
 {
     VirtIODevice *vdev = pv;
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
 
     if (!k->load_extra_state) {
-        return -1;
-    } else {
-        return k->load_extra_state(qbus->parent, f);
+        error_setg(errp, "extra state is unsupported");
+        return false;
     }
+
+    return k->load_extra_state(qbus->parent, f, errp);
 }
 
-static int put_extra_state(QEMUFile *f, void *pv, size_t size,
-                           const VMStateField *field, JSONWriter *vmdesc)
+static bool save_extra_state(QEMUFile *f, void *pv, size_t size,
+                             const VMStateField *field, JSONWriter *vmdesc,
+                             Error **errp)
 {
     VirtIODevice *vdev = pv;
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
 
-    k->save_extra_state(qbus->parent, f);
-    return 0;
+    return k->save_extra_state(qbus->parent, f, errp);
 }
 
 static const VMStateInfo vmstate_info_extra_state = {
     .name = "virtqueue_extra_state",
-    .get = get_extra_state,
-    .put = put_extra_state,
+    .load = load_extra_state,
+    .save = save_extra_state,
 };
 
 static const VMStateDescription vmstate_virtio_extra_state = {
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index f80fd714244..255ecb2fcb2 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -43,11 +43,11 @@ struct VirtioBusClass {
     void (*notify)(DeviceState *d, uint16_t vector);
     void (*save_config)(DeviceState *d, QEMUFile *f);
     void (*save_queue)(DeviceState *d, int n, QEMUFile *f);
-    void (*save_extra_state)(DeviceState *d, QEMUFile *f);
+    bool (*save_extra_state)(DeviceState *d, QEMUFile *f, Error **errp);
     int (*load_config)(DeviceState *d, QEMUFile *f);
     int (*load_queue)(DeviceState *d, int n, QEMUFile *f);
     int (*load_done)(DeviceState *d, QEMUFile *f);
-    int (*load_extra_state)(DeviceState *d, QEMUFile *f);
+    bool (*load_extra_state)(DeviceState *d, QEMUFile *f, Error **errp);
     bool (*has_extra_state)(DeviceState *d);
     bool (*query_guest_notifiers)(DeviceState *d);
     int (*set_guest_notifiers)(DeviceState *d, int nvqs, bool assign);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 04/30] hw/virtio: config save/load: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (2 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 03/30] hw/virtio: extra state: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-09-03 17:41   ` Fabiano Rosas
  2026-08-25 21:37 ` [PATCH 05/30] hw/virtio: make virtio_save() and virtio_load() static Vladimir Sementsov-Ogievskiy
                   ` (26 subsequent siblings)
  30 siblings, 1 reply; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx
  Cc: farosas, qemu-devel, vsementsov, Michael S. Tsirkin,
	Cornelia Huck, Halil Pasic, Eric Farman, Richard Henderson,
	Ilya Leoshkevich, David Hildenbrand, Matthew Rosato,
	Christian Borntraeger, open list:virtio-ccw

Stop ignoring the error on save path.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/pci/pci.c                   | 27 +++++++++++----------------
 hw/s390x/virtio-ccw.c          | 19 ++++---------------
 hw/virtio/virtio-mmio.c        | 10 +++++++---
 hw/virtio/virtio-pci.c         | 24 +++++++++++++++---------
 hw/virtio/virtio.c             | 11 +++++++----
 include/hw/pci/pci.h           |  4 ++--
 include/hw/virtio/virtio-bus.h |  4 ++--
 7 files changed, 48 insertions(+), 51 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index d3191609e28..76d006fa1d7 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -940,37 +940,32 @@ const VMStateDescription vmstate_pci_device = {
 };
 
 
-void pci_device_save(PCIDevice *s, QEMUFile *f)
+bool pci_device_save(PCIDevice *s, QEMUFile *f, Error **errp)
 {
-    Error *local_err = NULL;
-    int ret;
+    bool ok;
 
     /* Clear interrupt status bit: it is implicit
      * in irq_state which we are saving.
      * This makes us compatible with old devices
      * which never set or clear this bit. */
     s->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT;
-    ret = vmstate_save_state(f, &vmstate_pci_device, s, NULL, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
+
+    ok = vmstate_save_vmsd(f, &vmstate_pci_device, s, NULL, errp);
+
     /* Restore the interrupt status bit. */
     pci_update_irq_status(s);
+
+    return ok;
 }
 
-int pci_device_load(PCIDevice *s, QEMUFile *f)
+bool pci_device_load(PCIDevice *s, QEMUFile *f, Error **errp)
 {
-    Error *local_err = NULL;
-    int ret;
+    bool ok = vmstate_load_vmsd(f, &vmstate_pci_device, s, s->version_id, errp);
 
-    ret = vmstate_load_state(f, &vmstate_pci_device, s, s->version_id,
-                             &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
     /* Restore the interrupt status bit. */
     pci_update_irq_status(s);
-    return ret;
+
+    return ok;
 }
 
 static void pci_set_default_subsystem_id(PCIDevice *pci_dev)
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index d82874ed27e..848ed09e94b 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -1129,29 +1129,18 @@ static int virtio_ccw_load_queue(DeviceState *d, int n, QEMUFile *f)
     return 0;
 }
 
-static void virtio_ccw_save_config(DeviceState *d, QEMUFile *f)
+static bool virtio_ccw_save_config(DeviceState *d, QEMUFile *f, Error **errp)
 {
     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
-    Error *local_err = NULL;
-    int ret;
 
-    ret = vmstate_save_state(f, &vmstate_virtio_ccw_dev, dev, NULL, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
+    return vmstate_save_vmsd(f, &vmstate_virtio_ccw_dev, dev, NULL, errp);
 }
 
-static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f)
+static bool virtio_ccw_load_config(DeviceState *d, QEMUFile *f, Error **errp)
 {
     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
-    Error *local_err = NULL;
-    int ret;
 
-    ret = vmstate_load_state(f, &vmstate_virtio_ccw_dev, dev, 1, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
-    return ret;
+    return vmstate_load_vmsd(f, &vmstate_virtio_ccw_dev, dev, 1, errp);
 }
 
 static void virtio_ccw_pre_plugged(DeviceState *d, Error **errp)
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 559363e4438..ef34b76913e 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -547,23 +547,27 @@ static void virtio_mmio_update_irq(DeviceState *opaque, uint16_t vector)
     qemu_set_irq(proxy->irq, level);
 }
 
-static int virtio_mmio_load_config(DeviceState *opaque, QEMUFile *f)
+static bool virtio_mmio_load_config(DeviceState *opaque, QEMUFile *f,
+                                    Error **errp)
 {
     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
 
     proxy->host_features_sel = qemu_get_be32(f);
     proxy->guest_features_sel = qemu_get_be32(f);
     proxy->guest_page_shift = qemu_get_be32(f);
-    return 0;
+    return true;
 }
 
-static void virtio_mmio_save_config(DeviceState *opaque, QEMUFile *f)
+static bool virtio_mmio_save_config(DeviceState *opaque, QEMUFile *f,
+                                    Error **errp)
 {
     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
 
     qemu_put_be32(f, proxy->host_features_sel);
     qemu_put_be32(f, proxy->guest_features_sel);
     qemu_put_be32(f, proxy->guest_page_shift);
+
+    return true;
 }
 
 static const VMStateDescription vmstate_virtio_mmio_queue_state = {
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 7a5d4f35e33..07941319be2 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -84,15 +84,21 @@ static void virtio_pci_notify(DeviceState *d, uint16_t vector)
     }
 }
 
-static void virtio_pci_save_config(DeviceState *d, QEMUFile *f)
+static bool virtio_pci_save_config(DeviceState *d, QEMUFile *f, Error **errp)
 {
     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 
-    pci_device_save(&proxy->pci_dev, f);
+    if (!pci_device_save(&proxy->pci_dev, f, errp)) {
+        return false;
+    }
+
     msix_save(&proxy->pci_dev, f);
-    if (msix_present(&proxy->pci_dev))
+    if (msix_present(&proxy->pci_dev)) {
         qemu_put_be16(f, vdev->config_vector);
+    }
+
+    return true;
 }
 
 static const VMStateDescription vmstate_virtio_pci_modern_queue_state = {
@@ -209,24 +215,24 @@ static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f)
         qemu_put_be16(f, virtio_queue_vector(vdev, n));
 }
 
-static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
+static bool virtio_pci_load_config(DeviceState *d, QEMUFile *f, Error **errp)
 {
     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
     uint16_t vector;
 
-    int ret;
-    ret = pci_device_load(&proxy->pci_dev, f);
-    if (ret) {
-        return ret;
+    if (!pci_device_load(&proxy->pci_dev, f, errp)) {
+        return false;
     }
+
     msix_unuse_all_vectors(&proxy->pci_dev);
     msix_load(&proxy->pci_dev, f);
     if (msix_present(&proxy->pci_dev)) {
         qemu_get_be16s(f, &vector);
 
         if (vector != VIRTIO_NO_VECTOR && vector >= proxy->nvectors) {
-            return -EINVAL;
+            error_setg(errp, "load config: unexpected vector %" PRIu16, vector);
+            return false;
         }
     } else {
         vector = VIRTIO_NO_VECTOR;
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 8230a383aff..0f7c8acead0 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -3077,7 +3077,10 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f)
     Error *local_err = NULL;
 
     if (k->save_config) {
-        k->save_config(qbus->parent, f);
+        if (!k->save_config(qbus->parent, f, &local_err)) {
+            error_report_err(local_err);
+            return -EINVAL;
+        }
     }
 
     qemu_put_8s(f, &vdev->status);
@@ -3526,9 +3529,9 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     vdev->device_endian = VIRTIO_DEVICE_ENDIAN_UNKNOWN;
 
     if (k->load_config) {
-        ret = k->load_config(qbus->parent, f);
-        if (ret)
-            return ret;
+        if (!k->load_config(qbus->parent, f, &local_err)) {
+            return -EINVAL;
+        }
     }
 
     qemu_get_8s(f, &vdev->status);
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index f2448e941a0..7c3fdc05630 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -270,8 +270,8 @@ uint32_t pci_default_read_config(PCIDevice *d,
                                  uint32_t address, int len);
 void pci_default_write_config(PCIDevice *d,
                               uint32_t address, uint32_t val, int len);
-void pci_device_save(PCIDevice *s, QEMUFile *f);
-int pci_device_load(PCIDevice *s, QEMUFile *f);
+bool pci_device_save(PCIDevice *s, QEMUFile *f, Error **errp);
+bool pci_device_load(PCIDevice *s, QEMUFile *f, Error **errp);
 MemoryRegion *pci_address_space(PCIDevice *dev);
 MemoryRegion *pci_address_space_io(PCIDevice *dev);
 
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index 255ecb2fcb2..1b9867002b8 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -41,10 +41,10 @@ struct VirtioBusClass {
     /* This is what a VirtioBus must implement */
     BusClass parent;
     void (*notify)(DeviceState *d, uint16_t vector);
-    void (*save_config)(DeviceState *d, QEMUFile *f);
+    bool (*save_config)(DeviceState *d, QEMUFile *f, Error **errp);
     void (*save_queue)(DeviceState *d, int n, QEMUFile *f);
     bool (*save_extra_state)(DeviceState *d, QEMUFile *f, Error **errp);
-    int (*load_config)(DeviceState *d, QEMUFile *f);
+    bool (*load_config)(DeviceState *d, QEMUFile *f, Error **errp);
     int (*load_queue)(DeviceState *d, int n, QEMUFile *f);
     int (*load_done)(DeviceState *d, QEMUFile *f);
     bool (*load_extra_state)(DeviceState *d, QEMUFile *f, Error **errp);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 05/30] hw/virtio: make virtio_save() and virtio_load() static
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (3 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 04/30] hw/virtio: config save/load: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 06/30] hw/virtio: remaining: move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (25 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Michael S. Tsirkin

These functions are used only in virtio.c, no reason to make
them public.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/virtio/virtio.c         | 7 +++++--
 include/hw/virtio/virtio.h | 4 ----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 0f7c8acead0..a9338af6d00 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -62,6 +62,9 @@
  */
 #define VIRTIO_PCI_VRING_ALIGN         4096
 
+static int coroutine_mixed_fn
+virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id);
+
 typedef struct VRingDesc
 {
     uint64_t addr;
@@ -3067,7 +3070,7 @@ static const VMStateDescription vmstate_virtio = {
     }
 };
 
-int virtio_save(VirtIODevice *vdev, QEMUFile *f)
+static int virtio_save(VirtIODevice *vdev, QEMUFile *f)
 {
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
@@ -3510,7 +3513,7 @@ size_t virtio_get_config_size(const VirtIOConfigSizeParams *params,
     return config_size;
 }
 
-int coroutine_mixed_fn
+static int coroutine_mixed_fn
 virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
 {
     int i, ret;
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index c99cb19d886..9628ae3bcb8 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -338,8 +338,6 @@ int virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
 
 void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
 
-int virtio_save(VirtIODevice *vdev, QEMUFile *f);
-
 /**
  * virtio_new_shmem_region() - Create a new shared memory region
  * @vdev: VirtIODevice
@@ -443,8 +441,6 @@ extern const VMStateInfo virtio_vmstate_info;
         .flags = VMS_SINGLE,                  \
     }
 
-int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id);
-
 /**
  * virtio_notify_config() - signal a change to device config
  * @vdev: the virtio device
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 06/30] hw/virtio: remaining: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (4 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 05/30] hw/virtio: make virtio_save() and virtio_load() static Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 07/30] hw/s390x/virtio-ccw.c: " Vladimir Sementsov-Ogievskiy
                   ` (24 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx
  Cc: farosas, qemu-devel, vsementsov, Michael S. Tsirkin,
	Stefano Garzarella, Stefan Hajnoczi, open list:virtiofs

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/virtio/vhost-user-fs.c |  68 +++++++++----------
 hw/virtio/virtio.c        | 133 +++++++++++++++++++-------------------
 2 files changed, 100 insertions(+), 101 deletions(-)

diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index 209993918a3..215aff77282 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -307,49 +307,50 @@ static struct vhost_dev *vuf_get_vhost(VirtIODevice *vdev)
 /**
  * Fetch the internal state from virtiofsd and save it to `f`.
  */
-static int vuf_save_state(QEMUFile *f, void *pv, size_t size,
-                          const VMStateField *field, JSONWriter *vmdesc)
+static bool vuf_save_state(QEMUFile *f, void *pv, size_t size,
+                           const VMStateField *field, JSONWriter *vmdesc,
+                           Error **errp)
 {
+    ERRP_GUARD();
     VirtIODevice *vdev = pv;
     VHostUserFS *fs = VHOST_USER_FS(vdev);
-    Error *local_error = NULL;
     int ret;
 
-    ret = vhost_save_backend_state(&fs->vhost_dev, f, &local_error);
+    ret = vhost_save_backend_state(&fs->vhost_dev, f, errp);
     if (ret < 0) {
-        error_reportf_err(local_error,
-                          "Error saving back-end state of %s device %s "
-                          "(tag: \"%s\"): ",
-                          vdev->name, vdev->parent_obj.canonical_path,
-                          fs->conf.tag ?: "<none>");
-        return ret;
+        error_prepend(errp,
+                      "Error saving back-end state of %s device %s "
+                      "(tag: \"%s\"): ",
+                      vdev->name, vdev->parent_obj.canonical_path,
+                      fs->conf.tag ?: "<none>");
+        return false;
     }
 
-    return 0;
+    return true;
 }
 
 /**
  * Load virtiofsd's internal state from `f` and send it over to virtiofsd.
  */
-static int vuf_load_state(QEMUFile *f, void *pv, size_t size,
-                          const VMStateField *field)
+static bool vuf_load_state(QEMUFile *f, void *pv, size_t size,
+                           const VMStateField *field, Error **errp)
 {
+    ERRP_GUARD();
     VirtIODevice *vdev = pv;
     VHostUserFS *fs = VHOST_USER_FS(vdev);
-    Error *local_error = NULL;
     int ret;
 
-    ret = vhost_load_backend_state(&fs->vhost_dev, f, &local_error);
+    ret = vhost_load_backend_state(&fs->vhost_dev, f, errp);
     if (ret < 0) {
-        error_reportf_err(local_error,
-                          "Error loading back-end state of %s device %s "
-                          "(tag: \"%s\"): ",
-                          vdev->name, vdev->parent_obj.canonical_path,
-                          fs->conf.tag ?: "<none>");
-        return ret;
+        error_prepend(errp,
+                      "Error loading back-end state of %s device %s "
+                      "(tag: \"%s\"): ",
+                      vdev->name, vdev->parent_obj.canonical_path,
+                      fs->conf.tag ?: "<none>");
+        return false;
     }
 
-    return 0;
+    return true;
 }
 
 static bool vuf_is_internal_migration(void *opaque)
@@ -358,20 +359,21 @@ static bool vuf_is_internal_migration(void *opaque)
     return true;
 }
 
-static int vuf_check_migration_support(void *opaque)
+static bool vuf_check_migration_support(void *opaque, Error **errp)
 {
     VirtIODevice *vdev = opaque;
     VHostUserFS *fs = VHOST_USER_FS(vdev);
 
     if (!vhost_supports_device_state(&fs->vhost_dev)) {
-        error_report("Back-end of %s device %s (tag: \"%s\") does not support "
-                     "migration through qemu",
-                     vdev->name, vdev->parent_obj.canonical_path,
-                     fs->conf.tag ?: "<none>");
-        return -ENOTSUP;
+        error_setg(errp,
+                   "Back-end of %s device %s (tag: \"%s\") does not support "
+                   "migration through qemu",
+                   vdev->name, vdev->parent_obj.canonical_path,
+                   fs->conf.tag ?: "<none>");
+        return false;
     }
 
-    return 0;
+    return true;
 }
 
 static const VMStateDescription vuf_backend_vmstate;
@@ -393,15 +395,15 @@ static const VMStateDescription vuf_backend_vmstate = {
     .name = "vhost-user-fs-backend",
     .version_id = 0,
     .needed = vuf_is_internal_migration,
-    .pre_load = vuf_check_migration_support,
-    .pre_save = vuf_check_migration_support,
+    .pre_load_errp = vuf_check_migration_support,
+    .pre_save_errp = vuf_check_migration_support,
     .fields = (const VMStateField[]) {
         {
             .name = "back-end",
             .info = &(const VMStateInfo) {
                 .name = "virtio-fs back-end state",
-                .get = vuf_load_state,
-                .put = vuf_save_state,
+                .load = vuf_load_state,
+                .save = vuf_save_state,
             },
         },
         VMSTATE_END_OF_LIST()
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index a9338af6d00..0b1ec41ac97 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -62,8 +62,8 @@
  */
 #define VIRTIO_PCI_VRING_ALIGN         4096
 
-static int coroutine_mixed_fn
-virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id);
+static bool coroutine_mixed_fn
+virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id, Error **errp);
 
 typedef struct VRingDesc
 {
@@ -3070,19 +3070,17 @@ static const VMStateDescription vmstate_virtio = {
     }
 };
 
-static int virtio_save(VirtIODevice *vdev, QEMUFile *f)
+static bool virtio_save(VirtIODevice *vdev, QEMUFile *f, Error **errp)
 {
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
     uint32_t guest_features_lo = (vdev->guest_features & 0xffffffff);
-    int i, ret;
-    Error *local_err = NULL;
+    int i;
 
     if (k->save_config) {
-        if (!k->save_config(qbus->parent, f, &local_err)) {
-            error_report_err(local_err);
-            return -EINVAL;
+        if (!k->save_config(qbus->parent, f, errp)) {
+            return false;
         }
     }
 
@@ -3124,19 +3122,13 @@ static int virtio_save(VirtIODevice *vdev, QEMUFile *f)
     }
 
     if (vdc->vmsd) {
-        ret = vmstate_save_state(f, vdc->vmsd, vdev, NULL, &local_err);
-        if (ret) {
-            error_report_err(local_err);
-            return ret;
+        if (!vmstate_save_vmsd(f, vdc->vmsd, vdev, NULL, errp)) {
+            return false;
         }
     }
 
     /* Subsections */
-    ret = vmstate_save_state(f, &vmstate_virtio, vdev, NULL, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
-    return ret;
+    return vmstate_save_vmsd(f, &vmstate_virtio, vdev, NULL, errp);
 }
 
 VirtioSharedMemory *virtio_new_shmem_region(VirtIODevice *vdev, uint8_t shmid, uint64_t size)
@@ -3307,27 +3299,28 @@ void virtio_del_shmem_map(VirtioSharedMemory *shmem, hwaddr offset,
 }
 
 /* A wrapper for use as a VMState .put function */
-static int virtio_device_put(QEMUFile *f, void *opaque, size_t size,
-                              const VMStateField *field, JSONWriter *vmdesc)
+static bool virtio_device_save(QEMUFile *f, void *opaque, size_t size,
+                               const VMStateField *field, JSONWriter *vmdesc,
+                               Error **errp)
 {
-    return virtio_save(VIRTIO_DEVICE(opaque), f);
+    return virtio_save(VIRTIO_DEVICE(opaque), f, errp);
 }
 
 /* A wrapper for use as a VMState .get function */
-static int coroutine_mixed_fn
-virtio_device_get(QEMUFile *f, void *opaque, size_t size,
-                  const VMStateField *field)
+static bool coroutine_mixed_fn
+virtio_device_load(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
     DeviceClass *dc = DEVICE_CLASS(VIRTIO_DEVICE_GET_CLASS(vdev));
 
-    return virtio_load(vdev, f, dc->vmsd->version_id);
+    return virtio_load(vdev, f, dc->vmsd->version_id, errp);
 }
 
 const VMStateInfo  virtio_vmstate_info = {
     .name = "virtio",
-    .get = virtio_device_get,
-    .put = virtio_device_put,
+    .load = virtio_device_load,
+    .save = virtio_device_save,
 };
 
 static int virtio_set_features_nocheck(VirtIODevice *vdev, const uint64_t *val)
@@ -3513,8 +3506,8 @@ size_t virtio_get_config_size(const VirtIOConfigSizeParams *params,
     return config_size;
 }
 
-static int coroutine_mixed_fn
-virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
+static bool coroutine_mixed_fn
+virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id, Error **errp)
 {
     int i, ret;
     uint32_t config_len;
@@ -3523,7 +3516,6 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
-    Error *local_err = NULL;
 
     /*
      * We poison the endianness to ensure it does not get used before
@@ -3532,8 +3524,8 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     vdev->device_endian = VIRTIO_DEVICE_ENDIAN_UNKNOWN;
 
     if (k->load_config) {
-        if (!k->load_config(qbus->parent, f, &local_err)) {
-            return -EINVAL;
+        if (!k->load_config(qbus->parent, f, errp)) {
+            return false;
         }
     }
 
@@ -3541,7 +3533,9 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     qemu_get_8s(f, &vdev->isr);
     qemu_get_be16s(f, &vdev->queue_sel);
     if (vdev->queue_sel >= VIRTIO_QUEUE_MAX) {
-        return -1;
+        error_setg(errp, "virtio_load: queue_sel %u out of range",
+                   vdev->queue_sel);
+        return false;
     }
     qemu_get_be32s(f, &features);
 
@@ -3566,7 +3560,9 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
 
     while (config_len > vdev->config_len) {
         if (qemu_file_get_error(f)) {
-            return -1;
+            error_setg(errp, "virtio_load: stream error while skipping "
+                       "excess config");
+            return false;
         }
         qemu_get_byte(f);
         config_len--;
@@ -3575,24 +3571,25 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     num = qemu_get_be32(f);
 
     if (num > VIRTIO_QUEUE_MAX) {
-        error_report("Invalid number of virtqueues: 0x%x", num);
-        return -1;
+        error_setg(errp, "Invalid number of virtqueues: 0x%x", num);
+        return false;
     }
 
     if (vdc->pre_load_queues) {
         ret = vdc->pre_load_queues(vdev, num);
         if (ret) {
-            return ret;
+            error_setg(errp, "virtio_load: pre_load_queues failed");
+            return false;
         }
     }
 
     for (i = 0; i < num; i++) {
         vdev->vq[i].vring.num = qemu_get_be32(f);
         if (vdev->vq[i].vring.num > vdev->vq[i].vring.num_default) {
-            error_report("VQ %d vring.num %u exceeds allocated max %u",
-                         i, vdev->vq[i].vring.num,
-                         vdev->vq[i].vring.num_default);
-            return -1;
+            error_setg(errp, "VQ %d vring.num %u exceeds allocated max %u",
+                       i, vdev->vq[i].vring.num,
+                       vdev->vq[i].vring.num_default);
+            return false;
         }
         if (k->has_variable_vring_alignment) {
             vdev->vq[i].vring.align = qemu_get_be32(f);
@@ -3603,15 +3600,17 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
         vdev->vq[i].notification = true;
 
         if (!vdev->vq[i].vring.desc && vdev->vq[i].last_avail_idx) {
-            error_report("VQ %d address 0x0 "
-                         "inconsistent with Host index 0x%x",
-                         i, vdev->vq[i].last_avail_idx);
-            return -1;
+            error_setg(errp, "VQ %d address 0x0 "
+                       "inconsistent with Host index 0x%x",
+                       i, vdev->vq[i].last_avail_idx);
+            return false;
         }
         if (k->load_queue) {
             ret = k->load_queue(qbus->parent, i, f);
-            if (ret)
-                return ret;
+            if (ret) {
+                error_setg(errp, "virtio_load: load_queue failed for vq %d", i);
+                return false;
+            }
         }
     }
 
@@ -3620,23 +3619,20 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     if (vdc->load != NULL) {
         ret = vdc->load(vdev, f, version_id);
         if (ret) {
-            return ret;
+            error_setg(errp, "virtio_load: device load failed");
+            return false;
         }
     }
 
     if (vdc->vmsd) {
-        ret = vmstate_load_state(f, vdc->vmsd, vdev, version_id, &local_err);
-        if (ret) {
-            error_report_err(local_err);
-            return ret;
+        if (!vmstate_load_vmsd(f, vdc->vmsd, vdev, version_id, errp)) {
+            return false;
         }
     }
 
     /* Subsections */
-    ret = vmstate_load_state(f, &vmstate_virtio, vdev, 1, &local_err);
-    if (ret) {
-        error_report_err(local_err);
-        return ret;
+    if (!vmstate_load_vmsd(f, &vmstate_virtio, vdev, 1, errp)) {
+        return false;
     }
 
     if (vdev->device_endian == VIRTIO_DEVICE_ENDIAN_UNKNOWN) {
@@ -3649,11 +3645,11 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
      */
     if (virtio_set_features_nocheck_maybe_co(vdev,
                                              vdev->guest_features_ex) < 0) {
-        error_report("Features 0x" VIRTIO_FEATURES_FMT " unsupported. "
-                     "Allowed features: 0x" VIRTIO_FEATURES_FMT,
-                     VIRTIO_FEATURES_PR(vdev->guest_features_ex),
-                     VIRTIO_FEATURES_PR(vdev->host_features_ex));
-        return -1;
+        error_setg(errp, "Features 0x" VIRTIO_FEATURES_FMT " unsupported. "
+                   "Allowed features: 0x" VIRTIO_FEATURES_FMT,
+                   VIRTIO_FEATURES_PR(vdev->guest_features_ex),
+                   VIRTIO_FEATURES_PR(vdev->host_features_ex));
+        return false;
     }
 
     if (!virtio_device_started(vdev, vdev->status) &&
@@ -3710,12 +3706,12 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
             vdev->vq[i].inuse = (uint16_t)(vdev->vq[i].last_avail_idx -
                                 vdev->vq[i].used_idx);
             if (vdev->vq[i].inuse > vdev->vq[i].vring.num) {
-                error_report("VQ %d size 0x%x < last_avail_idx 0x%x - "
-                             "used_idx 0x%x",
-                             i, vdev->vq[i].vring.num,
-                             vdev->vq[i].last_avail_idx,
-                             vdev->vq[i].used_idx);
-                return -1;
+                error_setg(errp, "VQ %d size 0x%x < last_avail_idx 0x%x - "
+                           "used_idx 0x%x",
+                           i, vdev->vq[i].vring.num,
+                           vdev->vq[i].last_avail_idx,
+                           vdev->vq[i].used_idx);
+                return false;
             }
         }
     }
@@ -3723,11 +3719,12 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     if (vdc->post_load) {
         ret = vdc->post_load(vdev);
         if (ret) {
-            return ret;
+            error_setg(errp, "virtio_load: post_load failed");
+            return false;
         }
     }
 
-    return 0;
+    return true;
 }
 
 void virtio_cleanup(VirtIODevice *vdev)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 07/30] hw/s390x/virtio-ccw.c: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (5 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 06/30] hw/virtio: remaining: move to new migration APIs Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 08/30] hw/scsi/spapr_vscsi: " Vladimir Sementsov-Ogievskiy
                   ` (23 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx
  Cc: farosas, qemu-devel, vsementsov, Cornelia Huck, Halil Pasic,
	Eric Farman, Michael S. Tsirkin, Matthew Rosato,
	Richard Henderson, Ilya Leoshkevich, David Hildenbrand,
	Christian Borntraeger, open list:virtio-ccw

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/s390x/virtio-ccw.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 848ed09e94b..6bc901a64ec 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -40,7 +40,7 @@
 
 bool have_virtio_ccw = true;
 
-static int virtio_ccw_dev_post_load(void *opaque, int version_id)
+static bool virtio_ccw_dev_post_load(void *opaque, int version_id, Error **errp)
 {
     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(opaque);
     CcwDevice *ccw_dev = CCW_DEVICE(dev);
@@ -56,7 +56,7 @@ static int virtio_ccw_dev_post_load(void *opaque, int version_id)
     if (ck->refill_ids) {
         ck->refill_ids(ccw_dev);
     }
-    return 0;
+    return true;
 }
 
 typedef struct VirtioCcwDeviceTmp {
@@ -64,7 +64,7 @@ typedef struct VirtioCcwDeviceTmp {
     uint16_t config_vector;
 } VirtioCcwDeviceTmp;
 
-static int virtio_ccw_dev_tmp_pre_save(void *opaque)
+static bool virtio_ccw_dev_tmp_pre_save(void *opaque, Error **errp)
 {
     VirtioCcwDeviceTmp *tmp = opaque;
     VirtioCcwDevice *dev = tmp->parent;
@@ -72,23 +72,24 @@ static int virtio_ccw_dev_tmp_pre_save(void *opaque)
 
     tmp->config_vector = vdev->config_vector;
 
-    return 0;
+    return true;
 }
 
-static int virtio_ccw_dev_tmp_post_load(void *opaque, int version_id)
+static bool virtio_ccw_dev_tmp_post_load(void *opaque, int version_id,
+                                         Error **errp)
 {
     VirtioCcwDeviceTmp *tmp = opaque;
     VirtioCcwDevice *dev = tmp->parent;
     VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
 
     vdev->config_vector = tmp->config_vector;
-    return 0;
+    return true;
 }
 
 const VMStateDescription vmstate_virtio_ccw_dev_tmp = {
     .name = "s390_virtio_ccw_dev_tmp",
-    .pre_save = virtio_ccw_dev_tmp_pre_save,
-    .post_load = virtio_ccw_dev_tmp_post_load,
+    .pre_save_errp = virtio_ccw_dev_tmp_pre_save,
+    .post_load_errp = virtio_ccw_dev_tmp_post_load,
     .fields = (const VMStateField[]) {
         VMSTATE_UINT16(config_vector, VirtioCcwDeviceTmp),
         VMSTATE_END_OF_LIST()
@@ -99,7 +100,7 @@ const VMStateDescription vmstate_virtio_ccw_dev = {
     .name = "s390_virtio_ccw_dev",
     .version_id = 1,
     .minimum_version_id = 1,
-    .post_load = virtio_ccw_dev_post_load,
+    .post_load_errp = virtio_ccw_dev_post_load,
     .fields = (const VMStateField[]) {
         VMSTATE_CCW_DEVICE(parent_obj, VirtioCcwDevice),
         VMSTATE_PTR_TO_IND_ADDR(indicators, VirtioCcwDevice),
@@ -107,7 +108,7 @@ const VMStateDescription vmstate_virtio_ccw_dev = {
         VMSTATE_PTR_TO_IND_ADDR(summary_indicator, VirtioCcwDevice),
         /*
          * Ugly hack because VirtIODevice does not migrate itself.
-         * This also makes legacy via vmstate_save_state possible.
+         * This also makes legacy via vmstate_save_vmsd possible.
          */
         VMSTATE_WITH_TMP(VirtioCcwDevice, VirtioCcwDeviceTmp,
                          vmstate_virtio_ccw_dev_tmp),
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 08/30] hw/scsi/spapr_vscsi: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (6 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 07/30] hw/s390x/virtio-ccw.c: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 09/30] hw/scsi/scsi-bus.c: use " Vladimir Sementsov-Ogievskiy
                   ` (22 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx
  Cc: farosas, qemu-devel, vsementsov, Paolo Bonzini, Fam Zheng,
	Nicholas Piggin, Harsh Prateek Bora, Amit Machhiwal,
	open list:sPAPR (pseries)

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/scsi/spapr_vscsi.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index b4c8f94d22a..5938a392b95 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -629,12 +629,11 @@ static void vscsi_save_request(QEMUFile *f, SCSIRequest *sreq)
 {
     vscsi_req *req = sreq->hba_private;
     Error *local_err = NULL;
-    int rc;
 
     assert(req->active);
 
-    rc = vmstate_save_state(f, &vmstate_spapr_vscsi_req, req, NULL, &local_err);
-    if (rc < 0) {
+    if (!vmstate_save_vmsd(f, &vmstate_spapr_vscsi_req, req, NULL,
+                           &local_err)) {
         error_report_err(local_err);
         return;
     }
@@ -647,7 +646,6 @@ static void *vscsi_load_request(QEMUFile *f, SCSIRequest *sreq)
     SCSIBus *bus = sreq->bus;
     VSCSIState *s = VIO_SPAPR_VSCSI_DEVICE(bus->qbus.parent);
     vscsi_req *req;
-    int rc;
     Error *local_err = NULL;
 
     assert(sreq->tag < VSCSI_REQ_LIMIT);
@@ -655,8 +653,7 @@ static void *vscsi_load_request(QEMUFile *f, SCSIRequest *sreq)
     assert(!req->active);
 
     memset(req, 0, sizeof(*req));
-    rc = vmstate_load_state(f, &vmstate_spapr_vscsi_req, req, 1, &local_err);
-    if (rc) {
+    if (!vmstate_load_vmsd(f, &vmstate_spapr_vscsi_req, req, 1, &local_err)) {
         fprintf(stderr, "VSCSI: failed loading request tag#%u\n", sreq->tag);
         error_report_err(local_err);
         return NULL;
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 09/30] hw/scsi/scsi-bus.c: use new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (7 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 08/30] hw/scsi/spapr_vscsi: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 10/30] hw/vfio/pci: move to " Vladimir Sementsov-Ogievskiy
                   ` (21 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Paolo Bonzini, Fam Zheng

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/scsi/scsi-bus.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index deb43d5560e..d455c0b46b5 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -1888,18 +1888,19 @@ static void put_scsi_req(SCSIRequest *req, void *opaque)
     }
 }
 
-static int put_scsi_requests(QEMUFile *f, void *pv, size_t size,
-                             const VMStateField *field, JSONWriter *vmdesc)
+static bool put_scsi_requests(QEMUFile *f, void *pv, size_t size,
+                              const VMStateField *field, JSONWriter *vmdesc,
+                              Error **errp)
 {
     SCSIDevice *s = pv;
 
     scsi_device_for_each_req_sync(s, put_scsi_req, f);
     qemu_put_sbyte(f, 0);
-    return 0;
+    return true;
 }
 
-static int get_scsi_requests(QEMUFile *f, void *pv, size_t size,
-                             const VMStateField *field)
+static bool get_scsi_requests(QEMUFile *f, void *pv, size_t size,
+                              const VMStateField *field, Error **errp)
 {
     SCSIDevice *s = pv;
     SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus);
@@ -1938,13 +1939,13 @@ static int get_scsi_requests(QEMUFile *f, void *pv, size_t size,
         scsi_req_unref(req);
     }
 
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_info_scsi_requests = {
     .name = "scsi-requests",
-    .get  = get_scsi_requests,
-    .put  = put_scsi_requests,
+    .load = get_scsi_requests,
+    .save = put_scsi_requests,
 };
 
 static bool scsi_sense_state_needed(void *opaque)
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 10/30] hw/vfio/pci: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (8 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 09/30] hw/scsi/scsi-bus.c: use " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 11/30] hw/pci/pci: " Vladimir Sementsov-Ogievskiy
                   ` (20 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx
  Cc: farosas, qemu-devel, vsementsov, Alex Williamson,
	Cédric Le Goater

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/vfio/pci.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 428ab2f0698..ec59c30495d 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3000,8 +3000,8 @@ static int vfio_pci_save_config(VFIODevice *vbasedev, QEMUFile *f, Error **errp)
 {
     VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev);
 
-    return vmstate_save_state(f, &vmstate_vfio_pci_config, vdev, NULL,
-                              errp);
+    return vmstate_save_vmsd(
+        f, &vmstate_vfio_pci_config, vdev, NULL, errp) ? 0 : -EINVAL;
 }
 
 static int vfio_pci_load_config(VFIODevice *vbasedev, QEMUFile *f)
@@ -3009,18 +3009,16 @@ static int vfio_pci_load_config(VFIODevice *vbasedev, QEMUFile *f)
     VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev);
     PCIDevice *pdev = PCI_DEVICE(vdev);
     pcibus_t old_addr[PCI_NUM_REGIONS - 1];
-    int bar, ret;
+    int bar;
     Error *local_err = NULL;
 
     for (bar = 0; bar < PCI_ROM_SLOT; bar++) {
         old_addr[bar] = pdev->io_regions[bar].addr;
     }
 
-    ret = vmstate_load_state(f, &vmstate_vfio_pci_config, vdev, 1,
-                             &local_err);
-    if (ret) {
+    if (!vmstate_load_vmsd(f, &vmstate_vfio_pci_config, vdev, 1, &local_err)) {
         error_report_err(local_err);
-        return ret;
+        return -EINVAL;
     }
 
     vfio_pci_write_config(pdev, PCI_COMMAND,
@@ -3044,7 +3042,7 @@ static int vfio_pci_load_config(VFIODevice *vbasedev, QEMUFile *f)
         vfio_msix_enable(vdev);
     }
 
-    return ret;
+    return 0;
 }
 
 /* Transform from VFIODevice to VFIOPCIDevice. Return NULL if fails. */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 11/30] hw/pci/pci: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (9 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 10/30] hw/vfio/pci: move to " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 12/30] hw/pci/msix.c: use " Vladimir Sementsov-Ogievskiy
                   ` (19 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Michael S. Tsirkin

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/pci/pci.c | 58 ++++++++++++++++++++++++++++------------------------
 1 file changed, 31 insertions(+), 27 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 76d006fa1d7..0f70f0f7af8 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -807,8 +807,9 @@ int pci_bus_numa_node(PCIBus *bus)
     return PCI_BUS_GET_CLASS(bus)->numa_node(bus);
 }
 
-static int get_pci_config_device(QEMUFile *f, void *pv, size_t size,
-                                 const VMStateField *field)
+static bool load_pci_config_device(QEMUFile *f, void *pv, size_t size,
+                                   const VMStateField *field,
+                                   Error **errp)
 {
     PCIDevice *s = container_of(pv, PCIDevice, config);
     uint8_t *config;
@@ -821,12 +822,12 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size,
     for (i = 0; i < size; ++i) {
         if ((config[i] ^ s->config[i]) &
             s->cmask[i] & ~s->wmask[i] & ~s->w1cmask[i]) {
-            error_report("%s: Bad config data: i=0x%x read: %x device: %x "
-                         "cmask: %x wmask: %x w1cmask:%x", __func__,
-                         i, config[i], s->config[i],
-                         s->cmask[i], s->wmask[i], s->w1cmask[i]);
+            error_setg(errp, "%s: Bad config data: i=0x%x read: %x device: %x "
+                       "cmask: %x wmask: %x w1cmask:%x", __func__,
+                       i, config[i], s->config[i],
+                       s->cmask[i], s->wmask[i], s->w1cmask[i]);
             g_free(config);
-            return -EINVAL;
+            return false;
         }
     }
     memcpy(s->config, config, size);
@@ -840,28 +841,30 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size,
                       & PCI_COMMAND_MASTER);
 
     g_free(config);
-    return 0;
+    return true;
 }
 
 /* just put buffer */
-static int put_pci_config_device(QEMUFile *f, void *pv, size_t size,
-                                 const VMStateField *field, JSONWriter *vmdesc)
+static bool save_pci_config_device(QEMUFile *f, void *pv, size_t size,
+                                   const VMStateField *field,
+                                   JSONWriter *vmdesc, Error **errp)
 {
     const uint8_t **v = pv;
     assert(size == pci_config_size(container_of(pv, PCIDevice, config)));
     qemu_put_buffer(f, *v, size);
 
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_info_pci_config = {
     .name = "pci config",
-    .get  = get_pci_config_device,
-    .put  = put_pci_config_device,
+    .load  = load_pci_config_device,
+    .save  = save_pci_config_device,
 };
 
-static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size,
-                             const VMStateField *field)
+static bool load_pci_irq_state(QEMUFile *f, void *pv, size_t size,
+                               const VMStateField *field,
+                               Error **errp)
 {
     PCIDevice *s = container_of(pv, PCIDevice, irq_state);
     uint32_t irq_state[PCI_NUM_PINS];
@@ -869,9 +872,9 @@ static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size,
     for (i = 0; i < PCI_NUM_PINS; ++i) {
         irq_state[i] = qemu_get_be32(f);
         if (irq_state[i] != 0x1 && irq_state[i] != 0) {
-            fprintf(stderr, "irq state %d: must be 0 or 1.\n",
-                    irq_state[i]);
-            return -EINVAL;
+            error_setg(errp, "irq state %d: must be 0 or 1.",
+                       irq_state[i]);
+            return false;
         }
     }
 
@@ -879,11 +882,12 @@ static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size,
         pci_set_irq_state(s, i, irq_state[i]);
     }
 
-    return 0;
+    return true;
 }
 
-static int put_pci_irq_state(QEMUFile *f, void *pv, size_t size,
-                             const VMStateField *field, JSONWriter *vmdesc)
+static bool save_pci_irq_state(QEMUFile *f, void *pv, size_t size,
+                               const VMStateField *field, JSONWriter *vmdesc,
+                               Error **errp)
 {
     int i;
     PCIDevice *s = container_of(pv, PCIDevice, irq_state);
@@ -892,13 +896,13 @@ static int put_pci_irq_state(QEMUFile *f, void *pv, size_t size,
         qemu_put_be32(f, pci_irq_state(s, i));
     }
 
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_info_pci_irq_state = {
     .name = "pci irq state",
-    .get  = get_pci_irq_state,
-    .put  = put_pci_irq_state,
+    .load = load_pci_irq_state,
+    .save = save_pci_irq_state,
 };
 
 static bool migrate_is_pcie(void *opaque, int version_id)
@@ -911,17 +915,17 @@ static bool migrate_is_not_pcie(void *opaque, int version_id)
     return !pci_is_express((PCIDevice *)opaque);
 }
 
-static int pci_post_load(void *opaque, int version_id)
+static bool pci_post_load(void *opaque, int version_id, Error **errp)
 {
     pcie_sriov_pf_post_load(opaque);
-    return 0;
+    return true;
 }
 
 const VMStateDescription vmstate_pci_device = {
     .name = "PCIDevice",
     .version_id = 2,
     .minimum_version_id = 1,
-    .post_load = pci_post_load,
+    .post_load_errp = pci_post_load,
     .fields = (const VMStateField[]) {
         VMSTATE_INT32_POSITIVE_LE(version_id, PCIDevice),
         VMSTATE_BUFFER_UNSAFE_INFO_TEST(config, PCIDevice,
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 12/30] hw/pci/msix.c: use new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (10 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 11/30] hw/pci/pci: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 13/30] hw/pci/shpc.c: " Vladimir Sementsov-Ogievskiy
                   ` (18 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Michael S. Tsirkin

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/pci/msix.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/hw/pci/msix.c b/hw/pci/msix.c
index 1b23eaf1007..4dcb7c36770 100644
--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -685,25 +685,26 @@ void msix_unset_vector_notifiers(PCIDevice *dev)
     dev->msix_vector_poll_notifier = NULL;
 }
 
-static int put_msix_state(QEMUFile *f, void *pv, size_t size,
-                          const VMStateField *field, JSONWriter *vmdesc)
+static bool put_msix_state(QEMUFile *f, void *pv, size_t size,
+                           const VMStateField *field, JSONWriter *vmdesc,
+                           Error **errp)
 {
     msix_save(pv, f);
 
-    return 0;
+    return true;
 }
 
-static int get_msix_state(QEMUFile *f, void *pv, size_t size,
-                          const VMStateField *field)
+static bool get_msix_state(QEMUFile *f, void *pv, size_t size,
+                           const VMStateField *field, Error **errp)
 {
     msix_load(pv, f);
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_info_msix = {
     .name = "msix state",
-    .get  = get_msix_state,
-    .put  = put_msix_state,
+    .load = get_msix_state,
+    .save = put_msix_state,
 };
 
 const VMStateDescription vmstate_msix = {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 13/30] hw/pci/shpc.c: use new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (11 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 12/30] hw/pci/msix.c: use " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 14/30] hw/display/virtio-gpu: move to " Vladimir Sementsov-Ogievskiy
                   ` (17 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Michael S. Tsirkin

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/pci/shpc.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index 938602866d7..cdd2d0564ea 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -758,31 +758,33 @@ void shpc_cap_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
     shpc_cap_update_dword(d);
 }
 
-static int shpc_save(QEMUFile *f, void *pv, size_t size,
-                     const VMStateField *field, JSONWriter *vmdesc)
+static bool shpc_save(QEMUFile *f, void *pv, size_t size,
+                      const VMStateField *field, JSONWriter *vmdesc,
+                      Error **errp)
 {
     PCIDevice *d = container_of(pv, PCIDevice, shpc);
     qemu_put_buffer(f, d->shpc->config, SHPC_SIZEOF(d));
 
-    return 0;
+    return true;
 }
 
-static int shpc_load(QEMUFile *f, void *pv, size_t size,
-                     const VMStateField *field)
+static bool shpc_load(QEMUFile *f, void *pv, size_t size,
+                      const VMStateField *field, Error **errp)
 {
     PCIDevice *d = container_of(pv, PCIDevice, shpc);
     int ret = qemu_get_buffer(f, d->shpc->config, SHPC_SIZEOF(d));
     if (ret != SHPC_SIZEOF(d)) {
-        return -EINVAL;
+        error_setg(errp, "Failed to load SHPC config");
+        return false;
     }
     /* Make sure we don't lose notifications. An extra interrupt is harmless. */
     d->shpc->msi_requested = 0;
     shpc_interrupt_update(d);
-    return 0;
+    return true;
 }
 
 const VMStateInfo shpc_vmstate_info = {
     .name = "shpc",
-    .get  = shpc_load,
-    .put  = shpc_save,
+    .load = shpc_load,
+    .save = shpc_save,
 };
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 14/30] hw/display/virtio-gpu: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (12 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 13/30] hw/pci/shpc.c: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-29  6:54   ` Akihiko Odaki
  2026-08-25 21:37 ` [PATCH 15/30] hw/net/virtio-net.c: use " Vladimir Sementsov-Ogievskiy
                   ` (16 subsequent siblings)
  30 siblings, 1 reply; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx
  Cc: farosas, qemu-devel, vsementsov, Michael S. Tsirkin,
	Alex Bennée, Akihiko Odaki, Dmitry Osipenko

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/display/virtio-gpu.c | 99 ++++++++++++++++++++++-------------------
 1 file changed, 52 insertions(+), 47 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index fbb6fec7a0a..1af640accdc 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1308,13 +1308,13 @@ static const VMStateDescription vmstate_virtio_gpu_scanouts = {
     },
 };
 
-static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
-                           const VMStateField *field, JSONWriter *vmdesc)
+static bool virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
+                            const VMStateField *field, JSONWriter *vmdesc,
+                            Error **errp)
 {
     VirtIOGPU *g = opaque;
     struct virtio_gpu_simple_resource *res;
-    Error *err = NULL;
-    int i, ret;
+    int i;
 
     /* in 2d mode we should never find unprocessed commands here */
     assert(QTAILQ_EMPTY(&g->cmdq));
@@ -1337,12 +1337,7 @@ static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
     }
     qemu_put_be32(f, 0); /* end of list */
 
-    ret = vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL,
-                             &err);
-    if (ret < 0) {
-        error_report_err(err);
-    }
-    return ret;
+    return vmstate_save_vmsd(f, &vmstate_virtio_gpu_scanouts, g, NULL, errp);
 }
 
 static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
@@ -1374,14 +1369,13 @@ static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
     return true;
 }
 
-static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
-                           const VMStateField *field)
+static bool virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
+                            const VMStateField *field, Error **errp)
 {
     VirtIOGPU *g = opaque;
-    Error *err = NULL;
     struct virtio_gpu_simple_resource *res;
     uint32_t resource_id, pformat, hostmem, rowstride_bytes;
-    int i, ret;
+    int i;
 
     g->hostmem = 0;
 
@@ -1389,7 +1383,8 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
     while (resource_id != 0) {
         res = virtio_gpu_find_resource(g, resource_id);
         if (res) {
-            return -EINVAL;
+            error_setg(errp, "Failed to find resource %" PRIu32, resource_id);
+            return false;
         }
 
         res = g_new0(struct virtio_gpu_simple_resource, 1);
@@ -1402,14 +1397,16 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
         /* allocate */
         pformat = virtio_gpu_get_pixman_format(res->format);
         if (!pformat) {
+            error_setg(errp, "Unknown pixman format %" PRIu32, res->format);
             g_free(res);
-            return -EINVAL;
+            return false;
         }
 
         if (!calc_image_hostmem(pformat, res->width, res->height,
                                 &hostmem, &rowstride_bytes)) {
             g_free(res);
-            return -EINVAL;
+            error_setg(errp, "Failed to calculate image hostmem");
+            return false;
         }
         res->hostmem = hostmem;
         if (!qemu_pixman_image_new_shareable(&res->image,
@@ -1419,10 +1416,9 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
                                              res->width,
                                              res->height,
                                              rowstride_bytes,
-                                             &err)) {
-            warn_report_err(err);
+                                             errp)) {
             g_free(res);
-            return -EINVAL;
+            return false;
         }
 
         res->addrs = g_try_new(uint64_t, res->iov_cnt);
@@ -1432,7 +1428,8 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
             g_free(res->addrs);
             g_free(res->iov);
             g_free(res);
-            return -EINVAL;
+            error_setg(errp, "Failed to allocate iov arrays");
+            return false;
         }
 
         /* read data */
@@ -1446,22 +1443,20 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
         if (!virtio_gpu_load_restore_mapping(g, res)) {
             pixman_image_unref(res->image);
             g_free(res);
-            return -EINVAL;
+            error_setg(errp, "Failed to load restore mapping");
+            return false;
         }
 
         resource_id = qemu_get_be32(f);
     }
 
     /* load & apply scanout state */
-    ret = vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1, &err);
-    if (ret < 0) {
-        error_report_err(err);
-    }
-    return ret;
+    return vmstate_load_vmsd(f, &vmstate_virtio_gpu_scanouts, g, 1, errp);
 }
 
-static int virtio_gpu_blob_save(QEMUFile *f, void *opaque, size_t size,
-                                const VMStateField *field, JSONWriter *vmdesc)
+static bool virtio_gpu_blob_save(QEMUFile *f, void *opaque, size_t size,
+                                 const VMStateField *field, JSONWriter *vmdesc,
+                                 Error **errp)
 {
     VirtIOGPU *g = opaque;
     struct virtio_gpu_simple_resource *res;
@@ -1485,11 +1480,11 @@ static int virtio_gpu_blob_save(QEMUFile *f, void *opaque, size_t size,
     }
     qemu_put_be32(f, 0); /* end of list */
 
-    return 0;
+    return true;
 }
 
-static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
-                                const VMStateField *field)
+static bool virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
+                                 const VMStateField *field, Error **errp)
 {
     VirtIOGPU *g = opaque;
     struct virtio_gpu_simple_resource *res;
@@ -1500,7 +1495,8 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
     while (resource_id != 0) {
         res = virtio_gpu_find_resource(g, resource_id);
         if (res) {
-            return -EINVAL;
+            error_setg(errp, "Failed to find resource %" PRIu32, resource_id);
+            return false;
         }
 
         res = g_new0(struct virtio_gpu_simple_resource, 1);
@@ -1514,7 +1510,8 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
             g_free(res->addrs);
             g_free(res->iov);
             g_free(res);
-            return -EINVAL;
+            error_setg(errp, "Failed to allocate iov arrays");
+            return false;
         }
 
         /* read data */
@@ -1525,15 +1522,19 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
 
         if (res->iov_cnt > 0 &&
             iov_size(res->iov, res->iov_cnt) < res->blob_size) {
+            error_setg(errp, "iov size %" PRIu64 " < blob_size %" PRIu64,
+                       (uint64_t)iov_size(res->iov, res->iov_cnt),
+                       res->blob_size);
             g_free(res->addrs);
             g_free(res->iov);
             g_free(res);
-            return -EINVAL;
+            return false;
         }
 
         if (!virtio_gpu_load_restore_mapping(g, res)) {
             g_free(res);
-            return -EINVAL;
+            error_setg(errp, "Failed to load restore mapping");
+            return false;
         }
 
         virtio_gpu_init_udmabuf(res);
@@ -1541,10 +1542,10 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
         resource_id = qemu_get_be32(f);
     }
 
-    return 0;
+    return true;
 }
 
-static int virtio_gpu_post_load(void *opaque, int version_id)
+static bool virtio_gpu_post_load(void *opaque, int version_id, Error **errp)
 {
     VirtIOGPU *g = opaque;
     struct virtio_gpu_scanout *scanout;
@@ -1559,7 +1560,9 @@ static int virtio_gpu_post_load(void *opaque, int version_id)
 
         res = virtio_gpu_find_resource(g, scanout->resource_id);
         if (!res) {
-            return -EINVAL;
+            error_setg(errp, "Failed to find resource %" PRIu32,
+                       scanout->resource_id);
+            return false;
         }
 
         if (scanout->fb.format != 0) {
@@ -1572,12 +1575,14 @@ static int virtio_gpu_post_load(void *opaque, int version_id)
             };
 
             if (!virtio_gpu_do_set_scanout(g, i, &scanout->fb, res, &r, &error)) {
-                return -EINVAL;
+                error_setg(errp, "Failed to set scanout");
+                return false;
             }
         } else {
             /* legacy v1 migration support */
             if (!res->image) {
-                return -EINVAL;
+                error_setg(errp, "No image");
+                return false;
             }
             scanout->ds = qemu_create_displaysurface_pixman(res->image);
             qemu_displaysurface_set_share_handle(scanout->ds, res->share_handle, 0);
@@ -1591,7 +1596,7 @@ static int virtio_gpu_post_load(void *opaque, int version_id)
         res->scanout_bitmask |= (1 << i);
     }
 
-    return 0;
+    return true;
 }
 
 void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
@@ -1777,8 +1782,8 @@ const VMStateDescription vmstate_virtio_gpu_blob_state = {
             .name = "virtio-gpu/blob",
             .info = &(const VMStateInfo) {
                 .name = "blob",
-                .get = virtio_gpu_blob_load,
-                .put = virtio_gpu_blob_save,
+                .load = virtio_gpu_blob_load,
+                .save = virtio_gpu_blob_save,
             },
             .flags = VMS_SINGLE,
         } /* device */,
@@ -1804,8 +1809,8 @@ static const VMStateDescription vmstate_virtio_gpu = {
             .name = "virtio-gpu",
             .info = &(const VMStateInfo) {
                         .name = "virtio-gpu",
-                        .get = virtio_gpu_load,
-                        .put = virtio_gpu_save,
+                        .load = virtio_gpu_load,
+                        .save = virtio_gpu_save,
             },
             .flags = VMS_SINGLE,
         } /* device */,
@@ -1815,7 +1820,7 @@ static const VMStateDescription vmstate_virtio_gpu = {
         &vmstate_virtio_gpu_blob_state,
         NULL
     },
-    .post_load = virtio_gpu_post_load,
+    .post_load_errp = virtio_gpu_post_load,
 };
 
 static const Property virtio_gpu_properties[] = {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 15/30] hw/net/virtio-net.c: use new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (13 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 14/30] hw/display/virtio-gpu: move to " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 16/30] hw/nvram/eeprom93xx.c: " Vladimir Sementsov-Ogievskiy
                   ` (15 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Michael S. Tsirkin, Jason Wang

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/net/virtio-net.c | 133 ++++++++++++++++++++++----------------------
 1 file changed, 66 insertions(+), 67 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 814b99a43d2..a48c87e2453 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3198,7 +3198,8 @@ static void virtio_net_get_features(VirtIODevice *vdev, uint64_t *features,
     }
 }
 
-static int virtio_net_post_load_device(void *opaque, int version_id)
+static bool virtio_net_post_load_device(void *opaque, int version_id,
+                                        Error **errp)
 {
     VirtIONet *n = opaque;
     VirtIODevice *vdev = VIRTIO_DEVICE(n);
@@ -3261,7 +3262,7 @@ static int virtio_net_post_load_device(void *opaque, int version_id)
     }
 
     virtio_net_commit_rss_config(n);
-    return 0;
+    return true;
 }
 
 static int virtio_net_post_load_virtio(VirtIODevice *vdev)
@@ -3327,7 +3328,7 @@ struct VirtIONetMigTmp {
  * pointer and count and also validate the count.
  */
 
-static int virtio_net_tx_waiting_pre_save(void *opaque)
+static bool virtio_net_tx_waiting_pre_save(void *opaque, Error **errp)
 {
     struct VirtIONetMigTmp *tmp = opaque;
 
@@ -3337,30 +3338,31 @@ static int virtio_net_tx_waiting_pre_save(void *opaque)
         tmp->curr_queue_pairs_1 = 0;
     }
 
-    return 0;
+    return true;
 }
 
-static int virtio_net_tx_waiting_pre_load(void *opaque)
+static bool virtio_net_tx_waiting_pre_load(void *opaque, Error **errp)
 {
     struct VirtIONetMigTmp *tmp = opaque;
 
     /* Reuse the pointer setup from save */
-    virtio_net_tx_waiting_pre_save(opaque);
+    /* TODO: handle the error in a follow-up patch */
+    virtio_net_tx_waiting_pre_save(opaque, NULL);
 
     if (tmp->parent->curr_queue_pairs > tmp->parent->max_queue_pairs) {
-        error_report("virtio-net: curr_queue_pairs %x > max_queue_pairs %x",
+        error_setg(errp, "virtio-net: curr_queue_pairs %x > max_queue_pairs %x",
             tmp->parent->curr_queue_pairs, tmp->parent->max_queue_pairs);
 
-        return -EINVAL;
+        return false;
     }
 
-    return 0; /* all good */
+    return true;
 }
 
 static const VMStateDescription vmstate_virtio_net_tx_waiting = {
     .name      = "virtio-net-tx_waiting",
-    .pre_load  = virtio_net_tx_waiting_pre_load,
-    .pre_save  = virtio_net_tx_waiting_pre_save,
+    .pre_load_errp = virtio_net_tx_waiting_pre_load,
+    .pre_save_errp = virtio_net_tx_waiting_pre_save,
     .fields    = (const VMStateField[]) {
         VMSTATE_STRUCT_VARRAY_POINTER_UINT16(vqs_1, struct VirtIONetMigTmp,
                                      curr_queue_pairs_1,
@@ -3373,31 +3375,31 @@ static const VMStateDescription vmstate_virtio_net_tx_waiting = {
 /* the 'has_ufo' flag is just tested; if the incoming stream has the
  * flag set we need to check that we have it
  */
-static int virtio_net_ufo_post_load(void *opaque, int version_id)
+static bool virtio_net_ufo_post_load(void *opaque, int version_id, Error **errp)
 {
     struct VirtIONetMigTmp *tmp = opaque;
 
     if (tmp->has_ufo && !peer_has_ufo(tmp->parent)) {
-        error_report("virtio-net: saved image requires TUN_F_UFO support");
-        return -EINVAL;
+        error_setg(errp, "virtio-net: saved image requires TUN_F_UFO support");
+        return false;
     }
 
-    return 0;
+    return true;
 }
 
-static int virtio_net_ufo_pre_save(void *opaque)
+static bool virtio_net_ufo_pre_save(void *opaque, Error **errp)
 {
     struct VirtIONetMigTmp *tmp = opaque;
 
     tmp->has_ufo = tmp->parent->has_ufo;
 
-    return 0;
+    return true;
 }
 
 static const VMStateDescription vmstate_virtio_net_has_ufo = {
     .name      = "virtio-net-ufo",
-    .post_load = virtio_net_ufo_post_load,
-    .pre_save  = virtio_net_ufo_pre_save,
+    .post_load_errp = virtio_net_ufo_post_load,
+    .pre_save_errp = virtio_net_ufo_pre_save,
     .fields    = (const VMStateField[]) {
         VMSTATE_UINT8(has_ufo, struct VirtIONetMigTmp),
         VMSTATE_END_OF_LIST()
@@ -3407,38 +3409,39 @@ static const VMStateDescription vmstate_virtio_net_has_ufo = {
 /* the 'has_vnet_hdr' flag is just tested; if the incoming stream has the
  * flag set we need to check that we have it
  */
-static int virtio_net_vnet_post_load(void *opaque, int version_id)
+static bool virtio_net_vnet_post_load(void *opaque, int version_id,
+                                      Error **errp)
 {
     struct VirtIONetMigTmp *tmp = opaque;
 
     if (tmp->has_vnet_hdr && !peer_has_vnet_hdr(tmp->parent)) {
-        error_report("virtio-net: saved image requires vnet_hdr=on");
-        return -EINVAL;
+        error_setg(errp, "virtio-net: saved image requires vnet_hdr=on");
+        return false;
     }
 
-    return 0;
+    return true;
 }
 
-static int virtio_net_vnet_pre_save(void *opaque)
+static bool virtio_net_vnet_pre_save(void *opaque, Error **errp)
 {
     struct VirtIONetMigTmp *tmp = opaque;
 
     tmp->has_vnet_hdr = tmp->parent->has_vnet_hdr;
 
-    return 0;
+    return true;
 }
 
 static const VMStateDescription vmstate_virtio_net_has_vnet = {
     .name      = "virtio-net-vnet",
-    .post_load = virtio_net_vnet_post_load,
-    .pre_save  = virtio_net_vnet_pre_save,
+    .post_load_errp = virtio_net_vnet_post_load,
+    .pre_save_errp = virtio_net_vnet_pre_save,
     .fields    = (const VMStateField[]) {
         VMSTATE_UINT32(has_vnet_hdr, struct VirtIONetMigTmp),
         VMSTATE_END_OF_LIST()
     },
 };
 
-static int virtio_net_rss_post_load(void *opaque, int version_id)
+static bool virtio_net_rss_post_load(void *opaque, int version_id, Error **errp)
 {
     VirtIONet *n = VIRTIO_NET(opaque);
 
@@ -3447,13 +3450,13 @@ static int virtio_net_rss_post_load(void *opaque, int version_id)
     }
 
     if (!virtio_net_rss_indirections_len_valid(n->rss_data.indirections_len)) {
-        error_report("virtio-net: saved image has invalid RSS "
-                     "indirections_len: %u",
-                     n->rss_data.indirections_len);
-        return -EINVAL;
+        error_setg(errp, "virtio-net: saved image has invalid RSS "
+                   "indirections_len: %u",
+                   n->rss_data.indirections_len);
+        return false;
     }
 
-    return 0;
+    return true;
 }
 
 static bool virtio_net_rss_needed(void *opaque)
@@ -3465,7 +3468,7 @@ static const VMStateDescription vmstate_virtio_net_rss = {
     .name      = "virtio-net-device/rss",
     .version_id = 2,
     .minimum_version_id = 1,
-    .post_load = virtio_net_rss_post_load,
+    .post_load_errp = virtio_net_rss_post_load,
     .needed = virtio_net_rss_needed,
     .fields = (const VMStateField[]) {
         VMSTATE_BOOL(rss_data.enabled, VirtIONet),
@@ -3507,61 +3510,57 @@ static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev)
     return &net->dev;
 }
 
-static int vhost_user_net_save_state(QEMUFile *f, void *pv, size_t size,
-                                     const VMStateField *field,
-                                     JSONWriter *vmdesc)
+static bool vhost_user_net_save_state(QEMUFile *f, void *pv, size_t size,
+                                      const VMStateField *field,
+                                      JSONWriter *vmdesc, Error **errp)
 {
+    ERRP_GUARD();
     VirtIONet *n = pv;
     VirtIODevice *vdev = VIRTIO_DEVICE(n);
     struct vhost_dev *vhdev;
-    Error *local_error = NULL;
     int ret;
 
     vhdev = virtio_net_get_vhost(vdev);
     if (vhdev == NULL) {
-        error_reportf_err(local_error,
-                          "Error getting vhost back-end of %s device %s: ",
-                          vdev->name, vdev->parent_obj.canonical_path);
-        return -1;
+        error_setg(errp, "Error getting vhost back-end of %s device %s",
+                   vdev->name, vdev->parent_obj.canonical_path);
+        return false;
     }
 
-    ret = vhost_save_backend_state(vhdev, f, &local_error);
+    ret = vhost_save_backend_state(vhdev, f, errp);
     if (ret < 0) {
-        error_reportf_err(local_error,
-                          "Error saving back-end state of %s device %s: ",
-                          vdev->name, vdev->parent_obj.canonical_path);
-        return ret;
+        error_prepend(errp, "Error saving back-end state of %s device %s: ",
+                      vdev->name, vdev->parent_obj.canonical_path);
+        return false;
     }
 
-    return 0;
+    return true;
 }
 
-static int vhost_user_net_load_state(QEMUFile *f, void *pv, size_t size,
-                                     const VMStateField *field)
+static bool vhost_user_net_load_state(QEMUFile *f, void *pv, size_t size,
+                                      const VMStateField *field, Error **errp)
 {
+    ERRP_GUARD();
     VirtIONet *n = pv;
     VirtIODevice *vdev = VIRTIO_DEVICE(n);
     struct vhost_dev *vhdev;
-    Error *local_error = NULL;
     int ret;
 
     vhdev = virtio_net_get_vhost(vdev);
     if (vhdev == NULL) {
-        error_reportf_err(local_error,
-                          "Error getting vhost back-end of %s device %s: ",
-                          vdev->name, vdev->parent_obj.canonical_path);
-        return -1;
+        error_setg(errp, "Error getting vhost back-end of %s device %s",
+                   vdev->name, vdev->parent_obj.canonical_path);
+        return false;
     }
 
-    ret = vhost_load_backend_state(vhdev, f, &local_error);
+    ret = vhost_load_backend_state(vhdev, f, errp);
     if (ret < 0) {
-        error_reportf_err(local_error,
-                          "Error loading  back-end state of %s device %s: ",
-                          vdev->name, vdev->parent_obj.canonical_path);
-        return ret;
+        error_prepend(errp, "Error loading back-end state of %s device %s: ",
+                      vdev->name, vdev->parent_obj.canonical_path);
+        return false;
     }
 
-    return 0;
+    return true;
 }
 
 static bool vhost_user_net_is_internal_migration(void *opaque)
@@ -3587,8 +3586,8 @@ static const VMStateDescription vhost_user_net_backend_state = {
             .name = "backend",
             .info = &(const VMStateInfo) {
                 .name = "virtio-net vhost-user backend state",
-                .get = vhost_user_net_load_state,
-                .put = vhost_user_net_save_state,
+                .load = vhost_user_net_load_state,
+                .save = vhost_user_net_save_state,
             },
          },
          VMSTATE_END_OF_LIST()
@@ -3599,7 +3598,7 @@ static const VMStateDescription vmstate_virtio_net_device = {
     .name = "virtio-net-device",
     .version_id = VIRTIO_NET_VM_VERSION,
     .minimum_version_id = VIRTIO_NET_VM_VERSION,
-    .post_load = virtio_net_post_load_device,
+    .post_load_errp = virtio_net_post_load_device,
     .fields = (const VMStateField[]) {
         VMSTATE_UINT8_ARRAY(mac, VirtIONet, ETH_ALEN),
         VMSTATE_STRUCT_POINTER(vqs, VirtIONet,
@@ -4169,7 +4168,7 @@ static void virtio_net_instance_init(Object *obj)
     ebpf_rss_init(&n->ebpf_rss);
 }
 
-static int virtio_net_pre_save(void *opaque)
+static bool virtio_net_pre_save(void *opaque, Error **errp)
 {
     VirtIONet *n = opaque;
 
@@ -4177,7 +4176,7 @@ static int virtio_net_pre_save(void *opaque)
      * it might keep writing to memory. */
     assert(!n->vhost_started);
 
-    return 0;
+    return true;
 }
 
 static bool primary_unplug_pending(void *opaque)
@@ -4210,7 +4209,7 @@ static const VMStateDescription vmstate_virtio_net = {
         VMSTATE_VIRTIO_DEVICE,
         VMSTATE_END_OF_LIST()
     },
-    .pre_save = virtio_net_pre_save,
+    .pre_save_errp = virtio_net_pre_save,
     .dev_unplug_pending = dev_unplug_pending,
 };
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 16/30] hw/nvram/eeprom93xx.c: use new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (14 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 15/30] hw/net/virtio-net.c: use " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 17/30] hw/nvram/fw_cfg.c: " Vladimir Sementsov-Ogievskiy
                   ` (14 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Stefan Weil

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/nvram/eeprom93xx.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/hw/nvram/eeprom93xx.c b/hw/nvram/eeprom93xx.c
index 73b3d248d44..de689322567 100644
--- a/hw/nvram/eeprom93xx.c
+++ b/hw/nvram/eeprom93xx.c
@@ -95,28 +95,29 @@ struct _eeprom_t {
    This is a Big hack, but it is how the old state did it.
  */
 
-static int get_uint16_from_uint8(QEMUFile *f, void *pv, size_t size,
-                                 const VMStateField *field)
+static bool get_uint16_from_uint8(QEMUFile *f, void *pv, size_t size,
+                                  const VMStateField *field, Error **errp)
 {
     uint16_t *v = pv;
     *v = qemu_get_ubyte(f);
-    return 0;
+    return true;
 }
 
-static int put_unused(QEMUFile *f, void *pv, size_t size,
-                      const VMStateField *field, JSONWriter *vmdesc)
+static bool put_unused(QEMUFile *f, void *pv, size_t size,
+                       const VMStateField *field, JSONWriter *vmdesc,
+                       Error **errp)
 {
     fprintf(stderr, "uint16_from_uint8 is used only for backwards compatibility.\n");
     fprintf(stderr, "Never should be used to write a new state.\n");
     exit(0);
 
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_hack_uint16_from_uint8 = {
     .name = "uint16_from_uint8",
-    .get  = get_uint16_from_uint8,
-    .put  = put_unused,
+    .load = get_uint16_from_uint8,
+    .save = put_unused,
 };
 
 #define VMSTATE_UINT16_HACK_TEST(_f, _s, _t)                           \
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 17/30] hw/nvram/fw_cfg.c: use new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (15 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 16/30] hw/nvram/eeprom93xx.c: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 18/30] hw/usb/redirect.c: move to " Vladimir Sementsov-Ogievskiy
                   ` (13 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Gerd Hoffmann

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/nvram/fw_cfg.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index b057d870c00..5f67f5ff618 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -565,27 +565,28 @@ static void fw_cfg_reset(DeviceState *d)
    Or we broke compatibility in the state, or we can't use struct tm
  */
 
-static int get_uint32_as_uint16(QEMUFile *f, void *pv, size_t size,
-                                const VMStateField *field)
+static bool get_uint32_as_uint16(QEMUFile *f, void *pv, size_t size,
+                                 const VMStateField *field, Error **errp)
 {
     uint32_t *v = pv;
     *v = qemu_get_be16(f);
-    return 0;
+    return true;
 }
 
-static int put_unused(QEMUFile *f, void *pv, size_t size,
-                      const VMStateField *field, JSONWriter *vmdesc)
+static bool put_unused(QEMUFile *f, void *pv, size_t size,
+                       const VMStateField *field, JSONWriter *vmdesc,
+                       Error **errp)
 {
     fprintf(stderr, "uint32_as_uint16 is only used for backward compatibility.\n");
     fprintf(stderr, "This functions shouldn't be called.\n");
 
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_hack_uint32_as_uint16 = {
     .name = "int32_as_uint16",
-    .get  = get_uint32_as_uint16,
-    .put  = put_unused,
+    .load = get_uint32_as_uint16,
+    .save = put_unused,
 };
 
 #define VMSTATE_UINT16_HACK(_f, _s, _t)                                    \
@@ -631,7 +632,8 @@ static void fw_cfg_update_mr(FWCfgState *s, uint16_t key, size_t size)
     memory_region_ram_resize(mr, size, &error_abort);
 }
 
-static int fw_cfg_acpi_mr_restore_post_load(void *opaque, int version_id)
+static bool fw_cfg_acpi_mr_restore_post_load(void *opaque, int version_id,
+                                             Error **errp)
 {
     FWCfgState *s = opaque;
     int i, index;
@@ -650,7 +652,7 @@ static int fw_cfg_acpi_mr_restore_post_load(void *opaque, int version_id)
         }
     }
 
-    return 0;
+    return true;
 }
 
 static const VMStateDescription vmstate_fw_cfg_dma = {
@@ -667,7 +669,7 @@ static const VMStateDescription vmstate_fw_cfg_acpi_mr = {
     .version_id = 1,
     .minimum_version_id = 1,
     .needed = fw_cfg_acpi_mr_restore,
-    .post_load = fw_cfg_acpi_mr_restore_post_load,
+    .post_load_errp = fw_cfg_acpi_mr_restore_post_load,
     .fields = (const VMStateField[]) {
         VMSTATE_UINT64(table_mr_size, FWCfgState),
         VMSTATE_UINT64(linker_mr_size, FWCfgState),
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 18/30] hw/usb/redirect.c: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (16 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 17/30] hw/nvram/fw_cfg.c: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:37 ` [PATCH 19/30] alpha/machine: " Vladimir Sementsov-Ogievskiy
                   ` (12 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx
  Cc: farosas, qemu-devel, vsementsov, Paolo Bonzini,
	Marc-André Lureau, Thomas Huth, Philippe Mathieu-Daudé,
	Matthew Penney

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 hw/usb/redirect.c | 59 ++++++++++++++++++++++++++---------------------
 1 file changed, 33 insertions(+), 26 deletions(-)

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index dfd9e8bb50c..f4196b944d5 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -2267,8 +2267,9 @@ static int usbredir_post_load(void *priv, int version_id)
 }
 
 /* For usbredirparser migration */
-static int usbredir_put_parser(QEMUFile *f, void *priv, size_t unused,
-                               const VMStateField *field, JSONWriter *vmdesc)
+static bool usbredir_save_parser(QEMUFile *f, void *priv, size_t unused,
+                                 const VMStateField *field,
+                                 JSONWriter *vmdesc, Error **errp)
 {
     USBRedirDevice *dev = priv;
     uint8_t *data;
@@ -2276,7 +2277,7 @@ static int usbredir_put_parser(QEMUFile *f, void *priv, size_t unused,
 
     if (dev->parser == NULL) {
         qemu_put_be32(f, 0);
-        return 0;
+        return true;
     }
 
     usbredirparser_serialize(dev->parser, &data, &len);
@@ -2290,11 +2291,11 @@ static int usbredir_put_parser(QEMUFile *f, void *priv, size_t unused,
 
     free(data);
 
-    return 0;
+    return true;
 }
 
-static int usbredir_get_parser(QEMUFile *f, void *priv, size_t unused,
-                               const VMStateField *field)
+static bool usbredir_load_parser(QEMUFile *f, void *priv, size_t unused,
+                               const VMStateField *field, Error **errp)
 {
     USBRedirDevice *dev = priv;
     uint8_t *data;
@@ -2302,7 +2303,7 @@ static int usbredir_get_parser(QEMUFile *f, void *priv, size_t unused,
 
     len = qemu_get_be32(f);
     if (len == 0) {
-        return 0;
+        return true;
     }
 
     /*
@@ -2326,19 +2327,25 @@ static int usbredir_get_parser(QEMUFile *f, void *priv, size_t unused,
 
     g_free(data);
 
-    return ret;
+    if (ret) {
+        error_setg(errp, "usbredirparser_unserialize failed");
+        return false;
+    }
+
+    return true;
 }
 
 static const VMStateInfo usbredir_parser_vmstate_info = {
     .name = "usb-redir-parser",
-    .put  = usbredir_put_parser,
-    .get  = usbredir_get_parser,
+    .save = usbredir_save_parser,
+    .load = usbredir_load_parser,
 };
 
 
 /* For buffered packets (iso/irq) queue migration */
-static int usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused,
-                              const VMStateField *field, JSONWriter *vmdesc)
+static bool usbredir_save_bufpq(QEMUFile *f, void *priv, size_t unused,
+                                const VMStateField *field,
+                                JSONWriter *vmdesc, Error **errp)
 {
     struct endp_data *endp = priv;
     USBRedirDevice *dev = endp->dev;
@@ -2357,11 +2364,11 @@ static int usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused,
     }
     assert(i == endp->bufpq_size);
 
-    return 0;
+    return true;
 }
 
-static int usbredir_get_bufpq(QEMUFile *f, void *priv, size_t unused,
-                              const VMStateField *field)
+static bool usbredir_load_bufpq(QEMUFile *f, void *priv, size_t unused,
+                              const VMStateField *field, Error **errp)
 {
     struct endp_data *endp = priv;
     USBRedirDevice *dev = endp->dev;
@@ -2385,13 +2392,13 @@ static int usbredir_get_bufpq(QEMUFile *f, void *priv, size_t unused,
         DPRINTF("get_bufpq %d/%d len %d status %d\n", i + 1, endp->bufpq_size,
                 bufp->len, bufp->status);
     }
-    return 0;
+    return true;
 }
 
 static const VMStateInfo usbredir_ep_bufpq_vmstate_info = {
     .name = "usb-redir-bufpq",
-    .put  = usbredir_put_bufpq,
-    .get  = usbredir_get_bufpq,
+    .save = usbredir_save_bufpq,
+    .load = usbredir_load_bufpq,
 };
 
 
@@ -2468,9 +2475,9 @@ static const VMStateDescription usbredir_ep_vmstate = {
 
 
 /* For PacketIdQueue migration */
-static int usbredir_put_packet_id_q(QEMUFile *f, void *priv, size_t unused,
+static bool usbredir_save_packet_id_q(QEMUFile *f, void *priv, size_t unused,
                                     const VMStateField *field,
-                                    JSONWriter *vmdesc)
+                                    JSONWriter *vmdesc, Error **errp)
 {
     struct PacketIdQueue *q = priv;
     USBRedirDevice *dev = q->dev;
@@ -2485,11 +2492,11 @@ static int usbredir_put_packet_id_q(QEMUFile *f, void *priv, size_t unused,
     }
     assert(remain == 0);
 
-    return 0;
+    return true;
 }
 
-static int usbredir_get_packet_id_q(QEMUFile *f, void *priv, size_t unused,
-                                    const VMStateField *field)
+static bool usbredir_load_packet_id_q(QEMUFile *f, void *priv, size_t unused,
+                                    const VMStateField *field, Error **errp)
 {
     struct PacketIdQueue *q = priv;
     USBRedirDevice *dev = q->dev;
@@ -2503,13 +2510,13 @@ static int usbredir_get_packet_id_q(QEMUFile *f, void *priv, size_t unused,
         packet_id_queue_add(q, id);
     }
     assert(q->size == size);
-    return 0;
+    return true;
 }
 
 static const VMStateInfo usbredir_ep_packet_id_q_vmstate_info = {
     .name = "usb-redir-packet-id-q",
-    .put  = usbredir_put_packet_id_q,
-    .get  = usbredir_get_packet_id_q,
+    .save = usbredir_save_packet_id_q,
+    .load = usbredir_load_packet_id_q,
 };
 
 static const VMStateDescription usbredir_ep_packet_id_queue_vmstate = {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 19/30] alpha/machine: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (17 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 18/30] hw/usb/redirect.c: move to " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:37 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:38 ` [PATCH 20/30] avr/machine: " Vladimir Sementsov-Ogievskiy
                   ` (11 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:37 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Richard Henderson

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 target/alpha/machine.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/target/alpha/machine.c b/target/alpha/machine.c
index dcba5d441be..a3f67dd7b81 100644
--- a/target/alpha/machine.c
+++ b/target/alpha/machine.c
@@ -3,26 +3,27 @@
 #include "migration/qemu-file-types.h"
 #include "migration/vmstate.h"
 
-static int get_fpcr(QEMUFile *f, void *opaque, size_t size,
-                    const VMStateField *field)
+static bool load_fpcr(QEMUFile *f, void *opaque, size_t size,
+                     const VMStateField *field, Error **errp)
 {
     CPUAlphaState *env = opaque;
     cpu_alpha_store_fpcr(env, qemu_get_be64(f));
-    return 0;
+    return true;
 }
 
-static int put_fpcr(QEMUFile *f, void *opaque, size_t size,
-                    const VMStateField *field, JSONWriter *vmdesc)
+static bool save_fpcr(QEMUFile *f, void *opaque, size_t size,
+                     const VMStateField *field, JSONWriter *vmdesc,
+                     Error **errp)
 {
     CPUAlphaState *env = opaque;
     qemu_put_be64(f, cpu_alpha_load_fpcr(env));
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_fpcr = {
     .name = "fpcr",
-    .get = get_fpcr,
-    .put = put_fpcr,
+    .load = load_fpcr,
+    .save = save_fpcr,
 };
 
 static const VMStateField vmstate_env_fields[] = {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 20/30] avr/machine: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (18 preceding siblings ...)
  2026-08-25 21:37 ` [PATCH 19/30] alpha/machine: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:38 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:38 ` [PATCH 21/30] or1k/machine: " Vladimir Sementsov-Ogievskiy
                   ` (10 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:38 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Michael Rolnik

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 target/avr/machine.c | 50 +++++++++++++++++++++++---------------------
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/target/avr/machine.c b/target/avr/machine.c
index 8064a7214a3..2f6283743c7 100644
--- a/target/avr/machine.c
+++ b/target/avr/machine.c
@@ -23,78 +23,80 @@
 #include "migration/qemu-file-types.h"
 #include "migration/vmstate.h"
 
-static int get_sreg(QEMUFile *f, void *opaque, size_t size,
-                    const VMStateField *field)
+static bool load_sreg(QEMUFile *f, void *opaque, size_t size,
+                     const VMStateField *field, Error **errp)
 {
     CPUAVRState *env = opaque;
     uint8_t sreg;
 
     sreg = qemu_get_byte(f);
     cpu_set_sreg(env, sreg);
-    return 0;
+    return true;
 }
 
-static int put_sreg(QEMUFile *f, void *opaque, size_t size,
-                    const VMStateField *field, JSONWriter *vmdesc)
+static bool save_sreg(QEMUFile *f, void *opaque, size_t size,
+                     const VMStateField *field, JSONWriter *vmdesc,
+                     Error **errp)
 {
     CPUAVRState *env = opaque;
     uint8_t sreg = cpu_get_sreg(env);
 
     qemu_put_byte(f, sreg);
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vms_sreg = {
     .name = "sreg",
-    .get = get_sreg,
-    .put = put_sreg,
+    .load = load_sreg,
+    .save = save_sreg,
 };
 
-static int get_segment(QEMUFile *f, void *opaque, size_t size,
-                       const VMStateField *field)
+static bool load_segment(QEMUFile *f, void *opaque, size_t size,
+                        const VMStateField *field, Error **errp)
 {
     uint32_t *ramp = opaque;
     uint8_t temp;
 
     temp = qemu_get_byte(f);
     *ramp = ((uint32_t)temp) << 16;
-    return 0;
+    return true;
 }
 
-static int put_segment(QEMUFile *f, void *opaque, size_t size,
-                       const VMStateField *field, JSONWriter *vmdesc)
+static bool save_segment(QEMUFile *f, void *opaque, size_t size,
+                        const VMStateField *field, JSONWriter *vmdesc,
+                        Error **errp)
 {
     uint32_t *ramp = opaque;
     uint8_t temp = *ramp >> 16;
 
     qemu_put_byte(f, temp);
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vms_rampD = {
     .name = "rampD",
-    .get = get_segment,
-    .put = put_segment,
+    .load = load_segment,
+    .save = save_segment,
 };
 static const VMStateInfo vms_rampX = {
     .name = "rampX",
-    .get = get_segment,
-    .put = put_segment,
+    .load = load_segment,
+    .save = save_segment,
 };
 static const VMStateInfo vms_rampY = {
     .name = "rampY",
-    .get = get_segment,
-    .put = put_segment,
+    .load = load_segment,
+    .save = save_segment,
 };
 static const VMStateInfo vms_rampZ = {
     .name = "rampZ",
-    .get = get_segment,
-    .put = put_segment,
+    .load = load_segment,
+    .save = save_segment,
 };
 static const VMStateInfo vms_eind = {
     .name = "eind",
-    .get = get_segment,
-    .put = put_segment,
+    .load = load_segment,
+    .save = save_segment,
 };
 
 const VMStateDescription vms_avr_cpu = {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 21/30] or1k/machine: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (19 preceding siblings ...)
  2026-08-25 21:38 ` [PATCH 20/30] avr/machine: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:38 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:38 ` [PATCH 22/30] microblaze/machine: " Vladimir Sementsov-Ogievskiy
                   ` (9 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:38 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Stafford Horne

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 target/or1k/machine.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/target/or1k/machine.c b/target/or1k/machine.c
index 2d5ca16c511..800dc4c21cc 100644
--- a/target/or1k/machine.c
+++ b/target/or1k/machine.c
@@ -46,26 +46,27 @@ static const VMStateDescription vmstate_cpu_tlb = {
     }
 };
 
-static int get_sr(QEMUFile *f, void *opaque, size_t size,
-                  const VMStateField *field)
+static bool load_sr(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     CPUOpenRISCState *env = opaque;
     cpu_set_sr(env, qemu_get_be32(f));
-    return 0;
+    return true;
 }
 
-static int put_sr(QEMUFile *f, void *opaque, size_t size,
-                  const VMStateField *field, JSONWriter *vmdesc)
+static bool save_sr(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, JSONWriter *vmdesc,
+                   Error **errp)
 {
     CPUOpenRISCState *env = opaque;
     qemu_put_be32(f, cpu_get_sr(env));
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_sr = {
     .name = "sr",
-    .get = get_sr,
-    .put = put_sr,
+    .load = load_sr,
+    .save = save_sr,
 };
 
 static const VMStateDescription vmstate_env = {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 22/30] microblaze/machine: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (20 preceding siblings ...)
  2026-08-25 21:38 ` [PATCH 21/30] or1k/machine: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:38 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:38 ` [PATCH 23/30] hppa/machine: " Vladimir Sementsov-Ogievskiy
                   ` (8 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:38 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Edgar E. Iglesias

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 target/microblaze/machine.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/target/microblaze/machine.c b/target/microblaze/machine.c
index f930ff86091..73e741b6df2 100644
--- a/target/microblaze/machine.c
+++ b/target/microblaze/machine.c
@@ -37,28 +37,29 @@ static const VMStateDescription vmstate_mmu = {
     .fields = vmstate_mmu_fields,
 };
 
-static int get_msr(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field)
+static bool load_msr(QEMUFile *f, void *opaque, size_t size,
+                    const VMStateField *field, Error **errp)
 {
     CPUMBState *env = container_of(opaque, CPUMBState, msr);
 
     mb_cpu_write_msr(env, qemu_get_be32(f));
-    return 0;
+    return true;
 }
 
-static int put_msr(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field, JSONWriter *vmdesc)
+static bool save_msr(QEMUFile *f, void *opaque, size_t size,
+                    const VMStateField *field, JSONWriter *vmdesc,
+                    Error **errp)
 {
     CPUMBState *env = container_of(opaque, CPUMBState, msr);
 
     qemu_put_be32(f, mb_cpu_read_msr(env));
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_msr = {
     .name = "msr",
-    .get = get_msr,
-    .put = put_msr,
+    .load = load_msr,
+    .save = save_msr,
 };
 
 static const VMStateField vmstate_env_fields[] = {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 23/30] hppa/machine: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (21 preceding siblings ...)
  2026-08-25 21:38 ` [PATCH 22/30] microblaze/machine: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:38 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:38 ` [PATCH 24/30] sparc/machine: " Vladimir Sementsov-Ogievskiy
                   ` (7 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:38 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Richard Henderson, Helge Deller

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 target/hppa/machine.c | 34 ++++++++++++++++++----------------
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/target/hppa/machine.c b/target/hppa/machine.c
index 6a143cf8df2..ddd9f27b772 100644
--- a/target/hppa/machine.c
+++ b/target/hppa/machine.c
@@ -23,30 +23,31 @@
 #include "migration/vmstate.h"
 
 
-static int get_psw(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field)
+static bool load_psw(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     CPUHPPAState *env = opaque;
     cpu_hppa_put_psw(env, qemu_get_be64(f));
-    return 0;
+    return true;
 }
 
-static int put_psw(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field, JSONWriter *vmdesc)
+static bool save_psw(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, JSONWriter *vmdesc,
+                   Error **errp)
 {
     CPUHPPAState *env = opaque;
     qemu_put_be64(f, cpu_hppa_get_psw(env));
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_psw = {
     .name = "psw",
-    .get = get_psw,
-    .put = put_psw,
+    .load = load_psw,
+    .save = save_psw,
 };
 
-static int get_tlb(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field)
+static bool load_tlb(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     HPPATLBEntry *ent = opaque;
     uint64_t val;
@@ -69,11 +70,12 @@ static int get_tlb(QEMUFile *f, void *opaque, size_t size,
         ent->access_id = extract64(val, 1, 31);
         ent->entry_valid = 1;
     }
-    return 0;
+    return true;
 }
 
-static int put_tlb(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field, JSONWriter *vmdesc)
+static bool save_tlb(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, JSONWriter *vmdesc,
+                   Error **errp)
 {
     HPPATLBEntry *ent = opaque;
     uint64_t val = 0;
@@ -96,13 +98,13 @@ static int put_tlb(QEMUFile *f, void *opaque, size_t size,
     qemu_put_be64(f, ent->itree.last);
     qemu_put_be64(f, ent->pa);
     qemu_put_be64(f, val);
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_tlb_entry = {
     .name = "tlb entry",
-    .get = get_tlb,
-    .put = put_tlb,
+    .load = load_tlb,
+    .save = save_tlb,
 };
 
 static int tlb_pre_load(void *opaque)
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 24/30] sparc/machine: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (22 preceding siblings ...)
  2026-08-25 21:38 ` [PATCH 23/30] hppa/machine: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:38 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:38 ` [PATCH 25/30] ppc/machine: " Vladimir Sementsov-Ogievskiy
                   ` (6 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:38 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov, Mark Cave-Ayland,
	Artyom Tarasenko

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 target/sparc/machine.c | 68 ++++++++++++++++++++++--------------------
 1 file changed, 36 insertions(+), 32 deletions(-)

diff --git a/target/sparc/machine.c b/target/sparc/machine.c
index 0d5d79b5e7b..46f1e12344c 100644
--- a/target/sparc/machine.c
+++ b/target/sparc/machine.c
@@ -51,8 +51,8 @@ static const VMStateDescription vmstate_tlb_entry = {
 };
 #endif
 
-static int get_psr(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field)
+static bool load_psr(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     SPARCCPU *cpu = opaque;
     CPUSPARCState *env = &cpu->env;
@@ -62,11 +62,12 @@ static int get_psr(QEMUFile *f, void *opaque, size_t size,
     env->cwp = 0;
     cpu_put_psr_raw(env, val);
 
-    return 0;
+    return true;
 }
 
-static int put_psr(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field, JSONWriter *vmdesc)
+static bool save_psr(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, JSONWriter *vmdesc,
+                   Error **errp)
 {
     SPARCCPU *cpu = opaque;
     CPUSPARCState *env = &cpu->env;
@@ -75,17 +76,17 @@ static int put_psr(QEMUFile *f, void *opaque, size_t size,
     val = cpu_get_psr(env);
 
     qemu_put_be32(f, val);
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_psr = {
     .name = "psr",
-    .get = get_psr,
-    .put = put_psr,
+    .load = load_psr,
+    .save = save_psr,
 };
 
-static int get_fsr(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field)
+static bool load_fsr(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     SPARCCPU *cpu = opaque;
 
@@ -95,11 +96,12 @@ static int get_fsr(QEMUFile *f, void *opaque, size_t size,
         cpu_put_fsr(&cpu->env, qemu_get_be32(f));
     }
 
-    return 0;
+    return true;
 }
 
-static int put_fsr(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field, JSONWriter *vmdesc)
+static bool save_fsr(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, JSONWriter *vmdesc,
+                   Error **errp)
 {
     SPARCCPU *cpu = opaque;
 
@@ -108,18 +110,18 @@ static int put_fsr(QEMUFile *f, void *opaque, size_t size,
     } else {
         qemu_put_be32(f, cpu_get_fsr(&cpu->env));
     }
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_fsr = {
     .name = "fsr",
-    .get = get_fsr,
-    .put = put_fsr,
+    .load = load_fsr,
+    .save = save_fsr,
 };
 
 #ifdef TARGET_SPARC64
-static int get_xcc(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field)
+static bool load_xcc(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     SPARCCPU *cpu = opaque;
     CPUSPARCState *env = &cpu->env;
@@ -131,11 +133,12 @@ static int get_xcc(QEMUFile *f, void *opaque, size_t size,
     env->xcc_Z = ~val & PSR_ZERO;
     env->xcc_C = (val >> PSR_CARRY_SHIFT) & 1;
 
-    return 0;
+    return true;
 }
 
-static int put_xcc(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field, JSONWriter *vmdesc)
+static bool save_xcc(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, JSONWriter *vmdesc,
+                   Error **errp)
 {
     SPARCCPU *cpu = opaque;
     CPUSPARCState *env = &cpu->env;
@@ -143,17 +146,17 @@ static int put_xcc(QEMUFile *f, void *opaque, size_t size,
 
     /* Extract just xcc out of ccr and shift into legacy position. */
     qemu_put_be32(f, (val & 0xf0) << (20 - 4));
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_xcc = {
     .name = "xcc",
-    .get = get_xcc,
-    .put = put_xcc,
+    .load = load_xcc,
+    .save = save_xcc,
 };
 
-static int get_cwp(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field)
+static bool load_cwp(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     SPARCCPU *cpu = opaque;
     CPUSPARCState *env = &cpu->env;
@@ -163,24 +166,25 @@ static int get_cwp(QEMUFile *f, void *opaque, size_t size,
     env->cwp = 0;
     cpu_set_cwp(env, val);
 
-    return 0;
+    return true;
 }
 
-static int put_cwp(QEMUFile *f, void *opaque, size_t size,
-                   const VMStateField *field, JSONWriter *vmdesc)
+static bool save_cwp(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, JSONWriter *vmdesc,
+                   Error **errp)
 {
     SPARCCPU *cpu = opaque;
     CPUSPARCState *env = &cpu->env;
     uint32_t val = env->cwp;
 
     qemu_put_be32(f, val);
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_cwp = {
     .name = "uint32",
-    .get = get_cwp,
-    .put = put_cwp,
+    .load = load_cwp,
+    .save = save_cwp,
 };
 #else
 static bool fq_needed(void *opaque)
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 25/30] ppc/machine: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (23 preceding siblings ...)
  2026-08-25 21:38 ` [PATCH 24/30] sparc/machine: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:38 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:38 ` [PATCH 26/30] mips/machine: " Vladimir Sementsov-Ogievskiy
                   ` (5 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:38 UTC (permalink / raw)
  To: peterx
  Cc: farosas, qemu-devel, vsementsov, Nicholas Piggin, Chinmay Rath,
	Glenn Miles, Harsh Prateek Bora, open list:PowerPC TCG CPUs

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 target/ppc/machine.c | 80 ++++++++++++++++++++++----------------------
 1 file changed, 40 insertions(+), 40 deletions(-)

diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index 569536bd02d..f188bb9f5ea 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -23,31 +23,31 @@ static void post_load_update_msr(CPUPPCState *env)
     ppc_store_msr(env, msr);
 }
 
-static int get_avr(QEMUFile *f, void *pv, size_t size,
-                   const VMStateField *field)
+static bool load_avr(QEMUFile *f, void *pv, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     ppc_avr_t *v = pv;
 
     v->u64[0] = qemu_get_be64(f);
     v->u64[1] = qemu_get_be64(f);
 
-    return 0;
+    return true;
 }
 
-static int put_avr(QEMUFile *f, void *pv, size_t size,
-                   const VMStateField *field, JSONWriter *vmdesc)
+static bool save_avr(QEMUFile *f, void *pv, size_t size,
+                   const VMStateField *field, JSONWriter *vmdesc, Error **errp)
 {
     ppc_avr_t *v = pv;
 
     qemu_put_be64(f, v->u64[0]);
     qemu_put_be64(f, v->u64[1]);
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_info_avr = {
     .name = "avr",
-    .get  = get_avr,
-    .put  = put_avr,
+    .load = load_avr,
+    .save = save_avr,
 };
 
 #define VMSTATE_AVR_ARRAY_V(_f, _s, _n, _v)                       \
@@ -56,29 +56,29 @@ static const VMStateInfo vmstate_info_avr = {
 #define VMSTATE_AVR_ARRAY(_f, _s, _n)                             \
     VMSTATE_AVR_ARRAY_V(_f, _s, _n, 0)
 
-static int get_fpr(QEMUFile *f, void *pv, size_t size,
-                   const VMStateField *field)
+static bool load_fpr(QEMUFile *f, void *pv, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     ppc_vsr_t *v = pv;
 
     v->VsrD(0) = qemu_get_be64(f);
 
-    return 0;
+    return true;
 }
 
-static int put_fpr(QEMUFile *f, void *pv, size_t size,
-                   const VMStateField *field, JSONWriter *vmdesc)
+static bool save_fpr(QEMUFile *f, void *pv, size_t size,
+                   const VMStateField *field, JSONWriter *vmdesc, Error **errp)
 {
     ppc_vsr_t *v = pv;
 
     qemu_put_be64(f, v->VsrD(0));
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_info_fpr = {
     .name = "fpr",
-    .get  = get_fpr,
-    .put  = put_fpr,
+    .load = load_fpr,
+    .save = save_fpr,
 };
 
 #define VMSTATE_FPR_ARRAY_V(_f, _s, _n, _v)                       \
@@ -87,29 +87,29 @@ static const VMStateInfo vmstate_info_fpr = {
 #define VMSTATE_FPR_ARRAY(_f, _s, _n)                             \
     VMSTATE_FPR_ARRAY_V(_f, _s, _n, 0)
 
-static int get_vsr(QEMUFile *f, void *pv, size_t size,
-                   const VMStateField *field)
+static bool load_vsr(QEMUFile *f, void *pv, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     ppc_vsr_t *v = pv;
 
     v->VsrD(1) = qemu_get_be64(f);
 
-    return 0;
+    return true;
 }
 
-static int put_vsr(QEMUFile *f, void *pv, size_t size,
-                   const VMStateField *field, JSONWriter *vmdesc)
+static bool save_vsr(QEMUFile *f, void *pv, size_t size,
+                   const VMStateField *field, JSONWriter *vmdesc, Error **errp)
 {
     ppc_vsr_t *v = pv;
 
     qemu_put_be64(f, v->VsrD(1));
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_info_vsr = {
     .name = "vsr",
-    .get  = get_vsr,
-    .put  = put_vsr,
+    .load = load_vsr,
+    .save = save_vsr,
 };
 
 #define VMSTATE_VSR_ARRAY_V(_f, _s, _n, _v)                       \
@@ -344,26 +344,26 @@ static bool altivec_needed(void *opaque)
     return cpu->env.insns_flags & PPC_ALTIVEC;
 }
 
-static int get_vscr(QEMUFile *f, void *opaque, size_t size,
-                    const VMStateField *field)
+static bool load_vscr(QEMUFile *f, void *opaque, size_t size,
+                    const VMStateField *field, Error **errp)
 {
     PowerPCCPU *cpu = opaque;
     ppc_store_vscr(&cpu->env, qemu_get_be32(f));
-    return 0;
+    return true;
 }
 
-static int put_vscr(QEMUFile *f, void *opaque, size_t size,
-                    const VMStateField *field, JSONWriter *vmdesc)
+static bool save_vscr(QEMUFile *f, void *opaque, size_t size,
+                    const VMStateField *field, JSONWriter *vmdesc, Error **errp)
 {
     PowerPCCPU *cpu = opaque;
     qemu_put_be32(f, ppc_get_vscr(&cpu->env));
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_vscr = {
     .name = "cpu/altivec/vscr",
-    .get = get_vscr,
-    .put = put_vscr,
+    .load = load_vscr,
+    .save = save_vscr,
 };
 
 static const VMStateDescription vmstate_altivec = {
@@ -465,31 +465,31 @@ static const VMStateDescription vmstate_sr = {
 };
 
 #ifdef TARGET_PPC64
-static int get_slbe(QEMUFile *f, void *pv, size_t size,
-                    const VMStateField *field)
+static bool load_slbe(QEMUFile *f, void *pv, size_t size,
+                    const VMStateField *field, Error **errp)
 {
     ppc_slb_t *v = pv;
 
     v->esid = qemu_get_be64(f);
     v->vsid = qemu_get_be64(f);
 
-    return 0;
+    return true;
 }
 
-static int put_slbe(QEMUFile *f, void *pv, size_t size,
-                    const VMStateField *field, JSONWriter *vmdesc)
+static bool save_slbe(QEMUFile *f, void *pv, size_t size,
+                    const VMStateField *field, JSONWriter *vmdesc, Error **errp)
 {
     ppc_slb_t *v = pv;
 
     qemu_put_be64(f, v->esid);
     qemu_put_be64(f, v->vsid);
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_info_slbe = {
     .name = "slbe",
-    .get  = get_slbe,
-    .put  = put_slbe,
+    .load = load_slbe,
+    .save = save_slbe,
 };
 
 #define VMSTATE_SLB_ARRAY_V(_f, _s, _n, _v)                       \
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 26/30] mips/machine: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (24 preceding siblings ...)
  2026-08-25 21:38 ` [PATCH 25/30] ppc/machine: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:38 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:38 ` [PATCH 27/30] arm/machine: " Vladimir Sementsov-Ogievskiy
                   ` (4 subsequent siblings)
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:38 UTC (permalink / raw)
  To: peterx
  Cc: farosas, qemu-devel, vsementsov, Philippe Mathieu-Daudé,
	Aurelien Jarno, Jiaxun Yang, Aleksandar Rikalo

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 target/mips/system/machine.c | 49 ++++++++++++++++++------------------
 1 file changed, 25 insertions(+), 24 deletions(-)

diff --git a/target/mips/system/machine.c b/target/mips/system/machine.c
index bd1e4002cfd..dc8a9920e5a 100644
--- a/target/mips/system/machine.c
+++ b/target/mips/system/machine.c
@@ -22,8 +22,8 @@ static int cpu_post_load(void *opaque, int version_id)
 
 /* FPU state */
 
-static int get_fpr(QEMUFile *f, void *pv, size_t size,
-                   const VMStateField *field)
+static bool load_fpr(QEMUFile *f, void *pv, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     int i;
     fpr_t *v = pv;
@@ -31,11 +31,11 @@ static int get_fpr(QEMUFile *f, void *pv, size_t size,
     for (i = 0; i < MSA_WRLEN / 64; i++) {
         qemu_get_sbe64s(f, &v->wr.d[i]);
     }
-    return 0;
+    return true;
 }
 
-static int put_fpr(QEMUFile *f, void *pv, size_t size,
-                   const VMStateField *field, JSONWriter *vmdesc)
+static bool save_fpr(QEMUFile *f, void *pv, size_t size,
+                   const VMStateField *field, JSONWriter *vmdesc, Error **errp)
 {
     int i;
     fpr_t *v = pv;
@@ -44,13 +44,13 @@ static int put_fpr(QEMUFile *f, void *pv, size_t size,
         qemu_put_sbe64s(f, &v->wr.d[i]);
     }
 
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_info_fpr = {
     .name = "fpr",
-    .get  = get_fpr,
-    .put  = put_fpr,
+    .load = load_fpr,
+    .save = save_fpr,
 };
 
 #define VMSTATE_FPR_ARRAY_V(_f, _s, _n, _v)                     \
@@ -145,8 +145,9 @@ static gboolean put_octeon_llm_tree_entry(gpointer key, gpointer value,
     return false;
 }
 
-static int put_octeon_llm_tree(QEMUFile *f, void *pv, size_t size,
-                               const VMStateField *field, JSONWriter *vmdesc)
+static bool save_octeon_llm_tree(QEMUFile *f, void *pv, size_t size,
+                                 const VMStateField *field,
+                                 JSONWriter *vmdesc, Error **errp)
 {
     QTree *tree = *(QTree **)pv;
     OcteonLLMTreePutData data = { .f = f };
@@ -157,11 +158,11 @@ static int put_octeon_llm_tree(QEMUFile *f, void *pv, size_t size,
         q_tree_foreach(tree, put_octeon_llm_tree_entry, &data);
     }
 
-    return 0;
+    return true;
 }
 
-static int get_octeon_llm_tree(QEMUFile *f, void *pv, size_t size,
-                               const VMStateField *field)
+static bool load_octeon_llm_tree(QEMUFile *f, void *pv, size_t size,
+                               const VMStateField *field, Error **errp)
 {
     QTree **treep = pv;
     uint32_t nnodes = qemu_get_be32(f);
@@ -178,13 +179,13 @@ static int get_octeon_llm_tree(QEMUFile *f, void *pv, size_t size,
         mips_octeon_llm_store(treep, addr, value);
     }
 
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_info_octeon_llm_tree = {
     .name = "octeon_llm_tree",
-    .get = get_octeon_llm_tree,
-    .put = put_octeon_llm_tree,
+    .load = load_octeon_llm_tree,
+    .save = save_octeon_llm_tree,
 };
 
 #define VMSTATE_OCTEON_LLM_TREE(_f, _s) {                         \
@@ -210,8 +211,8 @@ static const VMStateDescription vmstate_mvp = {
 
 /* TLB state */
 
-static int get_tlb(QEMUFile *f, void *pv, size_t size,
-                   const VMStateField *field)
+static bool load_tlb(QEMUFile *f, void *pv, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     r4k_tlb_t *v = pv;
     uint16_t flags;
@@ -240,11 +241,11 @@ static int get_tlb(QEMUFile *f, void *pv, size_t size,
     qemu_get_be64s(f, &v->PFN[0]);
     qemu_get_be64s(f, &v->PFN[1]);
 
-    return 0;
+    return true;
 }
 
-static int put_tlb(QEMUFile *f, void *pv, size_t size,
-                   const VMStateField *field, JSONWriter *vmdesc)
+static bool save_tlb(QEMUFile *f, void *pv, size_t size,
+                   const VMStateField *field, JSONWriter *vmdesc, Error **errp)
 {
     r4k_tlb_t *v = pv;
 
@@ -275,13 +276,13 @@ static int put_tlb(QEMUFile *f, void *pv, size_t size,
     qemu_put_be64s(f, &v->PFN[0]);
     qemu_put_be64s(f, &v->PFN[1]);
 
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_info_tlb = {
     .name = "tlb_entry",
-    .get  = get_tlb,
-    .put  = put_tlb,
+    .load = load_tlb,
+    .save = save_tlb,
 };
 
 #define VMSTATE_TLB_ARRAY_V(_f, _s, _n, _v)                     \
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 27/30] arm/machine: move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (25 preceding siblings ...)
  2026-08-25 21:38 ` [PATCH 26/30] mips/machine: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:38 ` Vladimir Sementsov-Ogievskiy
  2026-09-03 17:15   ` Fabiano Rosas
  2026-08-25 21:38 ` [PATCH 28/30] migration/vmstate-types: convert vmstate_info_g_byte_array to new APIs Vladimir Sementsov-Ogievskiy
                   ` (3 subsequent siblings)
  30 siblings, 1 reply; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:38 UTC (permalink / raw)
  To: peterx
  Cc: farosas, qemu-devel, vsementsov, Peter Maydell,
	open list:ARM TCG CPUs

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 target/arm/machine.c | 107 ++++++++++++++++++++++---------------------
 1 file changed, 56 insertions(+), 51 deletions(-)

diff --git a/target/arm/machine.c b/target/arm/machine.c
index 89127e5d83c..159a1f0e930 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -51,8 +51,8 @@ static bool vfp_fpcr_fpsr_needed(void *opaque)
         (vfp_get_fpsr(env) & ~FPSCR_FPSR_MASK);
 }
 
-static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
-                     const VMStateField *field)
+static bool load_fpscr(QEMUFile *f, void *opaque, size_t size,
+                     const VMStateField *field, Error **errp)
 {
     ARMCPU *cpu = opaque;
     CPUARMState *env = &cpu->env;
@@ -62,78 +62,81 @@ static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
         /* 0 means we might have the data in the fpcr_fpsr subsection */
         vfp_set_fpscr(env, val);
     }
-    return 0;
+    return true;
 }
 
-static int put_fpscr(QEMUFile *f, void *opaque, size_t size,
-                     const VMStateField *field, JSONWriter *vmdesc)
+static bool save_fpscr(QEMUFile *f, void *opaque, size_t size,
+                      const VMStateField *field,
+                      JSONWriter *vmdesc, Error **errp)
 {
     ARMCPU *cpu = opaque;
     CPUARMState *env = &cpu->env;
     uint32_t fpscr = vfp_fpcr_fpsr_needed(opaque) ? 0 : vfp_get_fpscr(env);
 
     qemu_put_be32(f, fpscr);
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_fpscr = {
     .name = "fpscr",
-    .get = get_fpscr,
-    .put = put_fpscr,
+    .load = load_fpscr,
+    .save = save_fpscr,
 };
 
-static int get_fpcr(QEMUFile *f, void *opaque, size_t size,
-                     const VMStateField *field)
+static bool load_fpcr(QEMUFile *f, void *opaque, size_t size,
+                     const VMStateField *field, Error **errp)
 {
     ARMCPU *cpu = opaque;
     CPUARMState *env = &cpu->env;
     uint64_t val = qemu_get_be64(f);
 
     vfp_set_fpcr(env, val);
-    return 0;
+    return true;
 }
 
-static int put_fpcr(QEMUFile *f, void *opaque, size_t size,
-                     const VMStateField *field, JSONWriter *vmdesc)
+static bool save_fpcr(QEMUFile *f, void *opaque, size_t size,
+                    const VMStateField *field,
+                    JSONWriter *vmdesc, Error **errp)
 {
     ARMCPU *cpu = opaque;
     CPUARMState *env = &cpu->env;
 
     qemu_put_be64(f, vfp_get_fpcr(env));
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_fpcr = {
     .name = "fpcr",
-    .get = get_fpcr,
-    .put = put_fpcr,
+    .load = load_fpcr,
+    .save = save_fpcr,
 };
 
-static int get_fpsr(QEMUFile *f, void *opaque, size_t size,
-                     const VMStateField *field)
+static bool load_fpsr(QEMUFile *f, void *opaque, size_t size,
+                     const VMStateField *field, Error **errp)
 {
     ARMCPU *cpu = opaque;
     CPUARMState *env = &cpu->env;
     uint64_t val = qemu_get_be64(f);
 
     vfp_set_fpsr(env, val);
-    return 0;
+    return true;
 }
 
-static int put_fpsr(QEMUFile *f, void *opaque, size_t size,
-                     const VMStateField *field, JSONWriter *vmdesc)
+static bool save_fpsr(QEMUFile *f, void *opaque, size_t size,
+                    const VMStateField *field,
+                    JSONWriter *vmdesc, Error **errp)
 {
     ARMCPU *cpu = opaque;
     CPUARMState *env = &cpu->env;
 
     qemu_put_be64(f, vfp_get_fpsr(env));
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_fpsr = {
     .name = "fpsr",
-    .get = get_fpsr,
-    .put = put_fpsr,
+    .load = load_fpsr,
+    .save = save_fpsr,
 };
 
 static const VMStateDescription vmstate_vfp_fpcr_fpsr = {
@@ -755,8 +758,8 @@ static const VMStateDescription vmstate_m_security = {
     }
 };
 
-static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
-                    const VMStateField *field)
+static bool load_cpsr(QEMUFile *f, void *opaque, size_t size,
+                    const VMStateField *field, Error **errp)
 {
     ARMCPU *cpu = opaque;
     CPUARMState *env = &cpu->env;
@@ -797,22 +800,22 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
         }
         /* Ignore the low bits, they are handled by vmstate_m. */
         xpsr_write(env, val, ~XPSR_EXCP);
-        return 0;
+        return true;
     }
 
     env->aarch64 = ((val & PSTATE_nRW) == 0);
 
     if (is_a64(env)) {
         pstate_write(env, val);
-        return 0;
+        return true;
     }
 
     cpsr_write(env, val, 0xffffffff, CPSRWriteRaw);
-    return 0;
+    return true;
 }
 
-static int put_cpsr(QEMUFile *f, void *opaque, size_t size,
-                    const VMStateField *field, JSONWriter *vmdesc)
+static bool save_cpsr(QEMUFile *f, void *opaque, size_t size,
+                    const VMStateField *field, JSONWriter *vmdesc, Error **errp)
 {
     ARMCPU *cpu = opaque;
     CPUARMState *env = &cpu->env;
@@ -828,17 +831,17 @@ static int put_cpsr(QEMUFile *f, void *opaque, size_t size,
     }
 
     qemu_put_be32(f, val);
-    return 0;
+    return true;
 }
 
 static const VMStateInfo vmstate_cpsr = {
     .name = "cpsr",
-    .get = get_cpsr,
-    .put = put_cpsr,
+    .load = load_cpsr,
+    .save = save_cpsr,
 };
 
-static int get_pstate64(QEMUFile *f, void *opaque, size_t size,
-                        const VMStateField *field)
+static bool load_pstate64(QEMUFile *f, void *opaque, size_t size,
+                        const VMStateField *field, Error **errp)
 {
     ARMCPU *cpu = opaque;
     CPUARMState *env = &cpu->env;
@@ -850,11 +853,12 @@ static int get_pstate64(QEMUFile *f, void *opaque, size_t size,
     } else {
         cpsr_write_from_spsr_elx(env, val);
     }
-    return 0;
+    return true;
 }
 
-static int put_pstate64(QEMUFile *f, void *opaque, size_t size,
-                        const VMStateField *field, JSONWriter *vmdesc)
+static bool save_pstate64(QEMUFile *f, void *opaque, size_t size,
+                         const VMStateField *field,
+                         JSONWriter *vmdesc, Error **errp)
 {
     ARMCPU *cpu = opaque;
     CPUARMState *env = &cpu->env;
@@ -866,7 +870,7 @@ static int put_pstate64(QEMUFile *f, void *opaque, size_t size,
         val = cpsr_read_for_spsr_elx(env);
     }
     qemu_put_be64(f, val);
-    return 0;
+    return true;
 }
 
 static bool pstate64_needed(void *opaque)
@@ -901,8 +905,8 @@ static const VMStateDescription vmstate_pstate64 = {
             .size = sizeof(uint64_t),
             .info = &(const VMStateInfo) {
                 .name = "pstate64",
-                .get = get_pstate64,
-                .put = put_pstate64,
+                .load = load_pstate64,
+                .save = save_pstate64,
             },
             .flags = VMS_SINGLE,
             .offset = 0,
@@ -911,17 +915,17 @@ static const VMStateDescription vmstate_pstate64 = {
     },
 };
 
-static int get_power(QEMUFile *f, void *opaque, size_t size,
-                    const VMStateField *field)
+static bool load_power(QEMUFile *f, void *opaque, size_t size,
+                    const VMStateField *field, Error **errp)
 {
     ARMCPU *cpu = opaque;
     bool powered_off = qemu_get_byte(f);
     arm_set_cpu_power_state(cpu, powered_off ? PSCI_OFF : PSCI_ON);
-    return 0;
+    return true;
 }
 
-static int put_power(QEMUFile *f, void *opaque, size_t size,
-                    const VMStateField *field, JSONWriter *vmdesc)
+static bool save_power(QEMUFile *f, void *opaque, size_t size,
+                    const VMStateField *field, JSONWriter *vmdesc, Error **errp)
 {
     ARMCPU *cpu = opaque;
 
@@ -931,16 +935,17 @@ static int put_power(QEMUFile *f, void *opaque, size_t size,
         cpu->power_state == PSCI_OFF) {
         bool powered_off = (cpu->power_state == PSCI_OFF) ? true : false;
         qemu_put_byte(f, powered_off);
-        return 0;
+        return true;
     } else {
-        return 1;
+        error_setg(errp, "Migration should not happen during power transition");
+        return false;
     }
 }
 
 static const VMStateInfo vmstate_powered_off = {
     .name = "powered_off",
-    .get = get_power,
-    .put = put_power,
+    .load = load_power,
+    .save = save_power,
 };
 
 static bool syndrome64_needed(void *opaque)
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 28/30] migration/vmstate-types: convert vmstate_info_g_byte_array to new APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (26 preceding siblings ...)
  2026-08-25 21:38 ` [PATCH 27/30] arm/machine: " Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:38 ` Vladimir Sementsov-Ogievskiy
  2026-09-03 17:41   ` Fabiano Rosas
  2026-08-25 21:38 ` [PATCH 29/30] migration: VMStateInfo: remove old .get / .set handlers Vladimir Sementsov-Ogievskiy
                   ` (2 subsequent siblings)
  30 siblings, 1 reply; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:38 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 migration/vmstate-types.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/migration/vmstate-types.c b/migration/vmstate-types.c
index 8c01215c251..c2d4645f317 100644
--- a/migration/vmstate-types.c
+++ b/migration/vmstate-types.c
@@ -925,30 +925,31 @@ const VMStateInfo vmstate_info_qlist = {
     .save = save_qlist,
 };
 
-static int get_g_byte_array(QEMUFile *f, void *pv, size_t size,
-                            const VMStateField *field)
+static bool load_g_byte_array(QEMUFile *f, void *pv, size_t size,
+                              const VMStateField *field, Error **errp)
 {
     GByteArray *byte_array = *(GByteArray **)pv;
     uint32_t len = qemu_get_be32(f);
 
     g_byte_array_set_size(byte_array, len);
     qemu_get_buffer(f, byte_array->data, len);
-    return 0;
+    return true;
 }
 
-static int put_g_byte_array(QEMUFile *f, void *pv, size_t size,
-                            const VMStateField *field, JSONWriter *vmdesc)
+static bool save_g_byte_array(QEMUFile *f, void *pv, size_t size,
+                              const VMStateField *field, JSONWriter *vmdesc,
+                              Error **errp)
 {
     GByteArray *byte_array = *(GByteArray **)pv;
 
     qemu_put_be32(f, byte_array->len);
     qemu_put_buffer(f, byte_array->data, byte_array->len);
 
-    return 0;
+    return true;
 }
 
 const VMStateInfo vmstate_info_g_byte_array = {
     .name = "GByteArray",
-    .get  = get_g_byte_array,
-    .put  = put_g_byte_array,
+    .load = load_g_byte_array,
+    .save = save_g_byte_array,
 };
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 29/30] migration: VMStateInfo: remove old .get / .set handlers
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (27 preceding siblings ...)
  2026-08-25 21:38 ` [PATCH 28/30] migration/vmstate-types: convert vmstate_info_g_byte_array to new APIs Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:38 ` Vladimir Sementsov-Ogievskiy
  2026-08-25 21:38 ` [PATCH 30/30] migration: finally drop vmstate_save/load_state() functions Vladimir Sementsov-Ogievskiy
  2026-09-22 12:03 ` [PATCH 00/30] move to new migration APIs Fabiano Rosas
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:38 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov

They are unused now.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 include/migration/vmstate.h |  8 --------
 migration/vmstate.c         | 20 ++------------------
 2 files changed, 2 insertions(+), 26 deletions(-)

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 1b7f295417e..5e53440115e 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -39,17 +39,9 @@ typedef struct VMStateField VMStateField;
  * these two parameters should only be used in cases when customized
  * handling is needed, such as QTAILQ. For primitive data types such as
  * integer, field and vmdesc parameters should be ignored inside load/save.
- *
- * @get and @put are deprecated copies of @load and @save. For new interfaces
- * use @load and @save.
  */
 struct VMStateInfo {
     const char *name;
-    int coroutine_mixed_fn (*get)(QEMUFile *f, void *pv, size_t size,
-                                  const VMStateField *field);
-    int coroutine_mixed_fn (*put)(QEMUFile *f, void *pv, size_t size,
-                                  const VMStateField *field,
-                                  JSONWriter *vmdesc);
     bool coroutine_mixed_fn (*load)(QEMUFile *f, void *pv, size_t size,
                                     const VMStateField *field,
                                     Error **errp);
diff --git a/migration/vmstate.c b/migration/vmstate.c
index 50ebe378452..a4cf9214d54 100644
--- a/migration/vmstate.c
+++ b/migration/vmstate.c
@@ -189,18 +189,9 @@ static bool vmstate_load_field(QEMUFile *f, void *pv, size_t size,
     } else if (field->flags & VMS_VSTRUCT) {
         return vmstate_load_vmsd(f, field->vmsd, pv, field->struct_version_id,
                                  errp);
-    } else if (field->info->load) {
-        return field->info->load(f, pv, size, field, errp);
     }
 
-    if (field->info->get(f, pv, size, field) < 0) {
-        error_setg(errp,
-                   "Failed to load element of type %s for %s",
-                   field->info->name, field->name);
-        return false;
-    }
-
-    return true;
+    return field->info->load(f, pv, size, field, errp);
 }
 
 static bool vmstate_post_load(const VMStateDescription *vmsd,
@@ -583,16 +574,9 @@ static bool vmstate_save_field(QEMUFile *f, void *pv, size_t size,
     } else if (field->flags & VMS_VSTRUCT) {
         return vmstate_save_vmsd_v(f, field->vmsd, pv, vmdesc,
                                    field->struct_version_id, errp);
-    } else if (field->info->save) {
-        return field->info->save(f, pv, size, field, vmdesc, errp);
     }
 
-    if (field->info->put(f, pv, size, field, vmdesc) < 0) {
-        error_setg(errp, "put failed");
-        return false;
-    }
-
-    return true;
+    return field->info->save(f, pv, size, field, vmdesc, errp);
 }
 
 /*
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 30/30] migration: finally drop vmstate_save/load_state() functions
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (28 preceding siblings ...)
  2026-08-25 21:38 ` [PATCH 29/30] migration: VMStateInfo: remove old .get / .set handlers Vladimir Sementsov-Ogievskiy
@ 2026-08-25 21:38 ` Vladimir Sementsov-Ogievskiy
  2026-09-22 12:03 ` [PATCH 00/30] move to new migration APIs Fabiano Rosas
  30 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-25 21:38 UTC (permalink / raw)
  To: peterx; +Cc: farosas, qemu-devel, vsementsov

Now they are unused.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 include/migration/vmstate.h |  9 ---------
 migration/vmstate.c         | 12 ------------
 2 files changed, 21 deletions(-)

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 5e53440115e..b86386f14a9 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -1307,15 +1307,6 @@ extern const VMStateInfo vmstate_info_g_byte_array;
         .flags = VMS_END, \
     }
 
-/*
- * vmstate_load_state() and vmstate_save_state() are
- * depreacated, use vmstate_load_vmsd() and vmstate_save_vmsd()
- * instead.
- */
-int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
-                       void *opaque, int version_id, Error **errp);
-int vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
-                       void *opaque, JSONWriter *vmdesc, Error **errp);
 bool vmstate_load_vmsd(QEMUFile *f, const VMStateDescription *vmsd,
                        void *opaque, int version_id, Error **errp);
 bool vmstate_save_vmsd(QEMUFile *f, const VMStateDescription *vmsd,
diff --git a/migration/vmstate.c b/migration/vmstate.c
index a4cf9214d54..f8424234118 100644
--- a/migration/vmstate.c
+++ b/migration/vmstate.c
@@ -880,15 +880,3 @@ static bool vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
 
     return true;
 }
-
-int vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
-                       void *opaque, JSONWriter *vmdesc_id, Error **errp)
-{
-    return vmstate_save_vmsd(f, vmsd, opaque, vmdesc_id, errp) ? 0 : -EINVAL;
-}
-
-int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
-                        void *opaque, int version_id, Error **errp)
-{
-    return vmstate_load_vmsd(f, vmsd, opaque, version_id, errp) ? 0 : -EINVAL;
-}
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH 01/30] tests/unit/test-vmstate: move to new migration APIs
  2026-08-25 21:37 ` [PATCH 01/30] tests/unit/test-vmstate: " Vladimir Sementsov-Ogievskiy
@ 2026-08-29  5:55   ` Akihiko Odaki
  2026-09-03 17:12   ` Fabiano Rosas
  1 sibling, 0 replies; 40+ messages in thread
From: Akihiko Odaki @ 2026-08-29  5:55 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, peterx
  Cc: farosas, qemu-devel, Juraj Marcin, Alexander Mikhalitsyn

On 2026/08/26 6:37, Vladimir Sementsov-Ogievskiy wrote:
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>

Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>

Regards,
Akihiko Odaki


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 14/30] hw/display/virtio-gpu: move to new migration APIs
  2026-08-25 21:37 ` [PATCH 14/30] hw/display/virtio-gpu: move to " Vladimir Sementsov-Ogievskiy
@ 2026-08-29  6:54   ` Akihiko Odaki
  2026-08-29 19:30     ` Vladimir Sementsov-Ogievskiy
  0 siblings, 1 reply; 40+ messages in thread
From: Akihiko Odaki @ 2026-08-29  6:54 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, peterx
  Cc: farosas, qemu-devel, Michael S. Tsirkin, Alex Bennée,
	Dmitry Osipenko

On 2026/08/26 6:37, Vladimir Sementsov-Ogievskiy wrote:
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> ---
>   hw/display/virtio-gpu.c | 99 ++++++++++++++++++++++-------------------
>   1 file changed, 52 insertions(+), 47 deletions(-)
> 
> diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> index fbb6fec7a0a..1af640accdc 100644
> --- a/hw/display/virtio-gpu.c
> +++ b/hw/display/virtio-gpu.c
> @@ -1308,13 +1308,13 @@ static const VMStateDescription vmstate_virtio_gpu_scanouts = {
>       },
>   };
>   
> -static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
> -                           const VMStateField *field, JSONWriter *vmdesc)
> +static bool virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
> +                            const VMStateField *field, JSONWriter *vmdesc,
> +                            Error **errp)
>   {
>       VirtIOGPU *g = opaque;
>       struct virtio_gpu_simple_resource *res;
> -    Error *err = NULL;
> -    int i, ret;
> +    int i;
>   
>       /* in 2d mode we should never find unprocessed commands here */
>       assert(QTAILQ_EMPTY(&g->cmdq));
> @@ -1337,12 +1337,7 @@ static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
>       }
>       qemu_put_be32(f, 0); /* end of list */
>   
> -    ret = vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL,
> -                             &err);
> -    if (ret < 0) {
> -        error_report_err(err);
> -    }
> -    return ret;
> +    return vmstate_save_vmsd(f, &vmstate_virtio_gpu_scanouts, g, NULL, errp);
>   }
>   
>   static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
> @@ -1374,14 +1369,13 @@ static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
>       return true;
>   }
>   
> -static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
> -                           const VMStateField *field)
> +static bool virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
> +                            const VMStateField *field, Error **errp)
>   {
>       VirtIOGPU *g = opaque;
> -    Error *err = NULL;
>       struct virtio_gpu_simple_resource *res;
>       uint32_t resource_id, pformat, hostmem, rowstride_bytes;
> -    int i, ret;
> +    int i;
>   
>       g->hostmem = 0;
>   
> @@ -1389,7 +1383,8 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
>       while (resource_id != 0) {
>           res = virtio_gpu_find_resource(g, resource_id);
>           if (res) {
> -            return -EINVAL;
> +            error_setg(errp, "Failed to find resource %" PRIu32, resource_id);
> +            return false;
>           }
>   
>           res = g_new0(struct virtio_gpu_simple_resource, 1);
> @@ -1402,14 +1397,16 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
>           /* allocate */
>           pformat = virtio_gpu_get_pixman_format(res->format);
>           if (!pformat) {
> +            error_setg(errp, "Unknown pixman format %" PRIu32, res->format);
>               g_free(res);
> -            return -EINVAL;
> +            return false;
>           }
>   
>           if (!calc_image_hostmem(pformat, res->width, res->height,
>                                   &hostmem, &rowstride_bytes)) {
>               g_free(res);
> -            return -EINVAL;
> +            error_setg(errp, "Failed to calculate image hostmem");
> +            return false;
>           }
>           res->hostmem = hostmem;
>           if (!qemu_pixman_image_new_shareable(&res->image,
> @@ -1419,10 +1416,9 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
>                                                res->width,
>                                                res->height,
>                                                rowstride_bytes,
> -                                             &err)) {
> -            warn_report_err(err);
> +                                             errp)) {
>               g_free(res);
> -            return -EINVAL;
> +            return false;
>           }
>   
>           res->addrs = g_try_new(uint64_t, res->iov_cnt);
> @@ -1432,7 +1428,8 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
>               g_free(res->addrs);
>               g_free(res->iov);
>               g_free(res);
> -            return -EINVAL;
> +            error_setg(errp, "Failed to allocate iov arrays");
> +            return false;
>           }
>   
>           /* read data */
> @@ -1446,22 +1443,20 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
>           if (!virtio_gpu_load_restore_mapping(g, res)) {
>               pixman_image_unref(res->image);
>               g_free(res);
> -            return -EINVAL;
> +            error_setg(errp, "Failed to load restore mapping");
> +            return false;
>           }
>   
>           resource_id = qemu_get_be32(f);
>       }
>   
>       /* load & apply scanout state */
> -    ret = vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1, &err);
> -    if (ret < 0) {
> -        error_report_err(err);
> -    }
> -    return ret;
> +    return vmstate_load_vmsd(f, &vmstate_virtio_gpu_scanouts, g, 1, errp);
>   }
>   
> -static int virtio_gpu_blob_save(QEMUFile *f, void *opaque, size_t size,
> -                                const VMStateField *field, JSONWriter *vmdesc)
> +static bool virtio_gpu_blob_save(QEMUFile *f, void *opaque, size_t size,
> +                                 const VMStateField *field, JSONWriter *vmdesc,
> +                                 Error **errp)
>   {
>       VirtIOGPU *g = opaque;
>       struct virtio_gpu_simple_resource *res;
> @@ -1485,11 +1480,11 @@ static int virtio_gpu_blob_save(QEMUFile *f, void *opaque, size_t size,
>       }
>       qemu_put_be32(f, 0); /* end of list */
>   
> -    return 0;
> +    return true;
>   }
>   
> -static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
> -                                const VMStateField *field)
> +static bool virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
> +                                 const VMStateField *field, Error **errp)
>   {
>       VirtIOGPU *g = opaque;
>       struct virtio_gpu_simple_resource *res;
> @@ -1500,7 +1495,8 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
>       while (resource_id != 0) {
>           res = virtio_gpu_find_resource(g, resource_id);
>           if (res) {
> -            return -EINVAL;
> +            error_setg(errp, "Failed to find resource %" PRIu32, resource_id);
> +            return false;
>           }
>   
>           res = g_new0(struct virtio_gpu_simple_resource, 1);
> @@ -1514,7 +1510,8 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
>               g_free(res->addrs);
>               g_free(res->iov);
>               g_free(res);
> -            return -EINVAL;
> +            error_setg(errp, "Failed to allocate iov arrays");
> +            return false;
>           }
>   
>           /* read data */
> @@ -1525,15 +1522,19 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
>   
>           if (res->iov_cnt > 0 &&
>               iov_size(res->iov, res->iov_cnt) < res->blob_size) {
> +            error_setg(errp, "iov size %" PRIu64 " < blob_size %" PRIu64,
> +                       (uint64_t)iov_size(res->iov, res->iov_cnt),

nitpick: I somewhat prefer:

             error_setg(errp, "iov size %zu < blob_size %" PRIu64,
                        iov_size(res->iov, res->iov_cnt),

because:

- it does not require thinking about the cast. The conditional above
   does perform implicit cast, but it automatically picks the wider type.
   The explicit cast here doesn't so requires a little more thought.

- it requries less typing.

And this hunk cannot be applied due to recent virtio-gpu fixes. Please 
rebase it.

> +                       res->blob_size);
>               g_free(res->addrs);
>               g_free(res->iov);
>               g_free(res);
> -            return -EINVAL;
> +            return false;
>           }
>   
>           if (!virtio_gpu_load_restore_mapping(g, res)) {
>               g_free(res);
> -            return -EINVAL;
> +            error_setg(errp, "Failed to load restore mapping");

Let's say: "Failed to restore loaded mapping"

> +            return false;
>           }
>   
>           virtio_gpu_init_udmabuf(res);
> @@ -1541,10 +1542,10 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
>           resource_id = qemu_get_be32(f);
>       }
>   
> -    return 0;
> +    return true;
>   }
>   
> -static int virtio_gpu_post_load(void *opaque, int version_id)
> +static bool virtio_gpu_post_load(void *opaque, int version_id, Error **errp)
>   {
>       VirtIOGPU *g = opaque;
>       struct virtio_gpu_scanout *scanout;
> @@ -1559,7 +1560,9 @@ static int virtio_gpu_post_load(void *opaque, int version_id)
>   
>           res = virtio_gpu_find_resource(g, scanout->resource_id);
>           if (!res) {
> -            return -EINVAL;
> +            error_setg(errp, "Failed to find resource %" PRIu32,
> +                       scanout->resource_id);
> +            return false;
>           }
>   
>           if (scanout->fb.format != 0) {
> @@ -1572,12 +1575,14 @@ static int virtio_gpu_post_load(void *opaque, int version_id)
>               };
>   
>               if (!virtio_gpu_do_set_scanout(g, i, &scanout->fb, res, &r, &error)) {
> -                return -EINVAL;
> +                error_setg(errp, "Failed to set scanout");
> +                return false;
>               }
>           } else {
>               /* legacy v1 migration support */
>               if (!res->image) {
> -                return -EINVAL;
> +                error_setg(errp, "No image");

Let's say: "A blob scanout lacks metadata".

Regards,
Akihiko Odaki

> +                return false;
>               }
>               scanout->ds = qemu_create_displaysurface_pixman(res->image);
>               qemu_displaysurface_set_share_handle(scanout->ds, res->share_handle, 0);
> @@ -1591,7 +1596,7 @@ static int virtio_gpu_post_load(void *opaque, int version_id)
>           res->scanout_bitmask |= (1 << i);
>       }
>   
> -    return 0;
> +    return true;
>   }
>   
>   void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
> @@ -1777,8 +1782,8 @@ const VMStateDescription vmstate_virtio_gpu_blob_state = {
>               .name = "virtio-gpu/blob",
>               .info = &(const VMStateInfo) {
>                   .name = "blob",
> -                .get = virtio_gpu_blob_load,
> -                .put = virtio_gpu_blob_save,
> +                .load = virtio_gpu_blob_load,
> +                .save = virtio_gpu_blob_save,
>               },
>               .flags = VMS_SINGLE,
>           } /* device */,
> @@ -1804,8 +1809,8 @@ static const VMStateDescription vmstate_virtio_gpu = {
>               .name = "virtio-gpu",
>               .info = &(const VMStateInfo) {
>                           .name = "virtio-gpu",
> -                        .get = virtio_gpu_load,
> -                        .put = virtio_gpu_save,
> +                        .load = virtio_gpu_load,
> +                        .save = virtio_gpu_save,
>               },
>               .flags = VMS_SINGLE,
>           } /* device */,
> @@ -1815,7 +1820,7 @@ static const VMStateDescription vmstate_virtio_gpu = {
>           &vmstate_virtio_gpu_blob_state,
>           NULL
>       },
> -    .post_load = virtio_gpu_post_load,
> +    .post_load_errp = virtio_gpu_post_load,
>   };
>   
>   static const Property virtio_gpu_properties[] = {



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 14/30] hw/display/virtio-gpu: move to new migration APIs
  2026-08-29  6:54   ` Akihiko Odaki
@ 2026-08-29 19:30     ` Vladimir Sementsov-Ogievskiy
  0 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-08-29 19:30 UTC (permalink / raw)
  To: Akihiko Odaki, peterx
  Cc: farosas, qemu-devel, Michael S. Tsirkin, Alex Bennée,
	Dmitry Osipenko

On 29.08.26 09:54, Akihiko Odaki wrote:
> On 2026/08/26 6:37, Vladimir Sementsov-Ogievskiy wrote:
>> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
>> ---
>>   hw/display/virtio-gpu.c | 99 ++++++++++++++++++++++-------------------
>>   1 file changed, 52 insertions(+), 47 deletions(-)
>>
>> diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
>> index fbb6fec7a0a..1af640accdc 100644
>> --- a/hw/display/virtio-gpu.c
>> +++ b/hw/display/virtio-gpu.c
>> @@ -1308,13 +1308,13 @@ static const VMStateDescription vmstate_virtio_gpu_scanouts = {
>>       },
>>   };
>> -static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
>> -                           const VMStateField *field, JSONWriter *vmdesc)
>> +static bool virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
>> +                            const VMStateField *field, JSONWriter *vmdesc,
>> +                            Error **errp)
>>   {
>>       VirtIOGPU *g = opaque;
>>       struct virtio_gpu_simple_resource *res;
>> -    Error *err = NULL;
>> -    int i, ret;
>> +    int i;
>>       /* in 2d mode we should never find unprocessed commands here */
>>       assert(QTAILQ_EMPTY(&g->cmdq));
>> @@ -1337,12 +1337,7 @@ static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
>>       }
>>       qemu_put_be32(f, 0); /* end of list */
>> -    ret = vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL,
>> -                             &err);
>> -    if (ret < 0) {
>> -        error_report_err(err);
>> -    }
>> -    return ret;
>> +    return vmstate_save_vmsd(f, &vmstate_virtio_gpu_scanouts, g, NULL, errp);
>>   }
>>   static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
>> @@ -1374,14 +1369,13 @@ static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
>>       return true;
>>   }
>> -static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
>> -                           const VMStateField *field)
>> +static bool virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
>> +                            const VMStateField *field, Error **errp)
>>   {
>>       VirtIOGPU *g = opaque;
>> -    Error *err = NULL;
>>       struct virtio_gpu_simple_resource *res;
>>       uint32_t resource_id, pformat, hostmem, rowstride_bytes;
>> -    int i, ret;
>> +    int i;
>>       g->hostmem = 0;
>> @@ -1389,7 +1383,8 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
>>       while (resource_id != 0) {
>>           res = virtio_gpu_find_resource(g, resource_id);
>>           if (res) {
>> -            return -EINVAL;
>> +            error_setg(errp, "Failed to find resource %" PRIu32, resource_id);
>> +            return false;
>>           }
>>           res = g_new0(struct virtio_gpu_simple_resource, 1);
>> @@ -1402,14 +1397,16 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
>>           /* allocate */
>>           pformat = virtio_gpu_get_pixman_format(res->format);
>>           if (!pformat) {
>> +            error_setg(errp, "Unknown pixman format %" PRIu32, res->format);
>>               g_free(res);
>> -            return -EINVAL;
>> +            return false;
>>           }
>>           if (!calc_image_hostmem(pformat, res->width, res->height,
>>                                   &hostmem, &rowstride_bytes)) {
>>               g_free(res);
>> -            return -EINVAL;
>> +            error_setg(errp, "Failed to calculate image hostmem");
>> +            return false;
>>           }
>>           res->hostmem = hostmem;
>>           if (!qemu_pixman_image_new_shareable(&res->image,
>> @@ -1419,10 +1416,9 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
>>                                                res->width,
>>                                                res->height,
>>                                                rowstride_bytes,
>> -                                             &err)) {
>> -            warn_report_err(err);
>> +                                             errp)) {
>>               g_free(res);
>> -            return -EINVAL;
>> +            return false;
>>           }
>>           res->addrs = g_try_new(uint64_t, res->iov_cnt);
>> @@ -1432,7 +1428,8 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
>>               g_free(res->addrs);
>>               g_free(res->iov);
>>               g_free(res);
>> -            return -EINVAL;
>> +            error_setg(errp, "Failed to allocate iov arrays");
>> +            return false;
>>           }
>>           /* read data */
>> @@ -1446,22 +1443,20 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
>>           if (!virtio_gpu_load_restore_mapping(g, res)) {
>>               pixman_image_unref(res->image);
>>               g_free(res);
>> -            return -EINVAL;
>> +            error_setg(errp, "Failed to load restore mapping");
>> +            return false;
>>           }
>>           resource_id = qemu_get_be32(f);
>>       }
>>       /* load & apply scanout state */
>> -    ret = vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1, &err);
>> -    if (ret < 0) {
>> -        error_report_err(err);
>> -    }
>> -    return ret;
>> +    return vmstate_load_vmsd(f, &vmstate_virtio_gpu_scanouts, g, 1, errp);
>>   }
>> -static int virtio_gpu_blob_save(QEMUFile *f, void *opaque, size_t size,
>> -                                const VMStateField *field, JSONWriter *vmdesc)
>> +static bool virtio_gpu_blob_save(QEMUFile *f, void *opaque, size_t size,
>> +                                 const VMStateField *field, JSONWriter *vmdesc,
>> +                                 Error **errp)
>>   {
>>       VirtIOGPU *g = opaque;
>>       struct virtio_gpu_simple_resource *res;
>> @@ -1485,11 +1480,11 @@ static int virtio_gpu_blob_save(QEMUFile *f, void *opaque, size_t size,
>>       }
>>       qemu_put_be32(f, 0); /* end of list */
>> -    return 0;
>> +    return true;
>>   }
>> -static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
>> -                                const VMStateField *field)
>> +static bool virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
>> +                                 const VMStateField *field, Error **errp)
>>   {
>>       VirtIOGPU *g = opaque;
>>       struct virtio_gpu_simple_resource *res;
>> @@ -1500,7 +1495,8 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
>>       while (resource_id != 0) {
>>           res = virtio_gpu_find_resource(g, resource_id);
>>           if (res) {
>> -            return -EINVAL;
>> +            error_setg(errp, "Failed to find resource %" PRIu32, resource_id);
>> +            return false;
>>           }
>>           res = g_new0(struct virtio_gpu_simple_resource, 1);
>> @@ -1514,7 +1510,8 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
>>               g_free(res->addrs);
>>               g_free(res->iov);
>>               g_free(res);
>> -            return -EINVAL;
>> +            error_setg(errp, "Failed to allocate iov arrays");
>> +            return false;
>>           }
>>           /* read data */
>> @@ -1525,15 +1522,19 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
>>           if (res->iov_cnt > 0 &&
>>               iov_size(res->iov, res->iov_cnt) < res->blob_size) {
>> +            error_setg(errp, "iov size %" PRIu64 " < blob_size %" PRIu64,
>> +                       (uint64_t)iov_size(res->iov, res->iov_cnt),
> 
> nitpick: I somewhat prefer:
> 
>              error_setg(errp, "iov size %zu < blob_size %" PRIu64,
>                         iov_size(res->iov, res->iov_cnt),
> 
> because:
> 
> - it does not require thinking about the cast. The conditional above
>    does perform implicit cast, but it automatically picks the wider type.
>    The explicit cast here doesn't so requires a little more thought.
> 
> - it requries less typing.
> 
> And this hunk cannot be applied due to recent virtio-gpu fixes. Please rebase it.
> 
>> +                       res->blob_size);
>>               g_free(res->addrs);
>>               g_free(res->iov);
>>               g_free(res);
>> -            return -EINVAL;
>> +            return false;
>>           }
>>           if (!virtio_gpu_load_restore_mapping(g, res)) {
>>               g_free(res);
>> -            return -EINVAL;
>> +            error_setg(errp, "Failed to load restore mapping");
> 
> Let's say: "Failed to restore loaded mapping"
> 
>> +            return false;
>>           }
>>           virtio_gpu_init_udmabuf(res);
>> @@ -1541,10 +1542,10 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
>>           resource_id = qemu_get_be32(f);
>>       }
>> -    return 0;
>> +    return true;
>>   }
>> -static int virtio_gpu_post_load(void *opaque, int version_id)
>> +static bool virtio_gpu_post_load(void *opaque, int version_id, Error **errp)
>>   {
>>       VirtIOGPU *g = opaque;
>>       struct virtio_gpu_scanout *scanout;
>> @@ -1559,7 +1560,9 @@ static int virtio_gpu_post_load(void *opaque, int version_id)
>>           res = virtio_gpu_find_resource(g, scanout->resource_id);
>>           if (!res) {
>> -            return -EINVAL;
>> +            error_setg(errp, "Failed to find resource %" PRIu32,
>> +                       scanout->resource_id);
>> +            return false;
>>           }
>>           if (scanout->fb.format != 0) {
>> @@ -1572,12 +1575,14 @@ static int virtio_gpu_post_load(void *opaque, int version_id)
>>               };
>>               if (!virtio_gpu_do_set_scanout(g, i, &scanout->fb, res, &r, &error)) {
>> -                return -EINVAL;
>> +                error_setg(errp, "Failed to set scanout");
>> +                return false;
>>               }
>>           } else {
>>               /* legacy v1 migration support */
>>               if (!res->image) {
>> -                return -EINVAL;
>> +                error_setg(errp, "No image");
> 
> Let's say: "A blob scanout lacks metadata".
> 
> Regards,
> Akihiko Odaki

Thanks for reviewing! Will apply all suggestions in v2.


-- 
Best regards,
Vladimir


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 01/30] tests/unit/test-vmstate: move to new migration APIs
  2026-08-25 21:37 ` [PATCH 01/30] tests/unit/test-vmstate: " Vladimir Sementsov-Ogievskiy
  2026-08-29  5:55   ` Akihiko Odaki
@ 2026-09-03 17:12   ` Fabiano Rosas
  1 sibling, 0 replies; 40+ messages in thread
From: Fabiano Rosas @ 2026-09-03 17:12 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, peterx
  Cc: qemu-devel, vsementsov, Juraj Marcin, Alexander Mikhalitsyn,
	Akihiko Odaki

Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> writes:

> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> ---
>  tests/unit/test-vmstate.c | 118 ++++++++++----------------------------
>  1 file changed, 30 insertions(+), 88 deletions(-)
>
> diff --git a/tests/unit/test-vmstate.c b/tests/unit/test-vmstate.c
> index df1fb4c7780..23f31730703 100644
> --- a/tests/unit/test-vmstate.c
> +++ b/tests/unit/test-vmstate.c
> @@ -67,14 +67,9 @@ static QEMUFile *open_test_file(bool write)
>  static void save_vmstate(const VMStateDescription *desc, void *obj)
>  {
>      QEMUFile *f = open_test_file(true);
> -    Error *local_err = NULL;
>  
>      /* Save file with vmstate */
> -    int ret = vmstate_save_state(f, desc, obj, NULL, &local_err);
> -    if (ret) {
> -        error_report_err(local_err);
> -    }
> -    g_assert(!ret);
> +    vmstate_save_vmsd(f, desc, obj, NULL, &error_abort);
>      qemu_put_byte(f, QEMU_VM_EOF);
>      g_assert(!qemu_file_get_error(f));
>      qemu_fclose(f);
> @@ -112,7 +107,6 @@ static int load_vmstate_one(const VMStateDescription *desc, void *obj,
>                              int version, const uint8_t *wire, size_t size)
>  {
>      QEMUFile *f;
> -    int ret;
>      Error *local_err = NULL;
>  
>      f = open_test_file(true);
> @@ -120,15 +114,16 @@ static int load_vmstate_one(const VMStateDescription *desc, void *obj,
>      qemu_fclose(f);
>  
>      f = open_test_file(false);
> -    ret = vmstate_load_state(f, desc, obj, version, &local_err);
> -    if (ret) {
> +    if (!vmstate_load_vmsd(f, desc, obj, version, &local_err)) {
>          error_report_err(local_err);
>          g_assert(qemu_file_get_error(f));
> -    } else{
> -        g_assert(!qemu_file_get_error(f));
> +        qemu_fclose(f);
> +        return -EINVAL;
>      }
> +
> +    g_assert(!qemu_file_get_error(f));
>      qemu_fclose(f);
> -    return ret;
> +    return 0;
>  }
>  
>  
> @@ -362,8 +357,6 @@ static const VMStateDescription vmstate_versioned = {
>  
>  static void test_load_v1(void)
>  {
> -    Error *local_err = NULL;
> -    int ret;
>      uint8_t buf[] = {
>          0, 0, 0, 10,             /* a */
>          0, 0, 0, 30,             /* c */
> @@ -374,10 +367,7 @@ static void test_load_v1(void)
>  
>      QEMUFile *loading = open_test_file(false);
>      TestStruct obj = { .b = 200, .e = 500, .f = 600 };
> -    ret = vmstate_load_state(loading, &vmstate_versioned, &obj, 1, &local_err);
> -    if (ret < 0) {
> -        error_report_err(local_err);
> -    }
> +    vmstate_load_vmsd(loading, &vmstate_versioned, &obj, 1, &error_abort);
>      g_assert(!qemu_file_get_error(loading));
>      g_assert_cmpint(obj.a, ==, 10);
>      g_assert_cmpint(obj.b, ==, 200);
> @@ -390,8 +380,6 @@ static void test_load_v1(void)
>  
>  static void test_load_v2(void)
>  {
> -    Error *local_err = NULL;
> -    int ret;
>      uint8_t buf[] = {
>          0, 0, 0, 10,             /* a */
>          0, 0, 0, 20,             /* b */
> @@ -405,10 +393,7 @@ static void test_load_v2(void)
>  
>      QEMUFile *loading = open_test_file(false);
>      TestStruct obj;
> -    ret = vmstate_load_state(loading, &vmstate_versioned, &obj, 2, &local_err);
> -    if (ret < 0) {
> -        error_report_err(local_err);
> -    }
> +    vmstate_load_vmsd(loading, &vmstate_versioned, &obj, 2, &error_abort);
>      g_assert_cmpint(obj.a, ==, 10);
>      g_assert_cmpint(obj.b, ==, 20);
>      g_assert_cmpint(obj.c, ==, 30);
> @@ -442,16 +427,10 @@ static const VMStateDescription vmstate_skipping = {
>  
>  static void test_save_noskip(void)
>  {
> -    Error *local_err = NULL;
>      QEMUFile *fsave = open_test_file(true);
>      TestStruct obj = { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6,
>                         .skip_c_e = false };
> -    int ret = vmstate_save_state(fsave, &vmstate_skipping, &obj, NULL,
> -                                 &local_err);
> -    if (ret) {
> -        error_report_err(local_err);
> -    }
> -    g_assert(!ret);
> +    vmstate_save_vmsd(fsave, &vmstate_skipping, &obj, NULL, &error_abort);
>      g_assert(!qemu_file_get_error(fsave));
>  
>      uint8_t expected[] = {
> @@ -469,16 +448,10 @@ static void test_save_noskip(void)
>  
>  static void test_save_skip(void)
>  {
> -    Error *local_err = NULL;
>      QEMUFile *fsave = open_test_file(true);
>      TestStruct obj = { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6,
>                         .skip_c_e = true };
> -    int ret = vmstate_save_state(fsave, &vmstate_skipping, &obj, NULL,
> -                                 &local_err);
> -    if (ret) {
> -        error_report_err(local_err);
> -    }
> -    g_assert(!ret);
> +    vmstate_save_vmsd(fsave, &vmstate_skipping, &obj, NULL, &error_abort);
>      g_assert(!qemu_file_get_error(fsave));
>  
>      uint8_t expected[] = {
> @@ -494,8 +467,6 @@ static void test_save_skip(void)
>  
>  static void test_load_noskip(void)
>  {
> -    Error *local_err = NULL;
> -    int ret;
>      uint8_t buf[] = {
>          0, 0, 0, 10,             /* a */
>          0, 0, 0, 20,             /* b */
> @@ -509,10 +480,7 @@ static void test_load_noskip(void)
>  
>      QEMUFile *loading = open_test_file(false);
>      TestStruct obj = { .skip_c_e = false };
> -    ret = vmstate_load_state(loading, &vmstate_skipping, &obj, 2, &local_err);
> -    if (ret < 0) {
> -        error_report_err(local_err);
> -    }
> +    vmstate_load_vmsd(loading, &vmstate_skipping, &obj, 2, &error_abort);
>      g_assert(!qemu_file_get_error(loading));
>      g_assert_cmpint(obj.a, ==, 10);
>      g_assert_cmpint(obj.b, ==, 20);
> @@ -525,8 +493,6 @@ static void test_load_noskip(void)
>  
>  static void test_load_skip(void)
>  {
> -    Error *local_err = NULL;
> -    int ret;
>      uint8_t buf[] = {
>          0, 0, 0, 10,             /* a */
>          0, 0, 0, 20,             /* b */
> @@ -538,10 +504,7 @@ static void test_load_skip(void)
>  
>      QEMUFile *loading = open_test_file(false);
>      TestStruct obj = { .skip_c_e = true, .c = 300, .e = 500 };
> -    ret = vmstate_load_state(loading, &vmstate_skipping, &obj, 2, &local_err);
> -    if (ret < 0) {
> -        error_report_err(local_err);
> -    }
> +    vmstate_load_vmsd(loading, &vmstate_skipping, &obj, 2, &error_abort);
>      g_assert(!qemu_file_get_error(loading));
>      g_assert_cmpint(obj.a, ==, 10);
>      g_assert_cmpint(obj.b, ==, 20);
> @@ -863,8 +826,6 @@ static void test_save_q(void)
>  
>  static void test_load_q(void)
>  {
> -    int ret;
> -    Error *local_err = NULL;
>      TestQtailq obj_q = {
>          .i16 = -512,
>          .i32 = 70000,
> @@ -894,10 +855,7 @@ static void test_load_q(void)
>      TestQtailq tgt;
>  
>      QTAILQ_INIT(&tgt.q);
> -    ret = vmstate_load_state(fload, &vmstate_q, &tgt, 1, &local_err);
> -    if (ret < 0) {
> -        error_report_err(local_err);
> -    }
> +    vmstate_load_vmsd(fload, &vmstate_q, &tgt, 1, &error_abort);
>      char eof = qemu_get_byte(fload);
>      g_assert(!qemu_file_get_error(fload));
>      g_assert_cmpint(tgt.i16, ==, obj_q.i16);
> @@ -1015,29 +973,29 @@ static void destroy_domain(gpointer data)
>      g_free(domain);
>  }
>  
> -static int domain_preload(void *opaque)
> +static bool domain_preload(void *opaque, Error **errp)
>  {
>      TestGTreeDomain *domain = opaque;
>  
>      domain->mappings = g_tree_new_full((GCompareDataFunc)interval_cmp,
>                                         NULL, g_free, g_free);
> -    return 0;
> +    return true;
>  }
>  
> -static int iommu_preload(void *opaque)
> +static bool iommu_preload(void *opaque, Error **errp)
>  {
>      TestGTreeIOMMU *iommu = opaque;
>  
>      iommu->domains = g_tree_new_full((GCompareDataFunc)int_cmp,
>                                       NULL, NULL, destroy_domain);
> -    return 0;
> +    return true;
>  }
>  
>  static const VMStateDescription vmstate_domain = {
>      .name = "domain",
>      .version_id = 1,
>      .minimum_version_id = 1,
> -    .pre_load = domain_preload,
> +    .pre_load_errp = domain_preload,
>      .fields = (const VMStateField[]) {
>          VMSTATE_INT32(id, TestGTreeDomain),
>          VMSTATE_GTREE_V(mappings, TestGTreeDomain, 1,
> @@ -1073,7 +1031,7 @@ static const VMStateDescription vmstate_iommu = {
>      .name = "iommu",
>      .version_id = 1,
>      .minimum_version_id = 1,
> -    .pre_load = iommu_preload,
> +    .pre_load_errp = iommu_preload,
>      .fields = (const VMStateField[]) {
>          VMSTATE_INT32(id, TestGTreeIOMMU),
>          VMSTATE_GTREE_DIRECT_KEY_V(domains, TestGTreeIOMMU, 1,
> @@ -1239,8 +1197,6 @@ static void diff_iommu(TestGTreeIOMMU *iommu1, TestGTreeIOMMU *iommu2)
>  
>  static void test_gtree_load_domain(void)
>  {
> -    Error *local_err = NULL;
> -    int ret;
>      TestGTreeDomain *dest_domain = g_new0(TestGTreeDomain, 1);
>      TestGTreeDomain *orig_domain = create_first_domain();
>      QEMUFile *fload, *fsave;
> @@ -1253,11 +1209,7 @@ static void test_gtree_load_domain(void)
>  
>      fload = open_test_file(false);
>  
> -    ret = vmstate_load_state(fload, &vmstate_domain, dest_domain, 1,
> -                             &local_err);
> -    if (ret < 0) {
> -        error_report_err(local_err);
> -    }
> +    vmstate_load_vmsd(fload, &vmstate_domain, dest_domain, 1, &error_abort);
>      eof = qemu_get_byte(fload);
>      g_assert(!qemu_file_get_error(fload));
>      g_assert_cmpint(orig_domain->id, ==, dest_domain->id);
> @@ -1360,8 +1312,6 @@ static void test_gtree_save_iommu(void)
>  
>  static void test_gtree_load_iommu(void)
>  {
> -    Error *local_err = NULL;
> -    int ret;
>      TestGTreeIOMMU *dest_iommu = g_new0(TestGTreeIOMMU, 1);
>      TestGTreeIOMMU *orig_iommu = create_iommu();
>      QEMUFile *fsave, *fload;
> @@ -1373,10 +1323,7 @@ static void test_gtree_load_iommu(void)
>      qemu_fclose(fsave);
>  
>      fload = open_test_file(false);
> -    ret = vmstate_load_state(fload, &vmstate_iommu, dest_iommu, 1, &local_err);
> -    if (ret < 0) {
> -        error_report_err(local_err);
> -    }
> +    vmstate_load_vmsd(fload, &vmstate_iommu, dest_iommu, 1, &error_abort);
>      eof = qemu_get_byte(fload);
>      g_assert(!qemu_file_get_error(fload));
>      g_assert_cmpint(orig_iommu->id, ==, dest_iommu->id);
> @@ -1498,8 +1445,6 @@ static void test_save_qlist(void)
>  
>  static void test_load_qlist(void)
>  {
> -    Error *local_err = NULL;
> -    int ret;
>      QEMUFile *fsave, *fload;
>      TestQListContainer *orig_container = alloc_container();
>      TestQListContainer *dest_container = g_new0(TestQListContainer, 1);
> @@ -1513,11 +1458,8 @@ static void test_load_qlist(void)
>      qemu_fclose(fsave);
>  
>      fload = open_test_file(false);
> -    ret = vmstate_load_state(fload, &vmstate_container, dest_container, 1,
> -                             &local_err);
> -    if (ret < 0) {
> -        error_report_err(local_err);
> -    }
> +    vmstate_load_vmsd(fload, &vmstate_container, dest_container, 1,
> +                      &error_abort);
>      eof = qemu_get_byte(fload);
>      g_assert(!qemu_file_get_error(fload));
>      g_assert_cmpint(eof, ==, QEMU_VM_EOF);
> @@ -1534,22 +1476,22 @@ typedef struct TmpTestStruct {
>      int64_t diff;
>  } TmpTestStruct;
>  
> -static int tmp_child_pre_save(void *opaque)
> +static bool tmp_child_pre_save(void *opaque, Error **errp)
>  {
>      struct TmpTestStruct *tts = opaque;
>  
>      tts->diff = tts->parent->b - tts->parent->a;
>  
> -    return 0;
> +    return true;
>  }
>  
> -static int tmp_child_post_load(void *opaque, int version_id)
> +static bool tmp_child_post_load(void *opaque, int version_id, Error **errp)
>  {
>      struct TmpTestStruct *tts = opaque;
>  
>      tts->parent->b = tts->parent->a + tts->diff;
>  
> -    return 0;
> +    return true;
>  }
>  
>  static const VMStateDescription vmstate_tmp_back_to_parent = {
> @@ -1562,8 +1504,8 @@ static const VMStateDescription vmstate_tmp_back_to_parent = {
>  
>  static const VMStateDescription vmstate_tmp_child = {
>      .name = "test/tmp_child",
> -    .pre_save = tmp_child_pre_save,
> -    .post_load = tmp_child_post_load,
> +    .pre_save_errp = tmp_child_pre_save,
> +    .post_load_errp = tmp_child_post_load,
>      .fields = (const VMStateField[]) {
>          VMSTATE_INT64(diff, TmpTestStruct),
>          VMSTATE_STRUCT_POINTER(parent, TmpTestStruct,

Reviewed-by: Fabiano Rosas <farosas@suse.de>


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 27/30] arm/machine: move to new migration APIs
  2026-08-25 21:38 ` [PATCH 27/30] arm/machine: " Vladimir Sementsov-Ogievskiy
@ 2026-09-03 17:15   ` Fabiano Rosas
  0 siblings, 0 replies; 40+ messages in thread
From: Fabiano Rosas @ 2026-09-03 17:15 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, peterx
  Cc: qemu-devel, vsementsov, Peter Maydell, open list:ARM TCG CPUs

Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> writes:

> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> ---
>  target/arm/machine.c | 107 ++++++++++++++++++++++---------------------
>  1 file changed, 56 insertions(+), 51 deletions(-)
>
> diff --git a/target/arm/machine.c b/target/arm/machine.c
> index 89127e5d83c..159a1f0e930 100644
> --- a/target/arm/machine.c
> +++ b/target/arm/machine.c
> @@ -51,8 +51,8 @@ static bool vfp_fpcr_fpsr_needed(void *opaque)
>          (vfp_get_fpsr(env) & ~FPSCR_FPSR_MASK);
>  }
>  
> -static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
> -                     const VMStateField *field)
> +static bool load_fpscr(QEMUFile *f, void *opaque, size_t size,
> +                     const VMStateField *field, Error **errp)
>  {
>      ARMCPU *cpu = opaque;
>      CPUARMState *env = &cpu->env;
> @@ -62,78 +62,81 @@ static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
>          /* 0 means we might have the data in the fpcr_fpsr subsection */
>          vfp_set_fpscr(env, val);
>      }
> -    return 0;
> +    return true;
>  }
>  
> -static int put_fpscr(QEMUFile *f, void *opaque, size_t size,
> -                     const VMStateField *field, JSONWriter *vmdesc)
> +static bool save_fpscr(QEMUFile *f, void *opaque, size_t size,
> +                      const VMStateField *field,
> +                      JSONWriter *vmdesc, Error **errp)
>  {
>      ARMCPU *cpu = opaque;
>      CPUARMState *env = &cpu->env;
>      uint32_t fpscr = vfp_fpcr_fpsr_needed(opaque) ? 0 : vfp_get_fpscr(env);
>  
>      qemu_put_be32(f, fpscr);
> -    return 0;
> +    return true;
>  }
>  
>  static const VMStateInfo vmstate_fpscr = {
>      .name = "fpscr",
> -    .get = get_fpscr,
> -    .put = put_fpscr,
> +    .load = load_fpscr,
> +    .save = save_fpscr,
>  };
>  
> -static int get_fpcr(QEMUFile *f, void *opaque, size_t size,
> -                     const VMStateField *field)
> +static bool load_fpcr(QEMUFile *f, void *opaque, size_t size,
> +                     const VMStateField *field, Error **errp)
>  {
>      ARMCPU *cpu = opaque;
>      CPUARMState *env = &cpu->env;
>      uint64_t val = qemu_get_be64(f);
>  
>      vfp_set_fpcr(env, val);
> -    return 0;
> +    return true;
>  }
>  
> -static int put_fpcr(QEMUFile *f, void *opaque, size_t size,
> -                     const VMStateField *field, JSONWriter *vmdesc)
> +static bool save_fpcr(QEMUFile *f, void *opaque, size_t size,
> +                    const VMStateField *field,
> +                    JSONWriter *vmdesc, Error **errp)
>  {
>      ARMCPU *cpu = opaque;
>      CPUARMState *env = &cpu->env;
>  
>      qemu_put_be64(f, vfp_get_fpcr(env));
> -    return 0;
> +    return true;
>  }
>  
>  static const VMStateInfo vmstate_fpcr = {
>      .name = "fpcr",
> -    .get = get_fpcr,
> -    .put = put_fpcr,
> +    .load = load_fpcr,
> +    .save = save_fpcr,
>  };
>  
> -static int get_fpsr(QEMUFile *f, void *opaque, size_t size,
> -                     const VMStateField *field)
> +static bool load_fpsr(QEMUFile *f, void *opaque, size_t size,
> +                     const VMStateField *field, Error **errp)
>  {
>      ARMCPU *cpu = opaque;
>      CPUARMState *env = &cpu->env;
>      uint64_t val = qemu_get_be64(f);
>  
>      vfp_set_fpsr(env, val);
> -    return 0;
> +    return true;
>  }
>  
> -static int put_fpsr(QEMUFile *f, void *opaque, size_t size,
> -                     const VMStateField *field, JSONWriter *vmdesc)
> +static bool save_fpsr(QEMUFile *f, void *opaque, size_t size,
> +                    const VMStateField *field,
> +                    JSONWriter *vmdesc, Error **errp)
>  {
>      ARMCPU *cpu = opaque;
>      CPUARMState *env = &cpu->env;
>  
>      qemu_put_be64(f, vfp_get_fpsr(env));
> -    return 0;
> +    return true;
>  }
>  
>  static const VMStateInfo vmstate_fpsr = {
>      .name = "fpsr",
> -    .get = get_fpsr,
> -    .put = put_fpsr,
> +    .load = load_fpsr,
> +    .save = save_fpsr,
>  };
>  
>  static const VMStateDescription vmstate_vfp_fpcr_fpsr = {
> @@ -755,8 +758,8 @@ static const VMStateDescription vmstate_m_security = {
>      }
>  };
>  
> -static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
> -                    const VMStateField *field)
> +static bool load_cpsr(QEMUFile *f, void *opaque, size_t size,
> +                    const VMStateField *field, Error **errp)
>  {
>      ARMCPU *cpu = opaque;
>      CPUARMState *env = &cpu->env;
> @@ -797,22 +800,22 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
>          }
>          /* Ignore the low bits, they are handled by vmstate_m. */
>          xpsr_write(env, val, ~XPSR_EXCP);
> -        return 0;
> +        return true;
>      }
>  
>      env->aarch64 = ((val & PSTATE_nRW) == 0);
>  
>      if (is_a64(env)) {
>          pstate_write(env, val);
> -        return 0;
> +        return true;
>      }
>  
>      cpsr_write(env, val, 0xffffffff, CPSRWriteRaw);
> -    return 0;
> +    return true;
>  }
>  
> -static int put_cpsr(QEMUFile *f, void *opaque, size_t size,
> -                    const VMStateField *field, JSONWriter *vmdesc)
> +static bool save_cpsr(QEMUFile *f, void *opaque, size_t size,
> +                    const VMStateField *field, JSONWriter *vmdesc, Error **errp)
>  {
>      ARMCPU *cpu = opaque;
>      CPUARMState *env = &cpu->env;
> @@ -828,17 +831,17 @@ static int put_cpsr(QEMUFile *f, void *opaque, size_t size,
>      }
>  
>      qemu_put_be32(f, val);
> -    return 0;
> +    return true;
>  }
>  
>  static const VMStateInfo vmstate_cpsr = {
>      .name = "cpsr",
> -    .get = get_cpsr,
> -    .put = put_cpsr,
> +    .load = load_cpsr,
> +    .save = save_cpsr,
>  };
>  
> -static int get_pstate64(QEMUFile *f, void *opaque, size_t size,
> -                        const VMStateField *field)
> +static bool load_pstate64(QEMUFile *f, void *opaque, size_t size,
> +                        const VMStateField *field, Error **errp)
>  {
>      ARMCPU *cpu = opaque;
>      CPUARMState *env = &cpu->env;
> @@ -850,11 +853,12 @@ static int get_pstate64(QEMUFile *f, void *opaque, size_t size,
>      } else {
>          cpsr_write_from_spsr_elx(env, val);
>      }
> -    return 0;
> +    return true;
>  }
>  
> -static int put_pstate64(QEMUFile *f, void *opaque, size_t size,
> -                        const VMStateField *field, JSONWriter *vmdesc)
> +static bool save_pstate64(QEMUFile *f, void *opaque, size_t size,
> +                         const VMStateField *field,
> +                         JSONWriter *vmdesc, Error **errp)
>  {
>      ARMCPU *cpu = opaque;
>      CPUARMState *env = &cpu->env;
> @@ -866,7 +870,7 @@ static int put_pstate64(QEMUFile *f, void *opaque, size_t size,
>          val = cpsr_read_for_spsr_elx(env);
>      }
>      qemu_put_be64(f, val);
> -    return 0;
> +    return true;
>  }
>  
>  static bool pstate64_needed(void *opaque)
> @@ -901,8 +905,8 @@ static const VMStateDescription vmstate_pstate64 = {
>              .size = sizeof(uint64_t),
>              .info = &(const VMStateInfo) {
>                  .name = "pstate64",
> -                .get = get_pstate64,
> -                .put = put_pstate64,
> +                .load = load_pstate64,
> +                .save = save_pstate64,
>              },
>              .flags = VMS_SINGLE,
>              .offset = 0,
> @@ -911,17 +915,17 @@ static const VMStateDescription vmstate_pstate64 = {
>      },
>  };
>  
> -static int get_power(QEMUFile *f, void *opaque, size_t size,
> -                    const VMStateField *field)
> +static bool load_power(QEMUFile *f, void *opaque, size_t size,
> +                    const VMStateField *field, Error **errp)
>  {
>      ARMCPU *cpu = opaque;
>      bool powered_off = qemu_get_byte(f);
>      arm_set_cpu_power_state(cpu, powered_off ? PSCI_OFF : PSCI_ON);
> -    return 0;
> +    return true;
>  }
>  
> -static int put_power(QEMUFile *f, void *opaque, size_t size,
> -                    const VMStateField *field, JSONWriter *vmdesc)
> +static bool save_power(QEMUFile *f, void *opaque, size_t size,
> +                    const VMStateField *field, JSONWriter *vmdesc, Error **errp)
>  {
>      ARMCPU *cpu = opaque;
>  
> @@ -931,16 +935,17 @@ static int put_power(QEMUFile *f, void *opaque, size_t size,
>          cpu->power_state == PSCI_OFF) {
>          bool powered_off = (cpu->power_state == PSCI_OFF) ? true : false;
>          qemu_put_byte(f, powered_off);
> -        return 0;
> +        return true;
>      } else {
> -        return 1;
> +        error_setg(errp, "Migration should not happen during power transition");
> +        return false;
>      }
>  }
>  
>  static const VMStateInfo vmstate_powered_off = {
>      .name = "powered_off",
> -    .get = get_power,
> -    .put = put_power,
> +    .load = load_power,
> +    .save = save_power,
>  };
>  
>  static bool syndrome64_needed(void *opaque)

../target/arm/machine.c: In function ‘save_power’:
../target/arm/machine.c:940:9: error: implicit declaration of function ‘error_setg’ [-Wimplicit-function-declaration]
  940 |         error_setg(errp, "Migration should not happen during power transition");
      |         ^~~~~~~~~~
../target/arm/machine.c:940:9: error: nested extern declaration of ‘error_setg’ [-Werror=nested-externs]


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 04/30] hw/virtio: config save/load: move to new migration APIs
  2026-08-25 21:37 ` [PATCH 04/30] hw/virtio: config save/load: " Vladimir Sementsov-Ogievskiy
@ 2026-09-03 17:41   ` Fabiano Rosas
  2026-09-04 21:01     ` Vladimir Sementsov-Ogievskiy
  0 siblings, 1 reply; 40+ messages in thread
From: Fabiano Rosas @ 2026-09-03 17:41 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, peterx
  Cc: qemu-devel, vsementsov, Michael S. Tsirkin, Cornelia Huck,
	Halil Pasic, Eric Farman, Richard Henderson, Ilya Leoshkevich,
	David Hildenbrand, Matthew Rosato, Christian Borntraeger,
	open list:virtio-ccw

Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> writes:

> Stop ignoring the error on save path.
>
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> ---
>  hw/pci/pci.c                   | 27 +++++++++++----------------
>  hw/s390x/virtio-ccw.c          | 19 ++++---------------
>  hw/virtio/virtio-mmio.c        | 10 +++++++---
>  hw/virtio/virtio-pci.c         | 24 +++++++++++++++---------
>  hw/virtio/virtio.c             | 11 +++++++----
>  include/hw/pci/pci.h           |  4 ++--
>  include/hw/virtio/virtio-bus.h |  4 ++--
>  7 files changed, 48 insertions(+), 51 deletions(-)
>
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index d3191609e28..76d006fa1d7 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -940,37 +940,32 @@ const VMStateDescription vmstate_pci_device = {
>  };
>  
>  
> -void pci_device_save(PCIDevice *s, QEMUFile *f)
> +bool pci_device_save(PCIDevice *s, QEMUFile *f, Error **errp)
>  {
> -    Error *local_err = NULL;
> -    int ret;
> +    bool ok;
>  
>      /* Clear interrupt status bit: it is implicit
>       * in irq_state which we are saving.
>       * This makes us compatible with old devices
>       * which never set or clear this bit. */
>      s->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT;
> -    ret = vmstate_save_state(f, &vmstate_pci_device, s, NULL, &local_err);
> -    if (ret < 0) {
> -        error_report_err(local_err);
> -    }
> +
> +    ok = vmstate_save_vmsd(f, &vmstate_pci_device, s, NULL, errp);
> +
>      /* Restore the interrupt status bit. */
>      pci_update_irq_status(s);
> +
> +    return ok;
>  }
>  
> -int pci_device_load(PCIDevice *s, QEMUFile *f)
> +bool pci_device_load(PCIDevice *s, QEMUFile *f, Error **errp)
>  {
> -    Error *local_err = NULL;
> -    int ret;
> +    bool ok = vmstate_load_vmsd(f, &vmstate_pci_device, s, s->version_id, errp);
>  
> -    ret = vmstate_load_state(f, &vmstate_pci_device, s, s->version_id,
> -                             &local_err);
> -    if (ret < 0) {
> -        error_report_err(local_err);
> -    }
>      /* Restore the interrupt status bit. */
>      pci_update_irq_status(s);
> -    return ret;
> +
> +    return ok;
>  }
>  
>  static void pci_set_default_subsystem_id(PCIDevice *pci_dev)
> diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> index d82874ed27e..848ed09e94b 100644
> --- a/hw/s390x/virtio-ccw.c
> +++ b/hw/s390x/virtio-ccw.c
> @@ -1129,29 +1129,18 @@ static int virtio_ccw_load_queue(DeviceState *d, int n, QEMUFile *f)
>      return 0;
>  }
>  
> -static void virtio_ccw_save_config(DeviceState *d, QEMUFile *f)
> +static bool virtio_ccw_save_config(DeviceState *d, QEMUFile *f, Error **errp)
>  {
>      VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
> -    Error *local_err = NULL;
> -    int ret;
>  
> -    ret = vmstate_save_state(f, &vmstate_virtio_ccw_dev, dev, NULL, &local_err);
> -    if (ret < 0) {
> -        error_report_err(local_err);
> -    }
> +    return vmstate_save_vmsd(f, &vmstate_virtio_ccw_dev, dev, NULL, errp);
>  }
>  
> -static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f)
> +static bool virtio_ccw_load_config(DeviceState *d, QEMUFile *f, Error **errp)
>  {
>      VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
> -    Error *local_err = NULL;
> -    int ret;
>  
> -    ret = vmstate_load_state(f, &vmstate_virtio_ccw_dev, dev, 1, &local_err);
> -    if (ret < 0) {
> -        error_report_err(local_err);
> -    }
> -    return ret;
> +    return vmstate_load_vmsd(f, &vmstate_virtio_ccw_dev, dev, 1, errp);
>  }
>  
>  static void virtio_ccw_pre_plugged(DeviceState *d, Error **errp)
> diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
> index 559363e4438..ef34b76913e 100644
> --- a/hw/virtio/virtio-mmio.c
> +++ b/hw/virtio/virtio-mmio.c
> @@ -547,23 +547,27 @@ static void virtio_mmio_update_irq(DeviceState *opaque, uint16_t vector)
>      qemu_set_irq(proxy->irq, level);
>  }
>  
> -static int virtio_mmio_load_config(DeviceState *opaque, QEMUFile *f)
> +static bool virtio_mmio_load_config(DeviceState *opaque, QEMUFile *f,
> +                                    Error **errp)
>  {
>      VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
>  
>      proxy->host_features_sel = qemu_get_be32(f);
>      proxy->guest_features_sel = qemu_get_be32(f);
>      proxy->guest_page_shift = qemu_get_be32(f);
> -    return 0;
> +    return true;
>  }
>  
> -static void virtio_mmio_save_config(DeviceState *opaque, QEMUFile *f)
> +static bool virtio_mmio_save_config(DeviceState *opaque, QEMUFile *f,
> +                                    Error **errp)
>  {
>      VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
>  
>      qemu_put_be32(f, proxy->host_features_sel);
>      qemu_put_be32(f, proxy->guest_features_sel);
>      qemu_put_be32(f, proxy->guest_page_shift);
> +
> +    return true;
>  }
>  
>  static const VMStateDescription vmstate_virtio_mmio_queue_state = {
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index 7a5d4f35e33..07941319be2 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -84,15 +84,21 @@ static void virtio_pci_notify(DeviceState *d, uint16_t vector)
>      }
>  }
>  
> -static void virtio_pci_save_config(DeviceState *d, QEMUFile *f)
> +static bool virtio_pci_save_config(DeviceState *d, QEMUFile *f, Error **errp)
>  {
>      VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
>      VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
>  
> -    pci_device_save(&proxy->pci_dev, f);
> +    if (!pci_device_save(&proxy->pci_dev, f, errp)) {
> +        return false;
> +    }
> +
>      msix_save(&proxy->pci_dev, f);
> -    if (msix_present(&proxy->pci_dev))
> +    if (msix_present(&proxy->pci_dev)) {
>          qemu_put_be16(f, vdev->config_vector);
> +    }
> +
> +    return true;
>  }
>  
>  static const VMStateDescription vmstate_virtio_pci_modern_queue_state = {
> @@ -209,24 +215,24 @@ static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f)
>          qemu_put_be16(f, virtio_queue_vector(vdev, n));
>  }
>  
> -static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
> +static bool virtio_pci_load_config(DeviceState *d, QEMUFile *f, Error **errp)
>  {

This function is returning 0

>      VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
>      VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
>      uint16_t vector;
>  
> -    int ret;
> -    ret = pci_device_load(&proxy->pci_dev, f);
> -    if (ret) {
> -        return ret;
> +    if (!pci_device_load(&proxy->pci_dev, f, errp)) {
> +        return false;
>      }
> +
>      msix_unuse_all_vectors(&proxy->pci_dev);
>      msix_load(&proxy->pci_dev, f);
>      if (msix_present(&proxy->pci_dev)) {
>          qemu_get_be16s(f, &vector);
>  
>          if (vector != VIRTIO_NO_VECTOR && vector >= proxy->nvectors) {
> -            return -EINVAL;
> +            error_setg(errp, "load config: unexpected vector %" PRIu16, vector);
> +            return false;
>          }
>      } else {
>          vector = VIRTIO_NO_VECTOR;
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 8230a383aff..0f7c8acead0 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -3077,7 +3077,10 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f)
>      Error *local_err = NULL;
>  
>      if (k->save_config) {
> -        k->save_config(qbus->parent, f);
> +        if (!k->save_config(qbus->parent, f, &local_err)) {
> +            error_report_err(local_err);
> +            return -EINVAL;
> +        }
>      }
>  
>      qemu_put_8s(f, &vdev->status);
> @@ -3526,9 +3529,9 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
>      vdev->device_endian = VIRTIO_DEVICE_ENDIAN_UNKNOWN;
>  
>      if (k->load_config) {
> -        ret = k->load_config(qbus->parent, f);
> -        if (ret)
> -            return ret;
> +        if (!k->load_config(qbus->parent, f, &local_err)) {
> +            return -EINVAL;
> +        }
>      }
>  
>      qemu_get_8s(f, &vdev->status);
> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> index f2448e941a0..7c3fdc05630 100644
> --- a/include/hw/pci/pci.h
> +++ b/include/hw/pci/pci.h
> @@ -270,8 +270,8 @@ uint32_t pci_default_read_config(PCIDevice *d,
>                                   uint32_t address, int len);
>  void pci_default_write_config(PCIDevice *d,
>                                uint32_t address, uint32_t val, int len);
> -void pci_device_save(PCIDevice *s, QEMUFile *f);
> -int pci_device_load(PCIDevice *s, QEMUFile *f);
> +bool pci_device_save(PCIDevice *s, QEMUFile *f, Error **errp);
> +bool pci_device_load(PCIDevice *s, QEMUFile *f, Error **errp);
>  MemoryRegion *pci_address_space(PCIDevice *dev);
>  MemoryRegion *pci_address_space_io(PCIDevice *dev);
>  
> diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
> index 255ecb2fcb2..1b9867002b8 100644
> --- a/include/hw/virtio/virtio-bus.h
> +++ b/include/hw/virtio/virtio-bus.h
> @@ -41,10 +41,10 @@ struct VirtioBusClass {
>      /* This is what a VirtioBus must implement */
>      BusClass parent;
>      void (*notify)(DeviceState *d, uint16_t vector);
> -    void (*save_config)(DeviceState *d, QEMUFile *f);
> +    bool (*save_config)(DeviceState *d, QEMUFile *f, Error **errp);
>      void (*save_queue)(DeviceState *d, int n, QEMUFile *f);
>      bool (*save_extra_state)(DeviceState *d, QEMUFile *f, Error **errp);
> -    int (*load_config)(DeviceState *d, QEMUFile *f);
> +    bool (*load_config)(DeviceState *d, QEMUFile *f, Error **errp);
>      int (*load_queue)(DeviceState *d, int n, QEMUFile *f);
>      int (*load_done)(DeviceState *d, QEMUFile *f);
>      bool (*load_extra_state)(DeviceState *d, QEMUFile *f, Error **errp);


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 28/30] migration/vmstate-types: convert vmstate_info_g_byte_array to new APIs
  2026-08-25 21:38 ` [PATCH 28/30] migration/vmstate-types: convert vmstate_info_g_byte_array to new APIs Vladimir Sementsov-Ogievskiy
@ 2026-09-03 17:41   ` Fabiano Rosas
  0 siblings, 0 replies; 40+ messages in thread
From: Fabiano Rosas @ 2026-09-03 17:41 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, peterx; +Cc: qemu-devel, vsementsov

Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> writes:

> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
> ---
>  migration/vmstate-types.c | 17 +++++++++--------
>  1 file changed, 9 insertions(+), 8 deletions(-)
>
> diff --git a/migration/vmstate-types.c b/migration/vmstate-types.c
> index 8c01215c251..c2d4645f317 100644
> --- a/migration/vmstate-types.c
> +++ b/migration/vmstate-types.c
> @@ -925,30 +925,31 @@ const VMStateInfo vmstate_info_qlist = {
>      .save = save_qlist,
>  };
>  
> -static int get_g_byte_array(QEMUFile *f, void *pv, size_t size,
> -                            const VMStateField *field)
> +static bool load_g_byte_array(QEMUFile *f, void *pv, size_t size,
> +                              const VMStateField *field, Error **errp)
>  {
>      GByteArray *byte_array = *(GByteArray **)pv;
>      uint32_t len = qemu_get_be32(f);
>  
>      g_byte_array_set_size(byte_array, len);
>      qemu_get_buffer(f, byte_array->data, len);
> -    return 0;
> +    return true;
>  }
>  
> -static int put_g_byte_array(QEMUFile *f, void *pv, size_t size,
> -                            const VMStateField *field, JSONWriter *vmdesc)
> +static bool save_g_byte_array(QEMUFile *f, void *pv, size_t size,
> +                              const VMStateField *field, JSONWriter *vmdesc,
> +                              Error **errp)
>  {
>      GByteArray *byte_array = *(GByteArray **)pv;
>  
>      qemu_put_be32(f, byte_array->len);
>      qemu_put_buffer(f, byte_array->data, byte_array->len);
>  
> -    return 0;
> +    return true;
>  }
>  
>  const VMStateInfo vmstate_info_g_byte_array = {
>      .name = "GByteArray",
> -    .get  = get_g_byte_array,
> -    .put  = put_g_byte_array,
> +    .load = load_g_byte_array,
> +    .save = save_g_byte_array,
>  };

Reviewed-by: Fabiano Rosas <farosas@suse.de>


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 04/30] hw/virtio: config save/load: move to new migration APIs
  2026-09-03 17:41   ` Fabiano Rosas
@ 2026-09-04 21:01     ` Vladimir Sementsov-Ogievskiy
  0 siblings, 0 replies; 40+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-09-04 21:01 UTC (permalink / raw)
  To: Fabiano Rosas, peterx
  Cc: qemu-devel, Michael S. Tsirkin, Cornelia Huck, Halil Pasic,
	Eric Farman, Richard Henderson, Ilya Leoshkevich,
	David Hildenbrand, Matthew Rosato, Christian Borntraeger,
	open list:virtio-ccw

On 03.09.26 20:41, Fabiano Rosas wrote:
>>   }
>>   
>> -static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
>> +static bool virtio_pci_load_config(DeviceState *d, QEMUFile *f, Error **errp)
>>   {
> This function is returning 0


Oops right, thanks! Will fix.


-- 
Best regards,
Vladimir


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/30] move to new migration APIs
  2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
                   ` (29 preceding siblings ...)
  2026-08-25 21:38 ` [PATCH 30/30] migration: finally drop vmstate_save/load_state() functions Vladimir Sementsov-Ogievskiy
@ 2026-09-22 12:03 ` Fabiano Rosas
  30 siblings, 0 replies; 40+ messages in thread
From: Fabiano Rosas @ 2026-09-22 12:03 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, peterx; +Cc: qemu-devel, vsementsov

Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> writes:

> Hi all!
>
> That's a new version for old
>
> [RFC 00/22] migration: convert vmstate_load/save_state
>
> after the core patches converting migration code
> are already merged into master.
>
> Let's now convert the whole code base.
>
> Vladimir Sementsov-Ogievskiy (30):
>   tests/unit/test-vmstate: move to new migration APIs
>   ui/vdagent: move to new migration APIs
>   hw/virtio: extra state: move to new migration APIs
>   hw/virtio: config save/load: move to new migration APIs
>   hw/virtio: make virtio_save() and virtio_load() static
>   hw/virtio: remaining: move to new migration APIs
>   hw/s390x/virtio-ccw.c: move to new migration APIs
>   hw/scsi/spapr_vscsi: move to new migration APIs
>   hw/scsi/scsi-bus.c: use new migration APIs
>   hw/vfio/pci: move to new migration APIs
>   hw/pci/pci: move to new migration APIs
>   hw/pci/msix.c: use new migration APIs
>   hw/pci/shpc.c: use new migration APIs
>   hw/display/virtio-gpu: move to new migration APIs
>   hw/net/virtio-net.c: use new migration APIs
>   hw/nvram/eeprom93xx.c: use new migration APIs
>   hw/nvram/fw_cfg.c: use new migration APIs
>   hw/usb/redirect.c: move to new migration APIs
>   alpha/machine: move to new migration APIs
>   avr/machine: move to new migration APIs
>   or1k/machine: move to new migration APIs
>   microblaze/machine: move to new migration APIs
>   hppa/machine: move to new migration APIs
>   sparc/machine: move to new migration APIs
>   ppc/machine: move to new migration APIs
>   mips/machine: move to new migration APIs
>   arm/machine: move to new migration APIs
>   migration/vmstate-types: convert vmstate_info_g_byte_array to new APIs
>   migration: VMStateInfo: remove old .get / .set handlers
>   migration: finally drop vmstate_save/load_state() functions
>
>  hw/display/virtio-gpu.c        |  99 +++++++++++----------
>  hw/net/virtio-net.c            | 133 ++++++++++++++--------------
>  hw/nvram/eeprom93xx.c          |  17 ++--
>  hw/nvram/fw_cfg.c              |  24 ++---
>  hw/pci/msix.c                  |  17 ++--
>  hw/pci/pci.c                   |  85 +++++++++---------
>  hw/pci/shpc.c                  |  20 +++--
>  hw/s390x/virtio-ccw.c          |  40 ++++-----
>  hw/scsi/scsi-bus.c             |  17 ++--
>  hw/scsi/spapr_vscsi.c          |   9 +-
>  hw/usb/redirect.c              |  59 +++++++------
>  hw/vfio/pci.c                  |  14 ++-
>  hw/virtio/vhost-user-fs.c      |  68 +++++++-------
>  hw/virtio/virtio-mmio.c        |  31 +++----
>  hw/virtio/virtio-pci.c         |  45 +++++-----
>  hw/virtio/virtio.c             | 157 +++++++++++++++++----------------
>  include/hw/pci/pci.h           |   4 +-
>  include/hw/virtio/virtio-bus.h |   8 +-
>  include/hw/virtio/virtio.h     |   4 -
>  include/migration/vmstate.h    |  17 ----
>  migration/vmstate-types.c      |  17 ++--
>  migration/vmstate.c            |  32 +------
>  target/alpha/machine.c         |  17 ++--
>  target/arm/machine.c           | 107 +++++++++++-----------
>  target/avr/machine.c           |  50 ++++++-----
>  target/hppa/machine.c          |  34 +++----
>  target/microblaze/machine.c    |  17 ++--
>  target/mips/system/machine.c   |  49 +++++-----
>  target/or1k/machine.c          |  17 ++--
>  target/ppc/machine.c           |  80 ++++++++---------
>  target/sparc/machine.c         |  68 +++++++-------
>  tests/unit/test-vmstate.c      | 118 +++++++------------------
>  ui/vdagent.c                   |  38 ++++----
>  33 files changed, 710 insertions(+), 802 deletions(-)

Queued patches 1 and 28 for migration-next.


^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2026-09-22 12:04 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-25 21:37 [PATCH 00/30] move to new migration APIs Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 01/30] tests/unit/test-vmstate: " Vladimir Sementsov-Ogievskiy
2026-08-29  5:55   ` Akihiko Odaki
2026-09-03 17:12   ` Fabiano Rosas
2026-08-25 21:37 ` [PATCH 02/30] ui/vdagent: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 03/30] hw/virtio: extra state: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 04/30] hw/virtio: config save/load: " Vladimir Sementsov-Ogievskiy
2026-09-03 17:41   ` Fabiano Rosas
2026-09-04 21:01     ` Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 05/30] hw/virtio: make virtio_save() and virtio_load() static Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 06/30] hw/virtio: remaining: move to new migration APIs Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 07/30] hw/s390x/virtio-ccw.c: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 08/30] hw/scsi/spapr_vscsi: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 09/30] hw/scsi/scsi-bus.c: use " Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 10/30] hw/vfio/pci: move to " Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 11/30] hw/pci/pci: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 12/30] hw/pci/msix.c: use " Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 13/30] hw/pci/shpc.c: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 14/30] hw/display/virtio-gpu: move to " Vladimir Sementsov-Ogievskiy
2026-08-29  6:54   ` Akihiko Odaki
2026-08-29 19:30     ` Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 15/30] hw/net/virtio-net.c: use " Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 16/30] hw/nvram/eeprom93xx.c: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 17/30] hw/nvram/fw_cfg.c: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 18/30] hw/usb/redirect.c: move to " Vladimir Sementsov-Ogievskiy
2026-08-25 21:37 ` [PATCH 19/30] alpha/machine: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:38 ` [PATCH 20/30] avr/machine: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:38 ` [PATCH 21/30] or1k/machine: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:38 ` [PATCH 22/30] microblaze/machine: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:38 ` [PATCH 23/30] hppa/machine: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:38 ` [PATCH 24/30] sparc/machine: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:38 ` [PATCH 25/30] ppc/machine: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:38 ` [PATCH 26/30] mips/machine: " Vladimir Sementsov-Ogievskiy
2026-08-25 21:38 ` [PATCH 27/30] arm/machine: " Vladimir Sementsov-Ogievskiy
2026-09-03 17:15   ` Fabiano Rosas
2026-08-25 21:38 ` [PATCH 28/30] migration/vmstate-types: convert vmstate_info_g_byte_array to new APIs Vladimir Sementsov-Ogievskiy
2026-09-03 17:41   ` Fabiano Rosas
2026-08-25 21:38 ` [PATCH 29/30] migration: VMStateInfo: remove old .get / .set handlers Vladimir Sementsov-Ogievskiy
2026-08-25 21:38 ` [PATCH 30/30] migration: finally drop vmstate_save/load_state() functions Vladimir Sementsov-Ogievskiy
2026-09-22 12:03 ` [PATCH 00/30] move to new migration APIs Fabiano Rosas

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.