#define QEMU_ARCH QEMU_ARCH_XTENSA
#elif defined(TARGET_UNICORE32)
#define QEMU_ARCH QEMU_ARCH_UNICORE32
+#elif defined(TARGET_TRICORE)
+#define QEMU_ARCH QEMU_ARCH_TRICORE
#endif
const uint32_t arch_type = QEMU_ARCH;
/* We don't care if this fails to allocate a new cache page
* as long as it updated an old one */
- cache_insert(XBZRLE.cache, current_addr, ZERO_TARGET_PAGE);
+ cache_insert(XBZRLE.cache, current_addr, ZERO_TARGET_PAGE,
+ bitmap_sync_count);
}
#define ENCODING_FLAG_XBZRLE 0x1
int encoded_len = 0, bytes_sent = -1;
uint8_t *prev_cached_page;
- if (!cache_is_cached(XBZRLE.cache, current_addr)) {
+ if (!cache_is_cached(XBZRLE.cache, current_addr, bitmap_sync_count)) {
acct_info.xbzrle_cache_miss++;
if (!last_stage) {
- if (cache_insert(XBZRLE.cache, current_addr, *current_data) == -1) {
+ if (cache_insert(XBZRLE.cache, current_addr, *current_data,
+ bitmap_sync_count) == -1) {
return -1;
} else {
/* update *current_data when the page has been
/* Needs iothread lock! */
+/* Fix me: there are too many global variables used in migration process. */
+static int64_t start_time;
+static int64_t bytes_xfer_prev;
+static int64_t num_dirty_pages_period;
+
+static void migration_bitmap_sync_init(void)
+{
+ start_time = 0;
+ bytes_xfer_prev = 0;
+ num_dirty_pages_period = 0;
+}
static void migration_bitmap_sync(void)
{
RAMBlock *block;
uint64_t num_dirty_pages_init = migration_dirty_pages;
MigrationState *s = migrate_get_current();
- static int64_t start_time;
- static int64_t bytes_xfer_prev;
- static int64_t num_dirty_pages_period;
int64_t end_time;
int64_t bytes_xfer_now;
static uint64_t xbzrle_cache_miss_prev;
address_space_sync_dirty_bitmap(&address_space_memory);
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
- migration_bitmap_sync_range(block->mr->ram_addr, block->length);
+ migration_bitmap_sync_range(block->mr->ram_addr, block->used_length);
}
trace_migration_bitmap_sync_end(migration_dirty_pages
- num_dirty_pages_init);
offset >= last_offset) {
break;
}
- if (offset >= block->length) {
+ if (offset >= block->used_length) {
offset = 0;
block = QTAILQ_NEXT(block, next);
if (!block) {
uint64_t total = 0;
QTAILQ_FOREACH(block, &ram_list.blocks, next)
- total += block->length;
+ total += block->used_length;
return total;
}
XBZRLE_cache_lock();
if (XBZRLE.cache) {
cache_fini(XBZRLE.cache);
- g_free(XBZRLE.cache);
g_free(XBZRLE.encoded_buf);
g_free(XBZRLE.current_buf);
XBZRLE.cache = NULL;
mig_throttle_on = false;
dirty_rate_high_cnt = 0;
bitmap_sync_count = 0;
+ migration_bitmap_sync_init();
if (migrate_use_xbzrle()) {
XBZRLE_cache_lock();
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
uint64_t block_pages;
- block_pages = block->length >> TARGET_PAGE_BITS;
+ block_pages = block->used_length >> TARGET_PAGE_BITS;
migration_dirty_pages += block_pages;
}
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
qemu_put_byte(f, strlen(block->idstr));
qemu_put_buffer(f, (uint8_t *)block->idstr, strlen(block->idstr));
- qemu_put_be64(f, block->length);
+ qemu_put_be64(f, block->used_length);
}
qemu_mutex_unlock_ramlist();
uint8_t len;
if (flags & RAM_SAVE_FLAG_CONTINUE) {
- if (!block) {
+ if (!block || block->max_length <= offset) {
error_report("Ack, bad migration stream!");
return NULL;
}
id[len] = 0;
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
- if (!strncmp(id, block->idstr, sizeof(id)))
+ if (!strncmp(id, block->idstr, sizeof(id)) &&
+ block->max_length > offset) {
return memory_region_get_ram_ptr(block->mr) + offset;
+ }
}
error_report("Can't find block %s!", id);
static int ram_load(QEMUFile *f, void *opaque, int version_id)
{
- ram_addr_t addr;
- int flags, ret = 0;
- int error;
+ int flags = 0, ret = 0;
static uint64_t seq_iter;
seq_iter++;
if (version_id != 4) {
ret = -EINVAL;
- goto done;
}
- do {
- addr = qemu_get_be64(f);
+ while (!ret && !(flags & RAM_SAVE_FLAG_EOS)) {
+ ram_addr_t addr, total_ram_bytes;
+ void *host;
+ uint8_t ch;
+ addr = qemu_get_be64(f);
flags = addr & ~TARGET_PAGE_MASK;
addr &= TARGET_PAGE_MASK;
- if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
+ switch (flags & ~RAM_SAVE_FLAG_CONTINUE) {
+ case RAM_SAVE_FLAG_MEM_SIZE:
/* Synchronize RAM block list */
- char id[256];
- ram_addr_t length;
- ram_addr_t total_ram_bytes = addr;
-
- while (total_ram_bytes) {
+ total_ram_bytes = addr;
+ while (!ret && total_ram_bytes) {
RAMBlock *block;
uint8_t len;
+ char id[256];
+ ram_addr_t length;
len = qemu_get_byte(f);
qemu_get_buffer(f, (uint8_t *)id, len);
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
if (!strncmp(id, block->idstr, sizeof(id))) {
- if (block->length != length) {
- error_report("Length mismatch: %s: " RAM_ADDR_FMT
- " in != " RAM_ADDR_FMT, id, length,
- block->length);
- ret = -EINVAL;
- goto done;
+ if (length != block->used_length) {
+ Error *local_err = NULL;
+
+ ret = qemu_ram_resize(block->offset, length, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ }
}
break;
}
error_report("Unknown ramblock \"%s\", cannot "
"accept migration", id);
ret = -EINVAL;
- goto done;
}
total_ram_bytes -= length;
}
- }
-
- if (flags & RAM_SAVE_FLAG_COMPRESS) {
- void *host;
- uint8_t ch;
-
+ break;
+ case RAM_SAVE_FLAG_COMPRESS:
host = host_from_stream_offset(f, addr, flags);
if (!host) {
+ error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
ret = -EINVAL;
- goto done;
+ break;
}
ch = qemu_get_byte(f);
ram_handle_compressed(host, ch, TARGET_PAGE_SIZE);
- } else if (flags & RAM_SAVE_FLAG_PAGE) {
- void *host;
-
+ break;
+ case RAM_SAVE_FLAG_PAGE:
host = host_from_stream_offset(f, addr, flags);
if (!host) {
+ error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
ret = -EINVAL;
- goto done;
+ break;
}
qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
- } else if (flags & RAM_SAVE_FLAG_XBZRLE) {
- void *host = host_from_stream_offset(f, addr, flags);
+ break;
+ case RAM_SAVE_FLAG_XBZRLE:
+ host = host_from_stream_offset(f, addr, flags);
if (!host) {
+ error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
ret = -EINVAL;
- goto done;
+ break;
}
if (load_xbzrle(f, addr, host) < 0) {
+ error_report("Failed to decompress XBZRLE page at "
+ RAM_ADDR_FMT, addr);
+ ret = -EINVAL;
+ break;
+ }
+ break;
+ case RAM_SAVE_FLAG_EOS:
+ /* normal exit */
+ break;
+ default:
+ if (flags & RAM_SAVE_FLAG_HOOK) {
+ ram_control_load_hook(f, flags);
+ } else {
+ error_report("Unknown combination of migration flags: %#x",
+ flags);
ret = -EINVAL;
- goto done;
}
- } else if (flags & RAM_SAVE_FLAG_HOOK) {
- ram_control_load_hook(f, flags);
}
- error = qemu_file_get_error(f);
- if (error) {
- ret = error;
- goto done;
+ if (!ret) {
+ ret = qemu_file_get_error(f);
}
- } while (!(flags & RAM_SAVE_FLAG_EOS));
+ }
-done:
DPRINTF("Completed load of VM with exit code %d seq iteration "
"%" PRIu64 "\n", ret, seq_iter);
return ret;
#endif
}
-int tcg_available(void)
-{
- return 1;
-}
-
int kvm_available(void)
{
#ifdef CONFIG_KVM