mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-24 03:59:52 +00:00
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:
commit
21a21b853a
@ -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
66
exec.c
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
38
hw/i386/pc.c
38
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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -883,4 +883,6 @@ extern const struct VMStateDescription vmstate_cpu_common;
|
||||
.offset = 0, \
|
||||
}
|
||||
|
||||
#define UNASSIGNED_CPU_INDEX -1
|
||||
|
||||
#endif
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user