X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/fb626663da94ddbfae88900c62bf4a26534fbafa..b8c9cd5c8cf2a105dab8ac3e5799e3b27bfda9d5:/arch_init.c diff --git a/arch_init.c b/arch_init.c index 4e8f2c8a5c..9b3e25d805 100644 --- a/arch_init.c +++ b/arch_init.c @@ -104,6 +104,8 @@ int graphic_depth = 32; #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; @@ -560,20 +562,93 @@ static void migration_bitmap_sync(void) } /* - * ram_save_block: Writes a page of memory to the stream f + * ram_save_page: Send the given page to the stream + * + * Returns: Number of bytes written. + */ +static int ram_save_page(QEMUFile *f, RAMBlock* block, ram_addr_t offset, + bool last_stage) +{ + int bytes_sent; + int cont; + ram_addr_t current_addr; + MemoryRegion *mr = block->mr; + uint8_t *p; + int ret; + bool send_async = true; + + cont = (block == last_sent_block) ? RAM_SAVE_FLAG_CONTINUE : 0; + + p = memory_region_get_ram_ptr(mr) + offset; + + /* In doubt sent page as normal */ + bytes_sent = -1; + ret = ram_control_save_page(f, block->offset, + offset, TARGET_PAGE_SIZE, &bytes_sent); + + XBZRLE_cache_lock(); + + current_addr = block->offset + offset; + if (ret != RAM_SAVE_CONTROL_NOT_SUPP) { + if (ret != RAM_SAVE_CONTROL_DELAYED) { + if (bytes_sent > 0) { + acct_info.norm_pages++; + } else if (bytes_sent == 0) { + acct_info.dup_pages++; + } + } + } else if (is_zero_range(p, TARGET_PAGE_SIZE)) { + acct_info.dup_pages++; + bytes_sent = save_block_hdr(f, block, offset, cont, + RAM_SAVE_FLAG_COMPRESS); + qemu_put_byte(f, 0); + bytes_sent++; + /* Must let xbzrle know, otherwise a previous (now 0'd) cached + * page would be stale + */ + xbzrle_cache_zero_page(current_addr); + } else if (!ram_bulk_stage && migrate_use_xbzrle()) { + bytes_sent = save_xbzrle_page(f, &p, current_addr, block, + offset, cont, last_stage); + if (!last_stage) { + /* Can't send this cached data async, since the cache page + * might get updated before it gets to the wire + */ + send_async = false; + } + } + + /* XBZRLE overflow or normal page */ + if (bytes_sent == -1) { + bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE); + if (send_async) { + qemu_put_buffer_async(f, p, TARGET_PAGE_SIZE); + } else { + qemu_put_buffer(f, p, TARGET_PAGE_SIZE); + } + bytes_sent += TARGET_PAGE_SIZE; + acct_info.norm_pages++; + } + + XBZRLE_cache_unlock(); + + return bytes_sent; +} + +/* + * ram_find_and_save_block: Finds a page to send and sends it to f * * Returns: The number of bytes written. * 0 means no dirty pages */ -static int ram_save_block(QEMUFile *f, bool last_stage) +static int ram_find_and_save_block(QEMUFile *f, bool last_stage) { RAMBlock *block = last_seen_block; ram_addr_t offset = last_offset; bool complete_round = false; int bytes_sent = 0; MemoryRegion *mr; - ram_addr_t current_addr; if (!block) block = QTAILQ_FIRST(&ram_list.blocks); @@ -594,64 +669,8 @@ static int ram_save_block(QEMUFile *f, bool last_stage) ram_bulk_stage = false; } } else { - int ret; - uint8_t *p; - bool send_async = true; - int cont = (block == last_sent_block) ? - RAM_SAVE_FLAG_CONTINUE : 0; - - p = memory_region_get_ram_ptr(mr) + offset; - - /* In doubt sent page as normal */ - bytes_sent = -1; - ret = ram_control_save_page(f, block->offset, - offset, TARGET_PAGE_SIZE, &bytes_sent); - - XBZRLE_cache_lock(); - - current_addr = block->offset + offset; - if (ret != RAM_SAVE_CONTROL_NOT_SUPP) { - if (ret != RAM_SAVE_CONTROL_DELAYED) { - if (bytes_sent > 0) { - acct_info.norm_pages++; - } else if (bytes_sent == 0) { - acct_info.dup_pages++; - } - } - } else if (is_zero_range(p, TARGET_PAGE_SIZE)) { - acct_info.dup_pages++; - bytes_sent = save_block_hdr(f, block, offset, cont, - RAM_SAVE_FLAG_COMPRESS); - qemu_put_byte(f, 0); - bytes_sent++; - /* Must let xbzrle know, otherwise a previous (now 0'd) cached - * page would be stale - */ - xbzrle_cache_zero_page(current_addr); - } else if (!ram_bulk_stage && migrate_use_xbzrle()) { - bytes_sent = save_xbzrle_page(f, &p, current_addr, block, - offset, cont, last_stage); - if (!last_stage) { - /* Can't send this cached data async, since the cache page - * might get updated before it gets to the wire - */ - send_async = false; - } - } + bytes_sent = ram_save_page(f, block, offset, last_stage); - /* XBZRLE overflow or normal page */ - if (bytes_sent == -1) { - bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE); - if (send_async) { - qemu_put_buffer_async(f, p, TARGET_PAGE_SIZE); - } else { - qemu_put_buffer(f, p, TARGET_PAGE_SIZE); - } - bytes_sent += TARGET_PAGE_SIZE; - acct_info.norm_pages++; - } - - XBZRLE_cache_unlock(); /* if page is unmodified, continue to the next */ if (bytes_sent > 0) { last_sent_block = block; @@ -722,7 +741,6 @@ static void migration_end(void) 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; @@ -850,7 +868,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque) while ((ret = qemu_file_rate_limit(f)) == 0) { int bytes_sent; - bytes_sent = ram_save_block(f, false); + bytes_sent = ram_find_and_save_block(f, false); /* no more blocks to sent */ if (bytes_sent == 0) { break; @@ -912,7 +930,7 @@ static int ram_save_complete(QEMUFile *f, void *opaque) while (true) { int bytes_sent; - bytes_sent = ram_save_block(f, true); + bytes_sent = ram_find_and_save_block(f, true); /* no more blocks to sent */ if (bytes_sent == 0) { break; @@ -958,12 +976,12 @@ static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host) xh_len = qemu_get_be16(f); if (xh_flags != ENCODING_FLAG_XBZRLE) { - fprintf(stderr, "Failed to load XBZRLE page - wrong compression!\n"); + error_report("Failed to load XBZRLE page - wrong compression!"); return -1; } if (xh_len > TARGET_PAGE_SIZE) { - fprintf(stderr, "Failed to load XBZRLE page - len overflow!\n"); + error_report("Failed to load XBZRLE page - len overflow!"); return -1; } /* load data and decode */ @@ -972,7 +990,7 @@ static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host) /* decode RLE */ if (xbzrle_decode_buffer(xbzrle_decoded_buf, xh_len, host, TARGET_PAGE_SIZE) == -1) { - fprintf(stderr, "Failed to load XBZRLE page - decode error!\n"); + error_report("Failed to load XBZRLE page - decode error!"); return -1; } @@ -989,7 +1007,7 @@ static inline void *host_from_stream_offset(QEMUFile *f, if (flags & RAM_SAVE_FLAG_CONTINUE) { if (!block) { - fprintf(stderr, "Ack, bad migration stream!\n"); + error_report("Ack, bad migration stream!"); return NULL; } @@ -1005,7 +1023,7 @@ static inline void *host_from_stream_offset(QEMUFile *f, return memory_region_get_ram_ptr(block->mr) + offset; } - fprintf(stderr, "Can't find block %s!\n", id); + error_report("Can't find block %s!", id); return NULL; } @@ -1024,17 +1042,15 @@ 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; seq_iter++; if (version_id != 4) { ret = -EINVAL; - goto done; } - do { + while (!ret) { addr = qemu_get_be64(f); flags = addr & ~TARGET_PAGE_MASK; @@ -1058,36 +1074,35 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) QTAILQ_FOREACH(block, &ram_list.blocks, next) { if (!strncmp(id, block->idstr, sizeof(id))) { if (block->length != length) { - fprintf(stderr, - "Length mismatch: %s: " RAM_ADDR_FMT - " in != " RAM_ADDR_FMT "\n", id, length, - block->length); + error_report("Length mismatch: %s: 0x" RAM_ADDR_FMT + " in != 0x" RAM_ADDR_FMT, id, length, + block->length); ret = -EINVAL; - goto done; } break; } } if (!block) { - fprintf(stderr, "Unknown ramblock \"%s\", cannot " - "accept migration\n", id); + error_report("Unknown ramblock \"%s\", cannot " + "accept migration", id); ret = -EINVAL; - goto done; + } + if (ret) { + break; } total_ram_bytes -= length; } - } - - if (flags & RAM_SAVE_FLAG_COMPRESS) { + } else if (flags & RAM_SAVE_FLAG_COMPRESS) { void *host; uint8_t ch; 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); @@ -1097,33 +1112,39 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) 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); 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; - goto done; + break; } } else if (flags & RAM_SAVE_FLAG_HOOK) { ram_control_load_hook(f, flags); + } else if (flags & RAM_SAVE_FLAG_EOS) { + /* normal exit */ + break; + } else { + error_report("Unknown migration flags: %#x", flags); + ret = -EINVAL; + break; } - error = qemu_file_get_error(f); - if (error) { - ret = error; - goto done; - } - } while (!(flags & RAM_SAVE_FLAG_EOS)); + ret = qemu_file_get_error(f); + } -done: DPRINTF("Completed load of VM with exit code %d seq iteration " "%" PRIu64 "\n", ret, seq_iter); return ret; @@ -1226,12 +1247,11 @@ void select_soundhw(const char *optarg) if (!c->name) { if (l > 80) { - fprintf(stderr, - "Unknown sound card name (too big to show)\n"); + error_report("Unknown sound card name (too big to show)"); } else { - fprintf(stderr, "Unknown sound card name `%.*s'\n", - (int) l, p); + error_report("Unknown sound card name `%.*s'", + (int) l, p); } bad_card = 1; } @@ -1254,13 +1274,13 @@ void audio_init(void) if (c->enabled) { if (c->isa) { if (!isa_bus) { - fprintf(stderr, "ISA bus not available for %s\n", c->name); + error_report("ISA bus not available for %s", c->name); exit(1); } c->init.init_isa(isa_bus); } else { if (!pci_bus) { - fprintf(stderr, "PCI bus not available for %s\n", c->name); + error_report("PCI bus not available for %s", c->name); exit(1); } c->init.init_pci(pci_bus); @@ -1317,11 +1337,6 @@ void cpudef_init(void) #endif } -int tcg_available(void) -{ - return 1; -} - int kvm_available(void) { #ifdef CONFIG_KVM