diff --git a/savevm.c b/savevm.c
index dc20390..aa4f98c 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1005,6 +1005,8 @@ typedef struct SaveStateEntry {
 
 static QTAILQ_HEAD(savevm_handlers, SaveStateEntry) savevm_handlers =
     QTAILQ_HEAD_INITIALIZER(savevm_handlers);
+static QLIST_HEAD(, LoadStateEntry) loadvm_handlers =
+    QLIST_HEAD_INITIALIZER(loadvm_handlers);
 static int global_section_id;
 
 static int calculate_new_instance_id(const char *idstr)
@@ -1460,14 +1462,9 @@ typedef struct LoadStateEntry {
     int version_id;
 } LoadStateEntry;
 
-int qemu_loadvm_state(QEMUFile *f)
+int qemu_loadvm_state_begin(QEMUFile *f)
 {
-    QLIST_HEAD(, LoadStateEntry) loadvm_handlers =
-        QLIST_HEAD_INITIALIZER(loadvm_handlers);
-    LoadStateEntry *le, *new_le;
-    uint8_t section_type;
     unsigned int v;
-    int ret;
 
     v = qemu_get_be32(f);
     if (v != QEMU_VM_FILE_MAGIC)
@@ -1481,73 +1478,157 @@ int qemu_loadvm_state(QEMUFile *f)
     if (v != QEMU_VM_FILE_VERSION)
         return -ENOTSUP;
 
-    while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {
-        uint32_t instance_id, version_id, section_id;
-        SaveStateEntry *se;
-        char idstr[257];
-        int len;
+    return 0;
+}
 
-        switch (section_type) {
-        case QEMU_VM_SECTION_START:
-        case QEMU_VM_SECTION_FULL:
-            /* Read section start */
-            section_id = qemu_get_be32(f);
-            len = qemu_get_byte(f);
-            qemu_get_buffer(f, (uint8_t *)idstr, len);
-            idstr[len] = 0;
-            instance_id = qemu_get_be32(f);
-            version_id = qemu_get_be32(f);
-
-            /* Find savevm section */
-            se = find_se(idstr, instance_id);
-            if (se == NULL) {
-                fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id);
-                ret = -EINVAL;
-                goto out;
-            }
+static int qemu_loadvm_state_iterate(QEMUFile *f)
+{
+    LoadStateEntry *le;
+    uint32_t section_id;
+    int ret;
 
-            /* Validate version */
-            if (version_id > se->version_id) {
-                fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n",
-                        version_id, idstr, se->version_id);
-                ret = -EINVAL;
-                goto out;
-            }
+    section_id = qemu_get_be32(f);
+
+    QLIST_FOREACH(le, &loadvm_handlers, entry) {
+        if (le->section_id == section_id) {
+            break;
+        }
+    }
+    if (le == NULL) {
+        fprintf(stderr, "Unknown savevm section %d\n", section_id);
+        return -EINVAL;
+    }
+
+    ret = vmstate_load(f, le->se, le->version_id);
+    if (ret < 0) {
+        fprintf(stderr, "qemu: warning: error while loading state section id %d\n",
+                section_id);
+        return ret;
+    }
+
+    return 0;
+}
+
+static int qemu_loadvm_state_complete(QEMUFile *f)
+{
+    LoadStateEntry *le;
+    uint32_t instance_id, version_id, section_id;
+    SaveStateEntry *se;
+    char idstr[257];
+    int ret = -1, len;
+
+    /* Read section start */
+    section_id = qemu_get_be32(f);
+    len = qemu_get_byte(f);
+    qemu_get_buffer(f, (uint8_t *)idstr, len);
+    idstr[len] = 0;
+    instance_id = qemu_get_be32(f);
+    version_id = qemu_get_be32(f);
+
+    /* Find savevm section */
+    se = find_se(idstr, instance_id);
+    if (se == NULL) {
+        fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id);
+        return -EINVAL;
+    }
+
+    /* Validate version */
+    if (version_id > se->version_id) {
+        fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n",
+                version_id, idstr, se->version_id);
+        return -EINVAL;
+    }
+
+    /* Add entry */
+    le = qemu_mallocz(sizeof(*le));
+
+    le->se = se;
+    le->section_id = section_id;
+    le->version_id = version_id;
+    QLIST_INSERT_HEAD(&loadvm_handlers, le, entry);
+
+    ret = vmstate_load(f, le->se, le->version_id);
+    if (ret < 0) {
+        fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
+                instance_id, idstr);
+        return ret;
+    }
+
+    return 0;
+}
 
