diff options
| -rw-r--r-- | block/backup.c | 2 | ||||
| -rw-r--r-- | block/curl.c | 15 | ||||
| -rw-r--r-- | block/mirror.c | 24 | ||||
| -rw-r--r-- | blockdev.c | 7 | ||||
| -rw-r--r-- | hw/arm/boot.c | 28 | ||||
| -rw-r--r-- | include/hw/i386/pc.h | 68 | ||||
| -rw-r--r-- | include/migration/migration.h | 1 | ||||
| -rw-r--r-- | migration/migration.c | 52 | ||||
| -rw-r--r-- | migration/ram.c | 10 | ||||
| -rw-r--r-- | migration/savevm.c | 6 | ||||
| -rw-r--r-- | numa.c | 3 | ||||
| -rw-r--r-- | qmp-commands.hx | 1 | ||||
| -rw-r--r-- | target-arm/helper.c | 1 | ||||
| -rw-r--r-- | target-i386/cpu.c | 39 | ||||
| -rw-r--r-- | vl.c | 2 |
15 files changed, 193 insertions, 66 deletions
diff --git a/block/backup.c b/block/backup.c index d3c7d9f85d..965654d521 100644 --- a/block/backup.c +++ b/block/backup.c @@ -431,7 +431,7 @@ static void coroutine_fn backup_run(void *opaque) if (job->sync_bitmap) { BdrvDirtyBitmap *bm; - if (ret < 0) { + if (ret < 0 || block_job_is_cancelled(&job->common)) { /* Merge the successor back into the parent, delete nothing. */ bm = bdrv_reclaim_dirty_bitmap(bs, job->sync_bitmap, NULL); assert(bm); diff --git a/block/curl.c b/block/curl.c index 3a2b63e16e..032cc8ae22 100644 --- a/block/curl.c +++ b/block/curl.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu-common.h" +#include "qemu/error-report.h" #include "block/block_int.h" #include "qapi/qmp/qbool.h" #include "qapi/qmp/qstring.h" @@ -298,6 +299,18 @@ static void curl_multi_check_completion(BDRVCURLState *s) /* ACBs for successful messages get completed in curl_read_cb */ if (msg->data.result != CURLE_OK) { int i; + static int errcount = 100; + + /* Don't lose the original error message from curl, since + * it contains extra data. + */ + if (errcount > 0) { + error_report("curl: %s", state->errmsg); + if (--errcount == 0) { + error_report("curl: further errors suppressed"); + } + } + for (i = 0; i < CURL_NUM_ACB; i++) { CURLAIOCB *acb = state->acb[i]; @@ -305,7 +318,7 @@ static void curl_multi_check_completion(BDRVCURLState *s) continue; } - acb->common.cb(acb->common.opaque, -EIO); + acb->common.cb(acb->common.opaque, -EPROTO); qemu_aio_unref(acb); state->acb[i] = NULL; } diff --git a/block/mirror.c b/block/mirror.c index d409337c4a..323f747c75 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -20,6 +20,7 @@ #define SLICE_TIME 100000000ULL /* ns */ #define MAX_IN_FLIGHT 16 +#define DEFAULT_MIRROR_BUF_SIZE (10 << 20) /* The mirroring buffer is a list of granularity-sized chunks. * Free chunks are organized in a list. @@ -444,11 +445,23 @@ static void coroutine_fn mirror_run(void *opaque) sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS; mirror_free_init(s); + last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); if (!s->is_none_mode) { /* First part, loop on the sectors and initialize the dirty bitmap. */ BlockDriverState *base = s->base; for (sector_num = 0; sector_num < end; ) { int64_t next = (sector_num | (sectors_per_chunk - 1)) + 1; + int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); + + if (now - last_pause_ns > SLICE_TIME) { + last_pause_ns = now; + block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0); + } + + if (block_job_is_cancelled(&s->common)) { + goto immediate_exit; + } + ret = bdrv_is_allocated_above(bs, base, sector_num, next - sector_num, &n); @@ -467,7 +480,6 @@ static void coroutine_fn mirror_run(void *opaque) } bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi); - last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); for (;;) { uint64_t delay_ns = 0; int64_t cnt; @@ -690,6 +702,14 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target, return; } + if (buf_size < 0) { + error_setg(errp, "Invalid parameter 'buf-size'"); + return; + } + + if (buf_size == 0) { + buf_size = DEFAULT_MIRROR_BUF_SIZE; + } s = block_job_create(driver, bs, speed, cb, opaque, errp); if (!s) { @@ -703,7 +723,7 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target, s->is_none_mode = is_none_mode; s->base = base; s->granularity = granularity; - s->buf_size = MAX(buf_size, granularity); + s->buf_size = ROUND_UP(buf_size, granularity); s->unmap = unmap; s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp); diff --git a/blockdev.c b/blockdev.c index 7fee519a1c..62a4586cd6 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2380,9 +2380,6 @@ void qmp_block_commit(const char *device, aio_context = bdrv_get_aio_context(bs); aio_context_acquire(aio_context); - /* drain all i/o before commits */ - bdrv_drain_all(); - if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT_SOURCE, errp)) { goto out; } @@ -2642,8 +2639,6 @@ out: aio_context_release(aio_context); } -#define DEFAULT_MIRROR_BUF_SIZE (10 << 20) - void qmp_drive_mirror(const char *device, const char *target, bool has_format, const char *format, bool has_node_name, const char *node_name, @@ -2685,7 +2680,7 @@ void qmp_drive_mirror(const char *device, const char *target, granularity = 0; } if (!has_buf_size) { - buf_size = DEFAULT_MIRROR_BUF_SIZE; + buf_size = 0; } if (!has_unmap) { unmap = true; diff --git a/hw/arm/boot.c b/hw/arm/boot.c index f48ed2d34d..5b969cda1c 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -735,12 +735,28 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data) * we point to the kernel args. */ if (have_dtb(info)) { - /* Place the DTB after the initrd in memory. Note that some - * kernels will trash anything in the 4K page the initrd - * ends in, so make sure the DTB isn't caught up in that. - */ - hwaddr dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size, - 4096); + hwaddr align; + hwaddr dtb_start; + + if (elf_machine == EM_AARCH64) { + /* + * Some AArch64 kernels on early bootup map the fdt region as + * + * [ ALIGN_DOWN(fdt, 2MB) ... ALIGN_DOWN(fdt, 2MB) + 2MB ] + * + * Let's play safe and prealign it to 2MB to give us some space. + */ + align = 2 * 1024 * 1024; + } else { + /* + * Some 32bit kernels will trash anything in the 4K page the + * initrd ends in, so make sure the DTB isn't caught up in that. + */ + align = 4096; + } + + /* Place the DTB after the initrd in memory with alignment. */ + dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size, align); if (load_dtb(dtb_start, info, 0) < 0) { exit(1); } diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 15e3352967..c4165740cf 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -298,6 +298,74 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .driver = TYPE_X86_CPU,\ .property = "arat",\ .value = "off",\ + },{\ + .driver = "qemu64" "-" TYPE_X86_CPU,\ + .property = "level",\ + .value = stringify(4),\ + },{\ + .driver = "kvm64" "-" TYPE_X86_CPU,\ + .property = "level",\ + .value = stringify(5),\ + },{\ + .driver = "pentium3" "-" TYPE_X86_CPU,\ + .property = "level",\ + .value = stringify(2),\ + },{\ + .driver = "n270" "-" TYPE_X86_CPU,\ + .property = "level",\ + .value = stringify(5),\ + },{\ + .driver = "Conroe" "-" TYPE_X86_CPU,\ + .property = "level",\ + .value = stringify(4),\ + },{\ + .driver = "Penryn" "-" TYPE_X86_CPU,\ + .property = "level",\ + .value = stringify(4),\ + },{\ + .driver = "Nehalem" "-" TYPE_X86_CPU,\ + .property = "level",\ + .value = stringify(4),\ + },{\ + .driver = "n270" "-" TYPE_X86_CPU,\ + .property = "xlevel",\ + .value = stringify(0x8000000a),\ + },{\ + .driver = "Penryn" "-" TYPE_X86_CPU,\ + .property = "xlevel",\ + .value = stringify(0x8000000a),\ + },{\ + .driver = "Conroe" "-" TYPE_X86_CPU,\ + .property = "xlevel",\ + .value = stringify(0x8000000a),\ + },{\ + .driver = "Nehalem" "-" TYPE_X86_CPU,\ + .property = "xlevel",\ + .value = stringify(0x8000000a),\ + },{\ + .driver = "Westmere" "-" TYPE_X86_CPU,\ + .property = "xlevel",\ + .value = stringify(0x8000000a),\ + },{\ + .driver = "SandyBridge" "-" TYPE_X86_CPU,\ + .property = "xlevel",\ + .value = stringify(0x8000000a),\ + },{\ + .driver = "Haswell" "-" TYPE_X86_CPU,\ + .property = "xlevel",\ + .value = stringify(0x8000000a),\ + },{\ + .driver = "Haswell-noTSX" "-" TYPE_X86_CPU,\ + .property = "xlevel",\ + .value = stringify(0x8000000a),\ + },{\ + .driver = "Broadwell" "-" TYPE_X86_CPU,\ + .property = "xlevel",\ + .value = stringify(0x8000000a),\ + },{\ + .driver = "Broadwell-noTSX" "-" TYPE_X86_CPU,\ + .property = "xlevel",\ + .value = stringify(0x8000000a),\ }, #define PC_COMPAT_2_2 \ diff --git a/include/migration/migration.h b/include/migration/migration.h index b2711ef305..a2f8ed093c 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -202,4 +202,5 @@ void savevm_skip_section_footers(void); void register_global_state(void); void global_state_set_optional(void); void savevm_skip_configuration(void); +int global_state_store(void); #endif diff --git a/migration/migration.c b/migration/migration.c index 45719a0f5f..86ca099ac4 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -104,11 +104,13 @@ typedef struct { bool optional; uint32_t size; uint8_t runstate[100]; + RunState state; + bool received; } GlobalState; static GlobalState global_state; -static int global_state_store(void) +int global_state_store(void) { if (!runstate_store((char *)global_state.runstate, sizeof(global_state.runstate))) { @@ -119,9 +121,14 @@ static int global_state_store(void) return 0; } -static char *global_state_get_runstate(void) +static bool global_state_received(void) { - return (char *)global_state.runstate; + return global_state.received; +} + +static RunState global_state_get_runstate(void) +{ + return global_state.state; } void global_state_set_optional(void) @@ -154,26 +161,25 @@ static bool global_state_needed(void *opaque) static int global_state_post_load(void *opaque, int version_id) { GlobalState *s = opaque; - int ret = 0; + Error *local_err = NULL; + int r; char *runstate = (char *)s->runstate; + s->received = true; trace_migrate_global_state_post_load(runstate); - if (strcmp(runstate, "running") != 0) { - Error *local_err = NULL; - int r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE_MAX, + r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE_MAX, -1, &local_err); - if (r == -1) { - if (local_err) { - error_report_err(local_err); - } - return -EINVAL; + if (r == -1) { + if (local_err) { + error_report_err(local_err); } - ret = vm_stop_force_state(r); + return -EINVAL; } + s->state = r; - return ret; + return 0; } static void global_state_pre_save(void *opaque) @@ -202,6 +208,7 @@ void register_global_state(void) { /* We would use it independently that we receive it */ strcpy((char *)&global_state.runstate, ""); + global_state.received = false; vmstate_register(NULL, 0, &vmstate_globalstate, &global_state); } @@ -209,7 +216,6 @@ static void migrate_generate_event(int new_state) { if (migrate_use_events()) { qapi_event_send_migration(new_state, &error_abort); - trace_migrate_set_state(new_state); } } @@ -283,20 +289,19 @@ static void process_incoming_migration_co(void *opaque) exit(EXIT_FAILURE); } - /* runstate == "" means that we haven't received it through the - * wire, so we obey autostart. runstate == runing means that we - * need to run it, we need to make sure that we do it after - * everything else has finished. Every other state change is done - * at the post_load function */ + /* If global state section was not received or we are in running + state, we need to obey autostart. Any other state is set with + runstate_set. */ - if (strcmp(global_state_get_runstate(), "running") == 0) { - vm_start(); - } else if (strcmp(global_state_get_runstate(), "") == 0) { + if (!global_state_received() || + global_state_get_runstate() == RUN_STATE_RUNNING) { if (autostart) { vm_start(); } else { runstate_set(RUN_STATE_PAUSED); } + } else { + runstate_set(global_state_get_runstate()); } migrate_decompress_threads_join(); } @@ -522,6 +527,7 @@ void qmp_migrate_set_parameters(bool has_compress_level, static void migrate_set_state(MigrationState *s, int old_state, int new_state) { if (atomic_cmpxchg(&s->state, old_state, new_state) == old_state) { + trace_migrate_set_state(new_state); migrate_generate_event(new_state); } } diff --git a/migration/ram.c b/migration/ram.c index 1e58cd3924..7f007e6432 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -382,16 +382,16 @@ void migrate_compress_threads_create(void) */ static size_t save_page_header(QEMUFile *f, RAMBlock *block, ram_addr_t offset) { - size_t size; + size_t size, len; qemu_put_be64(f, offset); size = 8; if (!(offset & RAM_SAVE_FLAG_CONTINUE)) { - qemu_put_byte(f, strlen(block->idstr)); - qemu_put_buffer(f, (uint8_t *)block->idstr, - strlen(block->idstr)); - size += 1 + strlen(block->idstr); + len = strlen(block->idstr); + qemu_put_byte(f, len); + qemu_put_buffer(f, (uint8_t *)block->idstr, len); + size += 1 + len; } return size; } diff --git a/migration/savevm.c b/migration/savevm.c index 86735fc53a..81dbe5879f 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1315,6 +1315,12 @@ void hmp_savevm(Monitor *mon, const QDict *qdict) } saved_vm_running = runstate_is_running(); + + ret = global_state_store(); + if (ret) { + monitor_printf(mon, "Error saving global state\n"); + return; + } vm_stop(RUN_STATE_SAVE_VM); memset(sn, 0, sizeof(*sn)); diff --git a/numa.c b/numa.c index 3c8005913f..402804bdf4 100644 --- a/numa.c +++ b/numa.c @@ -54,7 +54,7 @@ NodeInfo numa_info[MAX_NODES]; void numa_set_mem_node_id(ram_addr_t addr, uint64_t size, uint32_t node) { - struct numa_addr_range *range = g_malloc0(sizeof(*range)); + struct numa_addr_range *range; /* * Memory-less nodes can come here with 0 size in which case, @@ -64,6 +64,7 @@ void numa_set_mem_node_id(ram_addr_t addr, uint64_t size, uint32_t node) return; } + range = g_malloc0(sizeof(*range)); range->mem_start = addr; range->mem_end = addr + size - 1; QLIST_INSERT_HEAD(&numa_info[node].addr, range, entry); diff --git a/qmp-commands.hx b/qmp-commands.hx index e1bcc60380..ba630b1e7f 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -3406,6 +3406,7 @@ Enable/Disable migration capabilities - "rdma-pin-all": pin all pages when using RDMA during migration - "auto-converge": throttle down guest to help convergence of migration - "zero-blocks": compress zero blocks during block migration +- "events": generate events for each migration state change Arguments: diff --git a/target-arm/helper.c b/target-arm/helper.c index b87afe7cde..01f0d0dac9 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2752,6 +2752,7 @@ static const ARMCPRegInfo el3_cp_reginfo[] = { .access = PL3_RW, .writefn = vbar_write, .resetvalue = 0, .fieldoffset = offsetof(CPUARMState, cp15.mvbar) }, { .name = "SCTLR_EL3", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_ALIAS, /* reset handled by AArch32 view */ .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 0, .access = PL3_RW, .raw_writefn = raw_write, .writefn = sctlr_write, .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[3]) }, diff --git a/target-i386/cpu.c b/target-i386/cpu.c index f9b1788cbd..7a779b1653 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -695,7 +695,7 @@ struct X86CPUDefinition { static X86CPUDefinition builtin_x86_defs[] = { { .name = "qemu64", - .level = 4, + .level = 0xd, .vendor = CPUID_VENDOR_AMD, .family = 6, .model = 6, @@ -771,7 +771,7 @@ static X86CPUDefinition builtin_x86_defs[] = { }, { .name = "kvm64", - .level = 5, + .level = 0xd, .vendor = CPUID_VENDOR_INTEL, .family = 15, .model = 6, @@ -882,7 +882,7 @@ static X86CPUDefinition builtin_x86_defs[] = { }, { .name = "pentium3", - .level = 2, + .level = 3, .vendor = CPUID_VENDOR_INTEL, .family = 6, .model = 7, @@ -907,8 +907,7 @@ static X86CPUDefinition builtin_x86_defs[] = { }, { .name = "n270", - /* original is on level 10 */ - .level = 5, + .level = 10, .vendor = CPUID_VENDOR_INTEL, .family = 6, .model = 28, @@ -928,12 +927,12 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT2_NX, .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM, - .xlevel = 0x8000000A, + .xlevel = 0x80000008, .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz", }, { .name = "Conroe", - .level = 4, + .level = 10, .vendor = CPUID_VENDOR_INTEL, .family = 6, .model = 15, @@ -950,12 +949,12 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM, - .xlevel = 0x8000000A, + .xlevel = 0x80000008, .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)", }, { .name = "Penryn", - .level = 4, + .level = 10, .vendor = CPUID_VENDOR_INTEL, .family = 6, .model = 23, @@ -973,12 +972,12 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM, - .xlevel = 0x8000000A, + .xlevel = 0x80000008, .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)", }, { .name = "Nehalem", - .level = 4, + .level = 11, .vendor = CPUID_VENDOR_INTEL, .family = 6, .model = 26, @@ -996,7 +995,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM, - .xlevel = 0x8000000A, + .xlevel = 0x80000008, .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)", }, { @@ -1022,7 +1021,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT3_LAHF_LM, .features[FEAT_6_EAX] = CPUID_6_EAX_ARAT, - .xlevel = 0x8000000A, + .xlevel = 0x80000008, .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)", }, { @@ -1053,7 +1052,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_XSAVE_XSAVEOPT, .features[FEAT_6_EAX] = CPUID_6_EAX_ARAT, - .xlevel = 0x8000000A, + .xlevel = 0x80000008, .model_id = "Intel Xeon E312xx (Sandy Bridge)", }, { @@ -1087,7 +1086,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_XSAVE_XSAVEOPT, .features[FEAT_6_EAX] = CPUID_6_EAX_ARAT, - .xlevel = 0x8000000A, + .xlevel = 0x80000008, .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)", }, { @@ -1123,7 +1122,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_XSAVE_XSAVEOPT, .features[FEAT_6_EAX] = CPUID_6_EAX_ARAT, - .xlevel = 0x8000000A, + .xlevel = 0x80000008, .model_id = "Intel Core Processor (Haswell, no TSX)", }, { .name = "Haswell", @@ -1159,7 +1158,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_XSAVE_XSAVEOPT, .features[FEAT_6_EAX] = CPUID_6_EAX_ARAT, - .xlevel = 0x8000000A, + .xlevel = 0x80000008, .model_id = "Intel Core Processor (Haswell)", }, { @@ -1197,7 +1196,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_XSAVE_XSAVEOPT, .features[FEAT_6_EAX] = CPUID_6_EAX_ARAT, - .xlevel = 0x8000000A, + .xlevel = 0x80000008, .model_id = "Intel Core Processor (Broadwell, no TSX)", }, { @@ -1235,7 +1234,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_XSAVE_XSAVEOPT, .features[FEAT_6_EAX] = CPUID_6_EAX_ARAT, - .xlevel = 0x8000000A, + .xlevel = 0x80000008, .model_id = "Intel Core Processor (Broadwell)", }, { @@ -3021,7 +3020,7 @@ static void x86_cpu_register_feature_bit_props(X86CPU *cpu, for (i = 1; names[i]; i++) { feat2prop(names[i]); - object_property_add_alias(obj, names[i], obj, g_strdup(names[0]), + object_property_add_alias(obj, names[i], obj, names[0], &error_abort); } diff --git a/vl.c b/vl.c index 3f269dc58d..5856396d46 100644 --- a/vl.c +++ b/vl.c @@ -4615,6 +4615,7 @@ int main(int argc, char **argv, char **envp) } qemu_system_reset(VMRESET_SILENT); + register_global_state(); if (loadvm) { if (load_vmstate(loadvm) < 0) { autostart = 0; @@ -4628,7 +4629,6 @@ int main(int argc, char **argv, char **envp) return 0; } - register_global_state(); if (incoming) { Error *local_err = NULL; qemu_start_incoming_migration(incoming, &local_err); |