aboutsummaryrefslogtreecommitdiff
path: root/qom
diff options
context:
space:
mode:
authorLinaro Packagers <linaro-pkg@lists.launchpad.net>2013-08-02 06:39:45 +0000
committerFathi Boudra <fathi.boudra@linaro.org>2013-08-05 10:19:57 +0300
commit3ba5745389cb428bf0f99fdde92ed3876ca5e5c8 (patch)
tree06dc0389b02c64ce9cb23cad85382745c0d6177c /qom
parentc3565b8703553405641c76a4c40961473d051edd (diff)
parent86342dcc9b73eac8310b9dc5fd1356bbfa5b9c8e (diff)
Imported Debian patch 1.5.0-2013.06+git74+20130802+ef1b0ae-3linaroraring1HEADmaster
Diffstat (limited to 'qom')
-rw-r--r--qom/cpu.c128
-rw-r--r--qom/object.c131
2 files changed, 233 insertions, 26 deletions
diff --git a/qom/cpu.c b/qom/cpu.c
index 8fb538b..04aefbb 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -20,6 +20,108 @@
#include "qom/cpu.h"
#include "qemu-common.h"
+#include "sysemu/kvm.h"
+#include "qemu/notify.h"
+#include "sysemu/sysemu.h"
+
+typedef struct CPUExistsArgs {
+ int64_t id;
+ bool found;
+} CPUExistsArgs;
+
+static void cpu_exist_cb(CPUState *cpu, void *data)
+{
+ CPUClass *klass = CPU_GET_CLASS(cpu);
+ CPUExistsArgs *arg = data;
+
+ if (klass->get_arch_id(cpu) == arg->id) {
+ arg->found = true;
+ }
+}
+
+bool cpu_exists(int64_t id)
+{
+ CPUExistsArgs data = {
+ .id = id,
+ .found = false,
+ };
+
+ qemu_for_each_cpu(cpu_exist_cb, &data);
+ return data.found;
+}
+
+/* CPU hot-plug notifiers */
+static NotifierList cpu_added_notifiers =
+ NOTIFIER_LIST_INITIALIZER(cpu_add_notifiers);
+
+void qemu_register_cpu_added_notifier(Notifier *notifier)
+{
+ notifier_list_add(&cpu_added_notifiers, notifier);
+}
+
+void cpu_reset_interrupt(CPUState *cpu, int mask)
+{
+ cpu->interrupt_request &= ~mask;
+}
+
+int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
+ void *opaque)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ return (*cc->write_elf32_qemunote)(f, cpu, opaque);
+}
+
+static int cpu_common_write_elf32_qemunote(WriteCoreDumpFunction f,
+ CPUState *cpu, void *opaque)
+{
+ return -1;
+}
+
+int cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu,
+ int cpuid, void *opaque)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ return (*cc->write_elf32_note)(f, cpu, cpuid, opaque);
+}
+
+static int cpu_common_write_elf32_note(WriteCoreDumpFunction f,
+ CPUState *cpu, int cpuid,
+ void *opaque)
+{
+ return -1;
+}
+
+int cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
+ void *opaque)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ return (*cc->write_elf64_qemunote)(f, cpu, opaque);
+}
+
+static int cpu_common_write_elf64_qemunote(WriteCoreDumpFunction f,
+ CPUState *cpu, void *opaque)
+{
+ return -1;
+}
+
+int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
+ int cpuid, void *opaque)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ return (*cc->write_elf64_note)(f, cpu, cpuid, opaque);
+}
+
+static int cpu_common_write_elf64_note(WriteCoreDumpFunction f,
+ CPUState *cpu, int cpuid,
+ void *opaque)
+{
+ return -1;
+}
+
void cpu_reset(CPUState *cpu)
{
@@ -32,6 +134,10 @@ void cpu_reset(CPUState *cpu)
static void cpu_common_reset(CPUState *cpu)
{
+ cpu->exit_request = 0;
+ cpu->interrupt_request = 0;
+ cpu->current_tb = NULL;
+ cpu->halted = 0;
}
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model)
@@ -46,6 +152,22 @@ static ObjectClass *cpu_common_class_by_name(const char *cpu_model)
return NULL;
}
+static void cpu_common_realizefn(DeviceState *dev, Error **errp)
+{
+ CPUState *cpu = CPU(dev);
+
+ if (dev->hotplugged) {
+ cpu_synchronize_post_init(cpu);
+ notifier_list_notify(&cpu_added_notifiers, dev);
+ cpu_resume(cpu);
+ }
+}
+
+static int64_t cpu_common_get_arch_id(CPUState *cpu)
+{
+ return cpu->cpu_index;
+}
+
static void cpu_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -53,6 +175,12 @@ static void cpu_class_init(ObjectClass *klass, void *data)
k->class_by_name = cpu_common_class_by_name;
k->reset = cpu_common_reset;
+ k->get_arch_id = cpu_common_get_arch_id;
+ k->write_elf32_qemunote = cpu_common_write_elf32_qemunote;
+ k->write_elf32_note = cpu_common_write_elf32_note;
+ k->write_elf64_qemunote = cpu_common_write_elf64_qemunote;
+ k->write_elf64_note = cpu_common_write_elf64_note;
+ dc->realize = cpu_common_realizefn;
dc->no_user = 1;
}
diff --git a/qom/object.c b/qom/object.c
index 563e45b..ec88231 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -16,6 +16,7 @@
#include "qapi/string-input-visitor.h"
#include "qapi/string-output-visitor.h"
#include "qapi/qmp/qerror.h"
+#include "trace.h"
/* TODO: replace QObject with a simpler visitor to avoid a dependency
* of the QOM core on QObject? */
@@ -245,6 +246,7 @@ static void type_initialize(TypeImpl *ti)
g_assert(parent->class_size <= ti->class_size);
memcpy(ti->class, parent->class, parent->class_size);
+ ti->class->interfaces = NULL;
for (e = parent->class->interfaces; e; e = e->next) {
ObjectClass *iface = e->data;
@@ -361,13 +363,17 @@ static void object_property_del_child(Object *obj, Object *child, Error **errp)
void object_unparent(Object *obj)
{
- object_ref(obj);
- if (obj->parent) {
- object_property_del_child(obj->parent, obj, NULL);
+ if (!obj->parent) {
+ return;
}
+
+ object_ref(obj);
if (obj->class->unparent) {
(obj->class->unparent)(obj);
}
+ if (obj->parent) {
+ object_property_del_child(obj->parent, obj, NULL);
+ }
object_unref(obj);
}
@@ -426,29 +432,69 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
return NULL;
}
-Object *object_dynamic_cast_assert(Object *obj, const char *typename)
+Object *object_dynamic_cast_assert(Object *obj, const char *typename,
+ const char *file, int line, const char *func)
{
+ trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)",
+ typename, file, line, func);
+
+#ifdef CONFIG_QOM_CAST_DEBUG
+ int i;
Object *inst;
+ for (i = 0; i < OBJECT_CLASS_CAST_CACHE; i++) {
+ if (obj->class->cast_cache[i] == typename) {
+ goto out;
+ }
+ }
+
inst = object_dynamic_cast(obj, typename);
if (!inst && obj) {
- fprintf(stderr, "Object %p is not an instance of type %s\n",
- obj, typename);
+ fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
+ file, line, func, obj, typename);
abort();
}
- return inst;
+ assert(obj == inst);
+
+ if (obj == inst) {
+ for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
+ obj->class->cast_cache[i - 1] = obj->class->cast_cache[i];
+ }
+ obj->class->cast_cache[i - 1] = typename;
+ }
+
+out:
+#endif
+ return obj;
}
ObjectClass *object_class_dynamic_cast(ObjectClass *class,
const char *typename)
{
- TypeImpl *target_type = type_get_by_name(typename);
- TypeImpl *type = class->type;
ObjectClass *ret = NULL;
+ TypeImpl *target_type;
+ TypeImpl *type;
+
+ if (!class) {
+ return NULL;
+ }
+
+ /* A simple fast path that can trigger a lot for leaf classes. */
+ type = class->type;
+ if (type->name == typename) {
+ return class;
+ }
- if (type->num_interfaces && type_is_ancestor(target_type, type_interface)) {
+ target_type = type_get_by_name(typename);
+ if (!target_type) {
+ /* target class type unknown, so fail the cast */
+ return NULL;
+ }
+
+ if (type->class->interfaces &&
+ type_is_ancestor(target_type, type_interface)) {
int found = 0;
GSList *i;
@@ -473,16 +519,46 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *class,
}
ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
- const char *typename)
+ const char *typename,
+ const char *file, int line,
+ const char *func)
{
- ObjectClass *ret = object_class_dynamic_cast(class, typename);
+ ObjectClass *ret;
- if (!ret) {
- fprintf(stderr, "Object %p is not an instance of type %s\n",
- class, typename);
+ trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)",
+ typename, file, line, func);
+
+#ifdef CONFIG_QOM_CAST_DEBUG
+ int i;
+
+ for (i = 0; i < OBJECT_CLASS_CAST_CACHE; i++) {
+ if (class->cast_cache[i] == typename) {
+ ret = class;
+ goto out;
+ }
+ }
+#else
+ if (!class->interfaces) {
+ return class;
+ }
+#endif
+
+ ret = object_class_dynamic_cast(class, typename);
+ if (!ret && class) {
+ fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
+ file, line, func, class, typename);
abort();
}
+#ifdef CONFIG_QOM_CAST_DEBUG
+ if (ret == class) {
+ for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
+ class->cast_cache[i - 1] = class->cast_cache[i];
+ }
+ class->cast_cache[i - 1] = typename;
+ }
+out:
+#endif
return ret;
}
@@ -627,7 +703,18 @@ void object_property_add(Object *obj, const char *name, const char *type,
ObjectPropertyRelease *release,
void *opaque, Error **errp)
{
- ObjectProperty *prop = g_malloc0(sizeof(*prop));
+ ObjectProperty *prop;
+
+ QTAILQ_FOREACH(prop, &obj->properties, node) {
+ if (strcmp(prop->name, name) == 0) {
+ error_setg(errp, "attempt to add duplicate property '%s'"
+ " to object (type '%s')", name,
+ object_get_typename(obj));
+ return;
+ }
+ }
+
+ prop = g_malloc0(sizeof(*prop));
prop->name = g_strdup(name);
prop->type = g_strdup(type);
@@ -1096,21 +1183,13 @@ static Object *object_resolve_partial_path(Object *parent,
Object *object_resolve_path_type(const char *path, const char *typename,
bool *ambiguous)
{
- bool partial_path = true;
Object *obj;
gchar **parts;
parts = g_strsplit(path, "/", 0);
- if (parts == NULL || parts[0] == NULL) {
- g_strfreev(parts);
- return object_get_root();
- }
-
- if (strcmp(parts[0], "") == 0) {
- partial_path = false;
- }
+ assert(parts);
- if (partial_path) {
+ if (parts[0] == NULL || strcmp(parts[0], "") != 0) {
if (ambiguous) {
*ambiguous = false;
}