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
                   ` (29 more replies)
  0 siblings, 30 replies; 39+ 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] 39+ 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
                   ` (28 subsequent siblings)
  29 siblings, 2 replies; 39+ 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] 39+ 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
                   ` (27 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (26 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (25 subsequent siblings)
  29 siblings, 1 reply; 39+ 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] 39+ 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
                   ` (24 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (23 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (22 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (21 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (20 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (19 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (18 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (17 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (16 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (15 subsequent siblings)
  29 siblings, 1 reply; 39+ 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] 39+ 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
                   ` (14 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (13 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (12 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (11 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (10 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (9 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (8 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (7 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (6 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (5 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (4 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (3 subsequent siblings)
  29 siblings, 0 replies; 39+ 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] 39+ 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
                   ` (2 subsequent siblings)
  29 siblings, 1 reply; 39+ 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] 39+ 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
  2026-08-25 21:38 ` [PATCH 30/30] migration: finally drop vmstate_save/load_state() functions Vladimir Sementsov-Ogievskiy
  29 siblings, 1 reply; 39+ 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] 39+ 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
  29 siblings, 0 replies; 39+ 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] 39+ 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
  29 siblings, 0 replies; 39+ 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] 39+ 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; 39+ 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] 39+ 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; 39+ 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] 39+ 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; 39+ 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] 39+ 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; 39+ 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] 39+ 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; 39+ 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] 39+ 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; 39+ 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] 39+ 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; 39+ 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] 39+ 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; 39+ 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] 39+ messages in thread

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

Thread overview: 39+ 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

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.