qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Igor Mammedov <imammedo@redhat.com>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, pbonzini@redhat.com, rth@twiddle.net,
	ehabkost@redhat.com, blauwirbel@gmail.com,
	mark.cave-ayland@ilande.co.uk, qemu-arm@nongnu.org
Subject: [Qemu-devel] [PATCH RFC 6/8] cpu: use CPUClass->parse_features() as convertor to global properties
Date: Wed,  1 Jun 2016 18:37:28 +0200	[thread overview]
Message-ID: <1464799050-11002-7-git-send-email-imammedo@redhat.com> (raw)
In-Reply-To: <1464799050-11002-1-git-send-email-imammedo@redhat.com>

Currently CPUClass->parse_features() is used to parse
-cpu features string and set properties on created CPU
instances.

But considering that features specified -cpu apply to
every created CPU instance, it doesn't make sence 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 Device instance for a given
type. That way it's possible to convert CPU features
into a set of global properties for specified by
 -cpu cpu_model and common Device.device_post_init()
will apply them to every cpu model model automaticaaly
regardless whether it's manually created CPU or CPU
created with help of device_add.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
This patch only make CPUClass->parse_features()
a global properties convertor and follow up patches
will do cleanups that new behaviour allows.
---
 hw/arm/virt.c     |  7 ++++---
 include/qom/cpu.h |  2 +-
 qom/cpu.c         | 29 +++++++++++++++++------------
 target-i386/cpu.c | 25 +++++++++++++++++++------
 4 files changed, 41 insertions(+), 22 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index e77ed88..473e439 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1193,6 +1193,7 @@ static void machvirt_init(MachineState *machine)
 
     for (n = 0; n < smp_cpus; n++) {
         ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
+        const char *typename = object_class_get_name(oc);
         CPUClass *cc = CPU_CLASS(oc);
         Object *cpuobj;
         Error *err = NULL;
@@ -1202,10 +1203,10 @@ static void machvirt_init(MachineState *machine)
             error_report("Unable to find CPU definition");
             exit(1);
         }
-        cpuobj = object_new(object_class_get_name(oc));
+        /* convert -smp CPU options specified by the user into global props */
+        cc->parse_features(typename, cpuopts, &err);
+        cpuobj = object_new(typename);
 
