diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-07-27 18:18:21 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-07-27 18:18:21 +0100 |
commit | 21a21b853a1bb606358af61e738abfb9aecbd720 (patch) | |
tree | 154ad3f9e601dff25552a9e68c666d6cce7a4706 | |
parent | 51313fe4f4afea65970a20b32ed2d35b44fbf993 (diff) | |
parent | 03f28efbbb0ee521611e0eb28b45096b3598fb34 (diff) | |
download | qemu-21a21b853a1bb606358af61e738abfb9aecbd720.zip qemu-21a21b853a1bb606358af61e738abfb9aecbd720.tar.gz qemu-21a21b853a1bb606358af61e738abfb9aecbd720.tar.bz2 |
Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging
x86 and machine queue, 2016-07-27
Highlights:
* Fixes to allow CPU hotplug/unplug in any order;
* Exit QEMU on invalid global properties.
# gpg: Signature made Wed 27 Jul 2016 15:28:53 BST
# gpg: using RSA key 0x2807936F984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF D1AA 2807 936F 984D C5A6
* remotes/ehabkost/tags/x86-pull-request:
vl: exit if a bad property value is passed to -global
qdev: ignore GlobalProperty.errp for hotplugged devices
machine: Add comment to abort path in machine_set_kernel_irqchip
Revert "pc: Enforce adding CPUs contiguously and removing them in opposite order"
pc: Init CPUState->cpu_index with index in possible_cpus[]
qdev: Fix object reference leak in case device.realize() fails
exec: Set cpu_index only if it's not been explictly set
exec: Don't use cpu_index to detect if cpu_exec_init()'s been called
exec: Reduce CONFIG_USER_ONLY ifdeffenery
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | bsd-user/qemu.h | 2 | ||||
-rw-r--r-- | exec.c | 66 | ||||
-rw-r--r-- | hw/core/machine.c | 3 | ||||
-rw-r--r-- | hw/core/qdev-properties.c | 4 | ||||
-rw-r--r-- | hw/core/qdev.c | 8 | ||||
-rw-r--r-- | hw/i386/pc.c | 38 | ||||
-rw-r--r-- | include/exec/exec-all.h | 12 | ||||
-rw-r--r-- | include/hw/qdev-core.h | 4 | ||||
-rw-r--r-- | include/qom/cpu.h | 2 | ||||
-rw-r--r-- | linux-user/qemu.h | 2 | ||||
-rw-r--r-- | qom/cpu.c | 2 | ||||
-rw-r--r-- | vl.c | 1 |
12 files changed, 47 insertions, 97 deletions
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index 6ccc544..2b2b918 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -209,8 +209,6 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, abi_ulong new_addr); int target_msync(abi_ulong start, abi_ulong len, int flags); extern unsigned long last_brk; -void cpu_list_lock(void); -void cpu_list_unlock(void); #if defined(CONFIG_USE_NPTL) void mmap_fork_start(void); void mmap_fork_end(int child); @@ -598,30 +598,7 @@ AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx) } #endif -#ifndef CONFIG_USER_ONLY -static DECLARE_BITMAP(cpu_index_map, MAX_CPUMASK_BITS); - -static int cpu_get_free_index(Error **errp) -{ - int cpu = find_first_zero_bit(cpu_index_map, MAX_CPUMASK_BITS); - - if (cpu >= MAX_CPUMASK_BITS) { - error_setg(errp, "Trying to use more CPUs than max of %d", - MAX_CPUMASK_BITS); - return -1; - } - - bitmap_set(cpu_index_map, cpu, 1); - return cpu; -} - -static void cpu_release_index(CPUState *cpu) -{ - bitmap_clear(cpu_index_map, cpu->cpu_index, 1); -} -#else - -static int cpu_get_free_index(Error **errp) +static int cpu_get_free_index(void) { CPUState *some_cpu; int cpu_index = 0; @@ -632,33 +609,21 @@ static int cpu_get_free_index(Error **errp) return cpu_index; } -static void cpu_release_index(CPUState *cpu) -{ - return; -} -#endif - void cpu_exec_exit(CPUState *cpu) { CPUClass *cc = CPU_GET_CLASS(cpu); -#if defined(CONFIG_USER_ONLY) cpu_list_lock(); -#endif - if (cpu->cpu_index == -1) { - /* cpu_index was never allocated by this @cpu or was already freed. */ -#if defined(CONFIG_USER_ONLY) + if (cpu->node.tqe_prev == NULL) { + /* there is nothing to undo since cpu_exec_init() hasn't been called */ cpu_list_unlock(); -#endif return; } QTAILQ_REMOVE(&cpus, cpu, node); - cpu_release_index(cpu); - cpu->cpu_index = -1; -#if defined(CONFIG_USER_ONLY) + cpu->node.tqe_prev = NULL; + cpu->cpu_index = UNASSIGNED_CPU_INDEX; cpu_list_unlock(); -#endif if (cc->vmsd != NULL) { vmstate_unregister(NULL, cc->vmsd, cpu); @@ -670,8 +635,8 @@ void cpu_exec_exit(CPUState *cpu) void cpu_exec_init(CPUState *cpu, Error **errp) { - CPUClass *cc = CPU_GET_CLASS(cpu); - Error *local_err = NULL; + CPUClass *cc ATTRIBUTE_UNUSED = CPU_GET_CLASS(cpu); + Error *local_err ATTRIBUTE_UNUSED = NULL; cpu->as = NULL; cpu->num_ases = 0; @@ -694,22 +659,15 @@ void cpu_exec_init(CPUState *cpu, Error **errp) object_ref(OBJECT(cpu->memory)); #endif -#if defined(CONFIG_USER_ONLY) cpu_list_lock(); -#endif - cpu->cpu_index = cpu_get_free_index(&local_err); - if (local_err) { - error_propagate(errp, local_err); -#if defined(CONFIG_USER_ONLY) - cpu_list_unlock(); -#endif - return; + if (cpu->cpu_index == UNASSIGNED_CPU_INDEX) { + cpu->cpu_index = cpu_get_free_index(); + assert(cpu->cpu_index != UNASSIGNED_CPU_INDEX); } QTAILQ_INSERT_TAIL(&cpus, cpu, node); -#if defined(CONFIG_USER_ONLY) - (void) cc; cpu_list_unlock(); -#else + +#ifndef CONFIG_USER_ONLY if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu); } diff --git a/hw/core/machine.c b/hw/core/machine.c index 2fe6ff6..e5a456f 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -65,6 +65,9 @@ static void machine_set_kernel_irqchip(Object *obj, Visitor *v, ms->kernel_irqchip_split = true; break; default: + /* The value was checked in visit_type_OnOffSplit() above. If + * we get here, then something is wrong in QEMU. + */ abort(); } } diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 14e544a..311af6d 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -1084,7 +1084,7 @@ int qdev_prop_check_globals(void) } static void qdev_prop_set_globals_for_type(DeviceState *dev, - const char *typename) + const char *typename) { GList *l; @@ -1100,7 +1100,7 @@ static void qdev_prop_set_globals_for_type(DeviceState *dev, if (err != NULL) { error_prepend(&err, "can't apply global %s.%s=%s: ", prop->driver, prop->property, prop->value); - if (prop->errp) { + if (!dev->hotplugged && prop->errp) { error_propagate(prop->errp, err); } else { assert(prop->user_provided); diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 6680089..ee4a083 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -885,6 +885,8 @@ static void device_set_realized(Object *obj, bool value, Error **errp) HotplugHandler *hotplug_ctrl; BusState *bus; Error *local_err = NULL; + bool unattached_parent = false; + static int unattached_count; if (dev->hotplugged && !dc->hotpluggable) { error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj)); @@ -893,12 +895,12 @@ static void device_set_realized(Object *obj, bool value, Error **errp) if (value && !dev->realized) { if (!obj->parent) { - static int unattached_count; gchar *name = g_strdup_printf("device[%d]", unattached_count++); object_property_add_child(container_get(qdev_get_machine(), "/unattached"), name, obj, &error_abort); + unattached_parent = true; g_free(name); } @@ -987,6 +989,10 @@ post_realize_fail: fail: error_propagate(errp, local_err); + if (unattached_parent) { + object_unparent(OBJECT(dev)); + unattached_count--; + } } static bool device_get_hotpluggable(Object *obj, Error **errp) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 9e3c70f..47593b7 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1818,23 +1818,6 @@ static void pc_cpu_unplug_request_cb(HotplugHandler *hotplug_dev, goto out; } - if (idx < pcms->possible_cpus->len - 1 && - pcms->possible_cpus->cpus[idx + 1].cpu != NULL) { - X86CPU *cpu; - - for (idx = pcms->possible_cpus->len - 1; - pcms->possible_cpus->cpus[idx].cpu == NULL; idx--) { - ;; - } - - cpu = X86_CPU(pcms->possible_cpus->cpus[idx].cpu); - error_setg(&local_err, "CPU [socket-id: %u, core-id: %u," - " thread-id: %u] should be removed first", - cpu->socket_id, cpu->core_id, cpu->thread_id); - goto out; - - } - hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); hhc->unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); @@ -1875,6 +1858,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { int idx; + CPUState *cs; CPUArchId *cpu_slot; X86CPUTopoInfo topo; X86CPU *cpu = X86_CPU(dev); @@ -1931,23 +1915,6 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, return; } - if (idx != 0 && pcms->possible_cpus->cpus[idx - 1].cpu == NULL) { - PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); - - for (idx = 1; pcms->possible_cpus->cpus[idx].cpu != NULL; idx++) { - ;; - } - - x86_topo_ids_from_apicid(pcms->possible_cpus->cpus[idx].arch_id, - smp_cores, smp_threads, &topo); - - if (!pcmc->legacy_cpu_hotplug) { - error_setg(errp, "CPU [socket: %u, core: %u, thread: %u] should be" - " added first", topo.pkg_id, topo.core_id, topo.smt_id); - return; - } - } - /* if 'address' properties socket-id/core-id/thread-id are not set, set them * so that query_hotpluggable_cpus would show correct values */ @@ -1975,6 +1942,9 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, return; } cpu->thread_id = topo.smt_id; + + cs = CPU(cpu); + cs->cpu_index = idx; } static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index acda7b6..d008296 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -56,6 +56,18 @@ TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc, target_ulong cs_base, uint32_t flags, int cflags); +#if defined(CONFIG_USER_ONLY) +void cpu_list_lock(void); +void cpu_list_unlock(void); +#else +static inline void cpu_list_unlock(void) +{ +} +static inline void cpu_list_lock(void) +{ +} +#endif + void cpu_exec_init(CPUState *cpu, Error **errp); void QEMU_NORETURN cpu_loop_exit(CPUState *cpu); void QEMU_NORETURN cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 1d1f861..4b4b33b 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -261,7 +261,9 @@ struct PropertyInfo { * @used: Set to true if property was used when initializing a device. * @errp: Error destination, used like first argument of error_setg() * in case property setting fails later. If @errp is NULL, we - * print warnings instead of ignoring errors silently. + * print warnings instead of ignoring errors silently. For + * hotplugged devices, errp is always ignored and warnings are + * printed instead. */ typedef struct GlobalProperty { const char *driver; diff --git a/include/qom/cpu.h b/include/qom/cpu.h index cbcd64c..ce0c406 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -883,4 +883,6 @@ extern const struct VMStateDescription vmstate_cpu_common; .offset = 0, \ } +#define UNASSIGNED_CPU_INDEX -1 + #endif diff --git a/linux-user/qemu.h b/linux-user/qemu.h index cdf23a7..bef465d 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -419,8 +419,6 @@ int target_msync(abi_ulong start, abi_ulong len, int flags); extern unsigned long last_brk; extern abi_ulong mmap_next_start; abi_ulong mmap_find_vma(abi_ulong, abi_ulong); -void cpu_list_lock(void); -void cpu_list_unlock(void); void mmap_fork_start(void); void mmap_fork_end(int child); @@ -340,7 +340,7 @@ static void cpu_common_initfn(Object *obj) CPUState *cpu = CPU(obj); CPUClass *cc = CPU_GET_CLASS(obj); - cpu->cpu_index = -1; + cpu->cpu_index = UNASSIGNED_CPU_INDEX; cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs; qemu_mutex_init(&cpu->work_mutex); QTAILQ_INIT(&cpu->breakpoints); @@ -2922,6 +2922,7 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp) g->property = qemu_opt_get(opts, "property"); g->value = qemu_opt_get(opts, "value"); g->user_provided = true; + g->errp = &error_fatal; qdev_prop_register_global(g); return 0; } |