-            /* Add entry */
-            le = qemu_mallocz(sizeof(*le));
+int qemu_loadvm_state_async(QEMUFile *f)
+{
+    LoadStateEntry *le, *new_le;
+    int ret;
+    uint8_t section_type;
 
-            le->se = se;
-            le->section_id = section_id;
-            le->version_id = version_id;
-            QLIST_INSERT_HEAD(&loadvm_handlers, le, entry);
+    section_type = qemu_get_byte(f);
+    switch (section_type) {
+    case QEMU_VM_SECTION_START:
+    case QEMU_VM_SECTION_FULL:
+        ret = qemu_loadvm_state_complete(f);
+        if (ret < 0) {
+            goto out_free;
+        }
+        break;
+    case QEMU_VM_SECTION_PART:
+    case QEMU_VM_SECTION_END:
+        ret = qemu_loadvm_state_iterate(f);
+        if (ret < 0) {
+            goto out_free;
+        }
+        break;
+    case QEMU_VM_EOF:
+        cpu_synchronize_all_post_init();
+        break;
+    default:
+        fprintf(stderr, "Unknown savevm section type %d\n", section_type);
+        ret = -EINVAL;
+        goto out_free;
+    }
+ 
+    ret = section_type;
+    if (ret != QEMU_VM_EOF) {
+        goto out;
+    }
 
-            ret = vmstate_load(f, le->se, le->version_id);
+out_free:
+    QLIST_FOREACH_SAFE(le, &loadvm_handlers, entry, new_le) {
+        QLIST_REMOVE(le, entry);
+        qemu_free(le);
+    }
+out:
+    if (qemu_file_has_error(f)) {
+        ret = -EIO;
+    }
+
+    return ret;
+}
+
+int qemu_loadvm_state(QEMUFile *f)
+{
+    LoadStateEntry *le, *new_le;
+    int ret;
+    uint8_t section_type;
+
+    ret = qemu_loadvm_state_begin(f);
+    if (ret < 0)
+        goto out;
+
+    while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {
+        switch (section_type) {
+        case QEMU_VM_SECTION_START:
+        case QEMU_VM_SECTION_FULL:
+            ret = qemu_loadvm_state_complete(f);
             if (ret < 0) {
-                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
-                        instance_id, idstr);
                 goto out;
             }
             break;
         case QEMU_VM_SECTION_PART:
         case QEMU_VM_SECTION_END:
-            section_id = qemu_get_be32(f);
-
-            QLIST_FOREACH(le, &loadvm_handlers, entry) {
-                if (le->section_id == section_id) {
-                    break;
-                }
-            }
-            if (le == NULL) {
-                fprintf(stderr, "Unknown savevm section %d\n", section_id);
-                ret = -EINVAL;
-                goto out;
-            }
-
-            ret = vmstate_load(f, le->se, le->version_id);
+            ret = qemu_loadvm_state_iterate(f);
             if (ret < 0) {
-                fprintf(stderr, "qemu: warning: error while loading state section id %d\n",
-                        section_id);
                 goto out;
             }
             break;
@@ -1568,8 +1649,9 @@ out:
         qemu_free(le);
     }
 
-    if (qemu_file_has_error(f))
+    if (qemu_file_has_error(f)) {
         ret = -EIO;
+    }
 
     return ret;
 }
diff --git a/sysemu.h b/sysemu.h
index 879446a..c576840 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -69,6 +69,8 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
 int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f);
 int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f);
 void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f);
+int qemu_loadvm_state_begin(QEMUFile *f);
+int qemu_loadvm_state_async(QEMUFile *f);
 int qemu_loadvm_state(QEMUFile *f);
 
 #ifdef _WIN32
