@@ -721,7 +721,7 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
return 0;
}
-static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
+static int load_xbzrle(QEMUFile *f, void *host)
{
int ret, rc = 0;
unsigned int xh_len;
@@ -792,12 +792,73 @@ static inline void *host_from_stream_offset(QEMUFile *f,
return NULL;
}
+int ram_load_mem_size(QEMUFile *f, ram_addr_t total_ram_bytes)
+{
+ /* Synchronize RAM block list */
+ char id[256];
+ ram_addr_t length;
+
+ while (total_ram_bytes) {
+ RAMBlock *block;
+ uint8_t len;
+
+ len = qemu_get_byte(f);
+ qemu_get_buffer(f, (uint8_t *)id, len);
+ id[len] = 0;
+ length = qemu_get_be64(f);
+
+ QLIST_FOREACH(block, &ram_list.blocks, next) {
+ if (!strncmp(id, block->idstr, sizeof(id))) {
+ if (block->length != length)
+ return -EINVAL;
+ break;
+ }
+ }
+
+ if (!block) {
+ fprintf(stderr, "Unknown ramblock \"%s\", cannot "
+ "accept migration\n", id);
+ return -EINVAL;
+ }
+
+ total_ram_bytes -= length;
+ }
+
+ return 0;
+}
+
+int ram_load_page(QEMUFile *f, void *host, int flags)
+{
+ if (flags & RAM_SAVE_FLAG_COMPRESS) {
+ uint8_t ch;
+ ch = qemu_get_byte(f);
+ memset(host, ch, TARGET_PAGE_SIZE);
+#ifndef _WIN32
+ if (ch == 0 &&
+ (!kvm_enabled() || kvm_has_sync_mmu())) {
+ qemu_madvise(host, TARGET_PAGE_SIZE, QEMU_MADV_DONTNEED);
+ }
+#endif
+ } else if (flags & RAM_SAVE_FLAG_PAGE) {
+ qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
+ } else if (flags & RAM_SAVE_FLAG_XBZRLE) {
+ if (!migrate_use_xbzrle()) {
+ return -EINVAL;
+ }
+ if (load_xbzrle(f, host) < 0) {
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
static int ram_load(QEMUFile *f, void *opaque, int version_id)
{
ram_addr_t addr;
int flags, ret = 0;
int error;
static uint64_t seq_iter;
+ void *host;
seq_iter++;
@@ -813,82 +874,26 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
if (version_id == 4) {
- /* Synchronize RAM block list */
- char id[256];
- ram_addr_t length;
- ram_addr_t total_ram_bytes = addr;
-
- while (total_ram_bytes) {
- RAMBlock *block;
- uint8_t len;
-
- len = qemu_get_byte(f);
- qemu_get_buffer(f, (uint8_t *)id, len);
- id[len] = 0;
- length = qemu_get_be64(f);
-
- QLIST_FOREACH(block, &ram_list.blocks, next) {
- if (!strncmp(id, block->idstr, sizeof(id))) {
- if (block->length != length) {
- ret = -EINVAL;
- goto done;
- }
- break;
- }
- }
-
- if (!block) {
- fprintf(stderr, "Unknown ramblock \"%s\", cannot "
- "accept migration\n", id);
- ret = -EINVAL;
- goto done;
- }
-
- total_ram_bytes -= length;
+ error = ram_load_mem_size(f, addr);
+ if (error) {
+ DPRINTF("error %d\n", error);
+ return error;
}
}
}
- if (flags & RAM_SAVE_FLAG_COMPRESS) {
- void *host;
- uint8_t ch;
-
- host = host_from_stream_offset(f, addr, flags);
- if (!host) {
- return -EINVAL;
- }
-
- ch = qemu_get_byte(f);
- memset(host, ch, TARGET_PAGE_SIZE);
-#ifndef _WIN32
- if (ch == 0 &&
- (!kvm_enabled() || kvm_has_sync_mmu())) {
- qemu_madvise(host, TARGET_PAGE_SIZE, QEMU_MADV_DONTNEED);
- }
-#endif
- } else if (flags & RAM_SAVE_FLAG_PAGE) {
- void *host;
-
+ if (flags & (RAM_SAVE_FLAG_COMPRESS | RAM_SAVE_FLAG_PAGE |
+ RAM_SAVE_FLAG_XBZRLE)) {
host = host_from_stream_offset(f, addr, flags);
if (!host) {
return -EINVAL;
}
-
- qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
- } else if (flags & RAM_SAVE_FLAG_XBZRLE) {
- if (!migrate_use_xbzrle()) {
- return -EINVAL;
- }
- void *host = host_from_stream_offset(f, addr, flags);
- if (!host) {
- return -EINVAL;
- }
-
- if (load_xbzrle(f, addr, host) < 0) {
- ret = -EINVAL;
+ ret = ram_load_page(f, host, flags);
+ if (ret) {
goto done;
}
}
+
error = qemu_file_get_error(f);
if (error) {
ret = error;
@@ -46,9 +46,12 @@ CpuDefinitionInfoList GCC_WEAK_DECL *arch_query_cpu_definitions(Error **errp);
#define RAM_SAVE_VERSION_ID 4 /* currently version 4 */
+int ram_load_page(QEMUFile *f, void *host, int flags);
+
#if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY)
bool ram_save_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
bool last_stage);
+int ram_load_mem_size(QEMUFile *f, ram_addr_t total_ram_bytes);
#endif
#endif
ram_load_page() will be used by postcopy. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> --- Changes v2 -> v3: - new --- arch_init.c | 137 +++++++++++++++++++++++++++++++---------------------------- arch_init.h | 3 ++ 2 files changed, 74 insertions(+), 66 deletions(-)