x86 and machine queue, 2016-07-27

Highlights:
 * Fixes to allow CPU hotplug/unplug in any order;
 * Exit QEMU on invalid global properties.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJXmMUlAAoJECgHk2+YTcWmLooP/ioPaesxxcz4u7SMS2h6c12z
 shC2ERzGNeB+d6KZvscYG/fbR5SV3P1JAtOE5+BbiVvnZRbyvv0NaYhPlnLV/P5C
 KKIK3uimaSNyxaDF7zZiImZWLWq8vl51SXITIQenrCjPYPE6q32m3pvlbGJvVi8P
 x4lW9LMyRG1a2yOqF9nt+eTqkcigSj6z9cL8MQRoSnDhkXAh/q3ySofKfJ9RAhWQ
 tGg5xIa+B/0mjZQwS2e0vnDnVxeYRgQ0o7sdZJD9zjgog8HTKX2cei0b/+FINAKM
 bzDAQI97ECsWQ8MxXdcXsu9dHr7mwovmpBvecsU0DZtWnMv0vmd0OxmWJXoI4uh2
 4rcg576z9rQU7eA4CbU7Wh4PTeKcKYvjocIQlMN2mgrVNZK7FXsRDdUdyusE8JQC
 HHc/990kboC2Ui1MPi/QJm1RvA8+ofAk3py8DK5ixYvBPfeLxtcgHM8d3MpgeLbp
 jG1DgnhEcO5lg29vWUsPM8XujUdPSJ8sgJtjCQIiACKgpZhuYKHirrnq+TNtd0Ly
 qVrlVNWUuT0zWb9/kRgtcczgXFzP2+DQHH4jRc0csyFtxolt5SmA2tZ3vnlXnoUn
 SIOH4V16aY3tndt/uAJh7+Qo1ZsGoeTqzrFWYLdpynDxpNwjWcaLenJ9MogUmbWh
 FK+cKsazPWn3MOCxjhgj
 =2Abo
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Peter Maydell 2016-07-27 18:18:21 +01:00
commit 21a21b853a
12 changed files with 47 additions and 97 deletions

View File

@ -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);

66
exec.c
View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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)

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -883,4 +883,6 @@ extern const struct VMStateDescription vmstate_cpu_common;
.offset = 0, \
}
#define UNASSIGNED_CPU_INDEX -1
#endif

View File

@ -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);

View File

@ -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);

1
vl.c
View File

@ -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;
}