-        /* Handle any CPU options specified by the user */
-        cc->parse_features(CPU(cpuobj), cpuopts, &err);
         g_free(cpuopts);
         if (err) {
             error_report_err(err);
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 32f3af3..cacb100 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -134,7 +134,7 @@ typedef struct CPUClass {
     /*< public >*/
 
     ObjectClass *(*class_by_name)(const char *cpu_model);
-    void (*parse_features)(CPUState *cpu, char *str, Error **errp);
+    void (*parse_features)(const char *typename, char *str, Error **errp);
 
     void (*reset)(CPUState *cpu);
     int reset_dump_flags;
diff --git a/qom/cpu.c b/qom/cpu.c
index 751e992..f3e3c02 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -28,6 +28,7 @@
 #include "exec/log.h"
 #include "qemu/error-report.h"
 #include "sysemu/sysemu.h"
+#include "hw/qdev-properties.h"
 
 bool cpu_exists(int64_t id)
 {
@@ -46,7 +47,7 @@ bool cpu_exists(int64_t id)
 CPUState *cpu_generic_init(const char *typename, const char *cpu_model)
 {
     char *str, *name, *featurestr;
-    CPUState *cpu;
+    CPUState *cpu = NULL;
     ObjectClass *oc;
     CPUClass *cc;
     Error *err = NULL;
@@ -60,16 +61,15 @@ CPUState *cpu_generic_init(const char *typename, const char *cpu_model)
         return NULL;
     }
 
-    cpu = CPU(object_new(object_class_get_name(oc)));
-    cc = CPU_GET_CLASS(cpu);
-
+    cc = CPU_CLASS(oc);
     featurestr = strtok(NULL, ",");
-    cc->parse_features(cpu, featurestr, &err);
+    cc->parse_features(object_class_get_name(oc), featurestr, &err);
     g_free(str);
     if (err != NULL) {
         goto out;
     }
 
+    cpu = CPU(object_new(object_class_get_name(oc)));
     object_property_set_bool(OBJECT(cpu), true, "realized", &err);
 
 out:
@@ -282,25 +282,29 @@ static ObjectClass *cpu_common_class_by_name(const char *cpu_model)
     return NULL;
 }
 
-static void cpu_common_parse_features(CPUState *cpu, char *features,
+static void cpu_common_parse_features(const char *typename, char *features,
                                       Error **errp)
 {
     char *featurestr; /* Single "key=value" string being parsed */
     char *val;
-    Error *err = NULL;
+    static bool cpu_globals_initialized;
+
+    if (cpu_globals_initialized) {
+        return;
+    }
 
     featurestr = features ? strtok(features, ",") : NULL;
 
     while (featurestr) {
         val = strchr(featurestr, '=');
         if (val) {
+            GlobalProperty *prop = g_new0(typeof(*prop), 1);
             *val = 0;
             val++;
-            object_property_parse(OBJECT(cpu), val, featurestr, &err);
-            if (err) {
-                error_propagate(errp, err);
-                return;
-            }
+            prop->driver = typename;
+            prop->property = g_strdup(featurestr);
+            prop->value = g_strdup(val);
+            qdev_prop_register_global(prop);
         } else {
             error_setg(errp, "Expected key=value format, found %s.",
                        featurestr);
@@ -308,6 +312,7 @@ static void cpu_common_parse_features(CPUState *cpu, char *features,
         }
         featurestr = strtok(NULL, ",");
     }
+    cpu_globals_initialized = true;
 }
 
 static void cpu_common_realizefn(DeviceState *dev, Error **errp)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 618aef9..871175a 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1939,16 +1939,20 @@ 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 */
     uint32_t numvalue;
     char num[32];
     const char *name;
     char *err;
     Error *local_err = NULL;
+    static bool cpu_globals_initialized;
+
+    if (cpu_globals_initialized) {
+        return;
+    }
 
     featurestr = features ? strtok(features, ",") : NULL;
 
@@ -2011,7 +2015,11 @@ static void x86_cpu_parse_featurestr(CPUState *cs, char *features,
         }
 
         if (val) {
-            object_property_parse(OBJECT(cpu), val, name, &local_err);
+            GlobalProperty *prop = g_new0(typeof(*prop), 1);
+            prop->driver = typename;
+            prop->property = g_strdup(name);
+            prop->value = g_strdup(val);
+            qdev_prop_register_global(prop);
         }
 
         if (local_err) {
@@ -2020,6 +2028,8 @@ static void x86_cpu_parse_featurestr(CPUState *cs, char *features,
         }
         featurestr = strtok(NULL, ",");
     }
+
+    cpu_globals_initialized = true;
 }
 
 /* Print all cpuid feature names in featureset
@@ -2203,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]) {
@@ -2220,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;
     }
-- 
1.8.3.1

  parent reply	other threads:[~2016-06-01 16:38 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-01 16:37 [Qemu-devel] [PATCH RFC 0/8] cpus: make "-cpu cpux, features" global properties Igor Mammedov
2016-06-01 16:37 ` [Qemu-devel] [PATCH RFC 1/8] target-i386: cpu: move features logic that requires CPUState to realize time Igor Mammedov
2016-06-01 17:43   ` Eduardo Habkost
2016-06-02  9:59     ` Igor Mammedov
2016-06-02 14:38       ` Eduardo Habkost
2016-06-02 16:56         ` Igor Mammedov
2016-06-02 17:34           ` Eduardo Habkost
2016-06-02 18:23             ` Igor Mammedov
2016-06-02 18:43               ` Eduardo Habkost
2016-06-03 10:13             ` Igor Mammedov
2016-06-03 19:26               ` Eduardo Habkost
2016-06-04 16:44                 ` Igor Mammedov
2016-06-01 16:37 ` [Qemu-devel] [PATCH RFC 2/8] target-i386: cpu: move xcc->kvm_required check to reaize time Igor Mammedov
2016-06-01 17:46   ` Eduardo Habkost
2016-06-02 10:02     ` Igor Mammedov
2016-06-01 16:37 ` [Qemu-devel] [PATCH RFC 3/8] target-i386: cpu: use cpu_generic_init() in cpu_x86_init() Igor Mammedov
2016-06-01 18:08   ` Eduardo Habkost
2016-06-01 16:37 ` [Qemu-devel] [PATCH RFC 4/8] target-i386: cpu: consolidate calls of object_property_parse() in x86_cpu_parse_featurestr Igor Mammedov
2016-06-01 18:46   ` Eduardo Habkost
2016-06-02 12:22     ` Igor Mammedov
2016-06-02 14:42       ` Eduardo Habkost
2016-06-02 14:53       ` Eduardo Habkost
2016-06-02 15:05         ` Peter Krempa
2016-06-02 16:31           ` Igor Mammedov
2016-06-03  7:30             ` Peter Krempa
2016-06-03  9:37               ` Igor Mammedov
2016-06-03 19:36                 ` Eduardo Habkost
2016-06-02 16:32         ` Igor Mammedov
2016-06-02 16:55           ` [Qemu-devel] [PATCH] target-i386: Remove xlevel & hv-spinlocks option fixups Eduardo Habkost
2016-06-02 21:07             ` [Qemu-devel] [libvirt] " Eric Blake
2016-06-01 16:37 ` [Qemu-devel] [PATCH RFC 5/8] target-sparc: cpu: use sparc_cpu_parse_features() directly Igor Mammedov
2016-06-01 16:37 ` Igor Mammedov [this message]
2016-06-01 18:54   ` [Qemu-devel] [PATCH RFC 6/8] cpu: use CPUClass->parse_features() as convertor to global properties Eduardo Habkost
2016-06-02 10:06     ` Igor Mammedov
2016-06-02 14:41       ` Eduardo Habkost
2016-06-01 16:37 ` [Qemu-devel] [PATCH RFC 7/8] arm: virt: parse cpu_model only once Igor Mammedov
2016-06-01 16:37 ` [Qemu-devel] [PATCH RFC 8/8] pc: parse cpu features " Igor Mammedov
2016-06-01 18:21 ` [Qemu-devel] [PATCH RFC 0/8] cpus: make "-cpu cpux, features" global properties Peter Maydell
2016-06-01 18:51   ` Eduardo Habkost
2016-06-02 20:44 ` David Hildenbrand
2016-06-03 12:06   ` Jiri Denemark
2016-06-03 12:14     ` David Hildenbrand
     [not found] ` <201606022044.u52KaIkv017063@mx0a-001b2d01.pphosted.com>
2016-06-03  0:02   ` Eduardo Habkost
2016-06-03  6:36     ` David Hildenbrand
     [not found]     ` <20160603083621.6547bde4@thinkpad-w530>
2016-06-03  9:20       ` Igor Mammedov
2016-06-03 10:18         ` David Hildenbrand
2016-06-03 19:54       ` Eduardo Habkost
2016-06-06  9:59         ` David Hildenbrand

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1464799050-11002-7-git-send-email-imammedo@redhat.com \
    --to=imammedo@redhat.com \
    --cc=blauwirbel@gmail.com \
    --cc=ehabkost@redhat.com \
    --cc=mark.cave-ayland@ilande.co.uk \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).