summaryrefslogtreecommitdiff
path: root/target-i386/cpu.c
diff options
context:
space:
mode:
authorIgor Mammedov <imammedo@redhat.com>2016-06-09 19:11:01 +0200
committerEduardo Habkost <ehabkost@redhat.com>2016-07-07 15:25:01 -0300
commit62a48a2a5798425997152dea3fc48708f9116c04 (patch)
treed07e143d87334112feb80a2422ccb5e7afdb65c7 /target-i386/cpu.c
parentcf2887c9738451eb989c6c102af070dee2dc172a (diff)
downloadqemu-62a48a2a5798425997152dea3fc48708f9116c04.zip
cpu: Use CPUClass->parse_features() as convertor to global properties
Currently CPUClass->parse_features() is used to parse -cpu features string and set properties on created CPU instances. But considering that features specified by -cpu apply to every created CPU instance, it doesn't make sense to parse the same features string for every CPU created. It also makes every target that cares about parsing features string explicitly call CPUClass->parse_features() parser, which gets in a way if we consider using generic device_add for CPU hotplug as device_add has not a clue about CPU specific hooks. Turns out we can use global properties mechanism to set properties on every created CPU instance for a given type. That way it's possible to convert CPU features into a set of global properties for CPU type specified by -cpu cpu_model and common Device.device_post_init() will apply them to CPU of given type automatically regardless whether it's manually created CPU or CPU created with help of device_add. Signed-off-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Diffstat (limited to 'target-i386/cpu.c')
-rw-r--r--target-i386/cpu.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 0b286e161c..16977d5404 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1958,12 +1958,17 @@ static FeatureWordArray minus_features = { 0 };
/* Parse "+feature,-feature,feature=foo" CPU feature string
*/
-static void x86_cpu_parse_featurestr(CPUState *cs, char *features,
+static void x86_cpu_parse_featurestr(const char *typename, char *features,
Error **errp)
{
- X86CPU *cpu = X86_CPU(cs);
char *featurestr; /* Single 'key=value" string being parsed */
Error *local_err = NULL;
+ static bool cpu_globals_initialized;
+
+ if (cpu_globals_initialized) {
+ return;
+ }
+ cpu_globals_initialized = true;
if (!features) {
return;
@@ -1976,6 +1981,7 @@ static void x86_cpu_parse_featurestr(CPUState *cs, char *features,
const char *val = NULL;
char *eq = NULL;
char num[32];
+ GlobalProperty *prop;
/* Compatibility syntax: */
if (featurestr[0] == '+') {
@@ -2013,7 +2019,12 @@ static void x86_cpu_parse_featurestr(CPUState *cs, char *features,
name = "tsc-frequency";
}
- object_property_parse(OBJECT(cpu), val, name, &local_err);
+ prop = g_new0(typeof(*prop), 1);
+ prop->driver = typename;
+ prop->property = g_strdup(name);
+ prop->value = g_strdup(val);
+ prop->errp = &error_fatal;
+ qdev_prop_register_global(prop);
}
if (local_err) {
@@ -2202,9 +2213,11 @@ X86CPU *cpu_x86_create(const char *cpu_model, Error **errp)
{
X86CPU *cpu = NULL;
ObjectClass *oc;
+ CPUClass *cc;
gchar **model_pieces;
char *name, *features;
Error *error = NULL;
+ const char *typename;
model_pieces = g_strsplit(cpu_model, ",", 2);
if (!model_pieces[0]) {
@@ -2219,10 +2232,11 @@ X86CPU *cpu_x86_create(const char *cpu_model, Error **errp)
error_setg(&error, "Unable to find CPU definition: %s", name);
goto out;
}
+ cc = CPU_CLASS(oc);
+ typename = object_class_get_name(oc);
- cpu = X86_CPU(object_new(object_class_get_name(oc)));
-
- x86_cpu_parse_featurestr(CPU(cpu), features, &error);
+ cc->parse_features(typename, features, &error);
+ cpu = X86_CPU(object_new(typename));
if (error) {
goto out;
}