All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19
@ 2017-09-19 20:18 Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 01/12] vl: Clean up user-creatable objects when exiting Eduardo Habkost
                   ` (12 more replies)
  0 siblings, 13 replies; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-19 20:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel; +Cc: Marcel Apfelbaum, Igor Mammedov

The following changes since commit a9158a5cba955b79d580a252cc58ff44d154e370:

  Merge remote-tracking branch 'remotes/kraxel/tags/audio-20170918-pull-request' into staging (2017-09-18 12:40:54 +0100)

are available in the git repository at:

  git://github.com/ehabkost/qemu.git tags/machine-next-pull-request

for you to fetch changes up to e3d038b89f1bf3f09da4d59aa16b16e8305e1a05:

  MAINTAINERS: Update git URLs for my trees (2017-09-19 16:53:13 -0300)

----------------------------------------------------------------
Machine/CPU/NUMA queue, 2017-09-19

----------------------------------------------------------------

Dou Liyang (1):
  NUMA: Replace MAX_NODES with nb_numa_nodes in for loop

Eduardo Habkost (5):
  vl: Clean up user-creatable objects when exiting
  osdep: Define QEMU_MADV_REMOVE
  hostmem-file: Add "discard-data" option
  hw/acpi-build: Fix SRAT memory building in case of node 0 without RAM
  MAINTAINERS: Update git URLs for my trees

Igor Mammedov (6):
  qom: cpus: split cpu_generic_init() on feature parsing and cpu
    creation parts
  cpu: make cpu_generic_init() abort QEMU on error
  vl.c: convert cpu_model to cpu type and set of global properties
    before machine_init()
  pc: use generic cpu_model parsing
  arm: drop intermediate cpu_model -> cpu type parsing and use cpu type
    directly
  numa: cpu: calculate/set default node-ids after all -numa CLI options
    are parsed

 include/hw/arm/armv7m.h         |  4 +--
 include/hw/arm/aspeed_soc.h     |  2 +-
 include/hw/arm/stm32f205_soc.h  |  2 +-
 include/hw/boards.h             | 10 +++++++
 include/qemu/osdep.h            |  7 +++++
 include/qom/cpu.h               | 22 +++++++++++++++
 include/qom/object_interfaces.h |  8 ++++++
 target/arm/cpu.h                |  3 ++
 target/i386/cpu.h               |  9 ++++++
 backends/hostmem-file.c         | 29 ++++++++++++++++++++
 bsd-user/main.c                 |  4 ---
 hw/alpha/dp264.c                |  4 ---
 hw/arm/armv7m.c                 | 40 ++++-----------------------
 hw/arm/aspeed_soc.c             | 13 ++++-----
 hw/arm/collie.c                 | 10 ++-----
 hw/arm/exynos4210.c             |  6 +---
 hw/arm/gumstix.c                |  5 ++--
 hw/arm/highbank.c               | 10 +++----
 hw/arm/integratorcp.c           | 30 ++------------------
 hw/arm/mainstone.c              |  9 +++---
 hw/arm/mps2.c                   | 17 +++++-------
 hw/arm/musicpal.c               | 11 ++------
 hw/arm/netduino2.c              |  2 +-
 hw/arm/nseries.c                |  4 ++-
 hw/arm/omap1.c                  | 11 ++------
 hw/arm/omap2.c                  |  8 ++----
 hw/arm/omap_sx1.c               |  5 +++-
 hw/arm/palm.c                   |  5 ++--
 hw/arm/pxa2xx.c                 | 18 +++---------
 hw/arm/realview.c               | 25 ++++-------------
 hw/arm/spitz.c                  | 12 ++++----
 hw/arm/stellaris.c              | 16 +++++------
 hw/arm/stm32f205_soc.c          |  4 +--
 hw/arm/strongarm.c              | 15 ++--------
 hw/arm/tosa.c                   |  4 ---
 hw/arm/versatilepb.c            | 15 ++--------
 hw/arm/vexpress.c               | 32 +++++++--------------
 hw/arm/virt.c                   | 60 ++++++++++------------------------------
 hw/arm/xilinx_zynq.c            | 10 ++-----
 hw/arm/z2.c                     |  9 ++----
 hw/core/machine.c               |  1 +
 hw/i386/acpi-build.c            | 28 +++++++++++++++----
 hw/i386/pc.c                    | 61 +++++++++++------------------------------
 hw/i386/pc_piix.c               |  4 +--
 hw/lm32/lm32_boards.c           |  8 ------
 hw/lm32/milkymist.c             |  4 ---
 hw/m68k/an5206.c                |  4 ---
 hw/m68k/mcf5208.c               |  4 ---
 hw/mips/cps.c                   |  4 ---
 hw/mips/mips_fulong2e.c         |  4 ---
 hw/mips/mips_jazz.c             |  4 ---
 hw/mips/mips_malta.c            |  4 ---
 hw/mips/mips_mipssim.c          |  4 ---
 hw/mips/mips_r4k.c              |  4 ---
 hw/moxie/moxiesim.c             |  4 ---
 hw/openrisc/openrisc_sim.c      |  4 ---
 hw/ppc/e500.c                   |  4 ---
 hw/ppc/mac_newworld.c           |  4 ---
 hw/ppc/mac_oldworld.c           |  4 ---
 hw/ppc/ppc440_bamboo.c          |  4 ---
 hw/ppc/ppc4xx_devs.c            |  5 ----
 hw/ppc/prep.c                   |  9 ------
 hw/ppc/spapr.c                  | 15 ++++------
 hw/ppc/virtex_ml507.c           |  4 ---
 hw/sh4/r2d.c                    |  4 ---
 hw/sh4/shix.c                   |  4 ---
 hw/sparc/leon3.c                |  4 ---
 hw/sparc/sun4m.c                |  4 ---
 hw/sparc64/sparc64.c            |  4 ---
 hw/tricore/tricore_testboard.c  |  4 ---
 hw/unicore32/puv3.c             |  4 ---
 hw/xtensa/sim.c                 |  5 ----
 hw/xtensa/xtfpga.c              |  5 ----
 linux-user/main.c               |  4 ---
 numa.c                          |  2 +-
 qom/cpu.c                       | 49 ++++++++++++++++++---------------
 qom/object_interfaces.c         |  5 ++++
 target/arm/cpu.c                |  2 +-
 target/i386/cpu.c               |  3 --
 vl.c                            | 11 ++++++++
 MAINTAINERS                     |  5 +++-
 qemu-options.hx                 |  8 +++++-
 82 files changed, 307 insertions(+), 525 deletions(-)

-- 
2.13.5

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 01/12] vl: Clean up user-creatable objects when exiting
  2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
@ 2017-09-19 20:18 ` Eduardo Habkost
  2017-09-26 10:14   ` Christian Borntraeger
  2017-09-19 20:18 ` [Qemu-devel] [PULL 02/12] osdep: Define QEMU_MADV_REMOVE Eduardo Habkost
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-19 20:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel; +Cc: Marcel Apfelbaum, Igor Mammedov

Delete all user-creatable objects in /objects when exiting QEMU, so they
can perform cleanup actions.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20170824192315.5897-2-ehabkost@redhat.com>
Acked-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: Zack Cornelius <zack.cornelius@kove.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qom/object_interfaces.h | 8 ++++++++
 qom/object_interfaces.c         | 5 +++++
 vl.c                            | 1 +
 3 files changed, 14 insertions(+)

diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index d63c1c28f8..d23e11bc53 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -147,4 +147,12 @@ int user_creatable_add_opts_foreach(void *opaque,
  */
 void user_creatable_del(const char *id, Error **errp);
 
+/**
+ * user_creatable_cleanup:
+ *
+ * Delete all user-creatable objects and the user-creatable
+ * objects container.
+ */
+void user_creatable_cleanup(void);
+
 #endif
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 3bb8959f09..6824a88caa 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -193,6 +193,11 @@ void user_creatable_del(const char *id, Error **errp)
     object_unparent(obj);
 }
 
+void user_creatable_cleanup(void)
+{
+    object_unparent(object_get_objects_root());
+}
+
 static void register_types(void)
 {
     static const TypeInfo uc_interface_info = {
diff --git a/vl.c b/vl.c
index 9e62e92aea..ad49314608 100644
--- a/vl.c
+++ b/vl.c
@@ -4887,6 +4887,7 @@ int main(int argc, char **argv, char **envp)
     audio_cleanup();
     monitor_cleanup();
     qemu_chr_cleanup();
+    user_creatable_cleanup();
     /* TODO: unref root container, check all devices are ok */
 
     return 0;
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 02/12] osdep: Define QEMU_MADV_REMOVE
  2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 01/12] vl: Clean up user-creatable objects when exiting Eduardo Habkost
@ 2017-09-19 20:18 ` Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 03/12] hostmem-file: Add "discard-data" option Eduardo Habkost
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-19 20:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel; +Cc: Marcel Apfelbaum, Igor Mammedov

Define QEMU_MADV_REMOVE, so we can use it with qemu_madvise().

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20170824192315.5897-3-ehabkost@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Tested-by: Zack Cornelius <zack.cornelius@kove.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qemu/osdep.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 6855b94bbf..e9fa21788b 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -257,6 +257,11 @@ void qemu_anon_ram_free(void *ptr, size_t size);
 #else
 #define QEMU_MADV_NOHUGEPAGE QEMU_MADV_INVALID
 #endif
+#ifdef MADV_REMOVE
+#define QEMU_MADV_REMOVE MADV_REMOVE
+#else
+#define QEMU_MADV_REMOVE QEMU_MADV_INVALID
+#endif
 
 #elif defined(CONFIG_POSIX_MADVISE)
 
@@ -269,6 +274,7 @@ void qemu_anon_ram_free(void *ptr, size_t size);
 #define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
 #define QEMU_MADV_HUGEPAGE  QEMU_MADV_INVALID
 #define QEMU_MADV_NOHUGEPAGE  QEMU_MADV_INVALID
+#define QEMU_MADV_REMOVE QEMU_MADV_INVALID
 
 #else /* no-op */
 
@@ -281,6 +287,7 @@ void qemu_anon_ram_free(void *ptr, size_t size);
 #define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
 #define QEMU_MADV_HUGEPAGE  QEMU_MADV_INVALID
 #define QEMU_MADV_NOHUGEPAGE  QEMU_MADV_INVALID
+#define QEMU_MADV_REMOVE QEMU_MADV_INVALID
 
 #endif
 
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 03/12] hostmem-file: Add "discard-data" option
  2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 01/12] vl: Clean up user-creatable objects when exiting Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 02/12] osdep: Define QEMU_MADV_REMOVE Eduardo Habkost
@ 2017-09-19 20:18 ` Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 04/12] qom: cpus: split cpu_generic_init() on feature parsing and cpu creation parts Eduardo Habkost
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-19 20:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel; +Cc: Marcel Apfelbaum, Igor Mammedov

The new option can be used to indicate that the file contents can
be destroyed and don't need to be flushed to disk when QEMU exits
or when the memory backend object is removed.

Internally, it will trigger a madvise(MADV_REMOVE) call when the
memory backend is removed.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20170824192315.5897-4-ehabkost@redhat.com>
[ehabkost: fixup: improved documentation]
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Tested-by: Zack Cornelius <zack.cornelius@kove.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 backends/hostmem-file.c | 29 +++++++++++++++++++++++++++++
 qemu-options.hx         |  8 +++++++-
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index fc4ef46d11..e44c319915 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -32,6 +32,7 @@ struct HostMemoryBackendFile {
     HostMemoryBackend parent_obj;
 
     bool share;
+    bool discard_data;
     char *mem_path;
 };
 
@@ -103,16 +104,44 @@ static void file_memory_backend_set_share(Object *o, bool value, Error **errp)
     fb->share = value;
 }
 
+static bool file_memory_backend_get_discard_data(Object *o, Error **errp)
+{
+    return MEMORY_BACKEND_FILE(o)->discard_data;
+}
+
+static void file_memory_backend_set_discard_data(Object *o, bool value,
+                                               Error **errp)
+{
+    MEMORY_BACKEND_FILE(o)->discard_data = value;
+}
+
+static void file_backend_unparent(Object *obj)
+{
+    HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+    HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
+
+    if (host_memory_backend_mr_inited(backend) && fb->discard_data) {
+        void *ptr = memory_region_get_ram_ptr(&backend->mr);
+        uint64_t sz = memory_region_size(&backend->mr);
+
+        qemu_madvise(ptr, sz, QEMU_MADV_REMOVE);
+    }
+}
+
 static void
 file_backend_class_init(ObjectClass *oc, void *data)
 {
     HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
 
     bc->alloc = file_backend_memory_alloc;
+    oc->unparent = file_backend_unparent;
 
     object_class_property_add_bool(oc, "share",
         file_memory_backend_get_share, file_memory_backend_set_share,
         &error_abort);
+    object_class_property_add_bool(oc, "discard-data",
+        file_memory_backend_get_discard_data, file_memory_backend_set_discard_data,
+        &error_abort);
     object_class_property_add_str(oc, "mem-path",
         get_mem_path, set_mem_path,
         &error_abort);
diff --git a/qemu-options.hx b/qemu-options.hx
index 600614f6e5..77859a248c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4182,7 +4182,7 @@ property must be set.  These objects are placed in the
 
 @table @option
 
-@item -object memory-backend-file,id=@var{id},size=@var{size},mem-path=@var{dir},share=@var{on|off}
+@item -object memory-backend-file,id=@var{id},size=@var{size},mem-path=@var{dir},share=@var{on|off},discard-data=@var{on|off}
 
 Creates a memory file backend object, which can be used to back
 the guest RAM with huge pages. The @option{id} parameter is a
@@ -4194,6 +4194,12 @@ the path to either a shared memory or huge page filesystem mount.
 The @option{share} boolean option determines whether the memory
 region is marked as private to QEMU, or shared. The latter allows
 a co-operating external process to access the QEMU memory region.
+Setting the @option{discard-data} boolean option to @var{on}
+indicates that file contents can be destroyed when QEMU exits,
+to avoid unnecessarily flushing data to the backing file.  Note
+that @option{discard-data} is only an optimization, and QEMU
+might not discard file contents if it aborts unexpectedly or is
+terminated using SIGKILL.
 
 @item -object rng-random,id=@var{id},filename=@var{/dev/random}
 
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 04/12] qom: cpus: split cpu_generic_init() on feature parsing and cpu creation parts
  2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
                   ` (2 preceding siblings ...)
  2017-09-19 20:18 ` [Qemu-devel] [PULL 03/12] hostmem-file: Add "discard-data" option Eduardo Habkost
@ 2017-09-19 20:18 ` Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 05/12] cpu: make cpu_generic_init() abort QEMU on error Eduardo Habkost
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-19 20:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel; +Cc: Marcel Apfelbaum, Igor Mammedov

From: Igor Mammedov <imammedo@redhat.com>

it would allow to reuse feature parsing part in various machines
that have CPU features instead of re-implementing the same feature
parsing each time.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <1505318697-77161-2-git-send-email-imammedo@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qom/cpu.h | 21 +++++++++++++++++++++
 qom/cpu.c         | 46 ++++++++++++++++++++++++++++++----------------
 2 files changed, 51 insertions(+), 16 deletions(-)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 995a7beeb5..885276c0cf 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -645,6 +645,27 @@ void cpu_reset(CPUState *cpu);
 ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model);
 
 /**
+ * cpu_create:
+ * @typename: The CPU type.
+ *
+ * Instantiates a CPU and realizes the CPU.
+ *
+ * Returns: A #CPUState or %NULL if an error occurred.
+ */
+CPUState *cpu_create(const char *typename);
+
+/**
+ * cpu_parse_cpu_model:
+ * @typename: The CPU base type or CPU type.
+ * @cpu_model: The model string including optional parameters.
+ *
+ * processes optional parameters and registers them as global properties
+ *
+ * Returns: type of CPU to create or %NULL if an error occurred.
+ */
+const char *cpu_parse_cpu_model(const char *typename, const char *cpu_model);
+
+/**
  * cpu_generic_init:
  * @typename: The CPU base type.
  * @cpu_model: The model string including optional parameters.
diff --git a/qom/cpu.c b/qom/cpu.c
index dc5392dbeb..483f26a5fb 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -54,13 +54,26 @@ bool cpu_exists(int64_t id)
     return !!cpu_by_arch_id(id);
 }
 
-CPUState *cpu_generic_init(const char *typename, const char *cpu_model)
+CPUState *cpu_create(const char *typename)
+{
+    Error *err = NULL;
+    CPUState *cpu = CPU(object_new(typename));
+    object_property_set_bool(OBJECT(cpu), true, "realized", &err);
+    if (err != NULL) {
+        error_report_err(err);
+        object_unref(OBJECT(cpu));
+        return NULL;
+    }
+    return cpu;
+}
+
+const char *cpu_parse_cpu_model(const char *typename, const char *cpu_model)
 {
-    CPUState *cpu = NULL;
     ObjectClass *oc;
     CPUClass *cc;
     Error *err = NULL;
     gchar **model_pieces;
+    const char *cpu_type;
 
     model_pieces = g_strsplit(cpu_model, ",", 2);
 
@@ -70,27 +83,28 @@ CPUState *cpu_generic_init(const char *typename, const char *cpu_model)
         return NULL;
     }
 
+    cpu_type = object_class_get_name(oc);
     cc = CPU_CLASS(oc);
-    /* TODO: all callers of cpu_generic_init() need to be converted to
-     * call parse_features() only once, before calling cpu_generic_init().
-     */
-    cc->parse_features(object_class_get_name(oc), model_pieces[1], &err);
+    cc->parse_features(cpu_type, model_pieces[1], &err);
     g_strfreev(model_pieces);
     if (err != NULL) {
-        goto out;
-    }
-
-    cpu = CPU(object_new(object_class_get_name(oc)));
-    object_property_set_bool(OBJECT(cpu), true, "realized", &err);
-
-out:
-    if (err != NULL) {
         error_report_err(err);
-        object_unref(OBJECT(cpu));
         return NULL;
     }
+    return cpu_type;
+}
 
-    return cpu;
+CPUState *cpu_generic_init(const char *typename, const char *cpu_model)
+{
+    /* TODO: all callers of cpu_generic_init() need to be converted to
+     * call cpu_parse_features() only once, before calling cpu_generic_init().
+     */
+    const char *cpu_type = cpu_parse_cpu_model(typename, cpu_model);
+
+    if (cpu_type) {
+        return cpu_create(cpu_type);
+    }
+    return NULL;
 }
 
 bool cpu_paging_enabled(const CPUState *cpu)
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 05/12] cpu: make cpu_generic_init() abort QEMU on error
  2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
                   ` (3 preceding siblings ...)
  2017-09-19 20:18 ` [Qemu-devel] [PULL 04/12] qom: cpus: split cpu_generic_init() on feature parsing and cpu creation parts Eduardo Habkost
@ 2017-09-19 20:18 ` Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 06/12] vl.c: convert cpu_model to cpu type and set of global properties before machine_init() Eduardo Habkost
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-19 20:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel; +Cc: Marcel Apfelbaum, Igor Mammedov

From: Igor Mammedov <imammedo@redhat.com>

Almost every user of cpu_generic_init() checks for
returned NULL and then reports failure in a custom way
and aborts process.
Some users assume that call can't fail and don't check
for failure, though they should have checked for it.

In either cases cpu_generic_init() failure is fatal,
so instead of checking for failure and reporting
it various ways, make cpu_generic_init() report
errors in consistent way and terminate QEMU on failure.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <1505318697-77161-3-git-send-email-imammedo@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qom/cpu.h              |  3 ++-
 bsd-user/main.c                |  4 ----
 hw/alpha/dp264.c               |  4 ----
 hw/arm/musicpal.c              |  4 ----
 hw/arm/omap1.c                 |  4 ----
 hw/arm/omap2.c                 |  4 ----
 hw/arm/pxa2xx.c                |  8 --------
 hw/arm/strongarm.c             |  5 -----
 hw/lm32/lm32_boards.c          |  8 --------
 hw/lm32/milkymist.c            |  4 ----
 hw/m68k/an5206.c               |  4 ----
 hw/m68k/mcf5208.c              |  4 ----
 hw/mips/cps.c                  |  4 ----
 hw/mips/mips_fulong2e.c        |  4 ----
 hw/mips/mips_jazz.c            |  4 ----
 hw/mips/mips_malta.c           |  4 ----
 hw/mips/mips_mipssim.c         |  4 ----
 hw/mips/mips_r4k.c             |  4 ----
 hw/moxie/moxiesim.c            |  4 ----
 hw/openrisc/openrisc_sim.c     |  4 ----
 hw/ppc/e500.c                  |  4 ----
 hw/ppc/mac_newworld.c          |  4 ----
 hw/ppc/mac_oldworld.c          |  4 ----
 hw/ppc/ppc440_bamboo.c         |  4 ----
 hw/ppc/ppc4xx_devs.c           |  5 -----
 hw/ppc/prep.c                  |  9 ---------
 hw/ppc/virtex_ml507.c          |  4 ----
 hw/sh4/r2d.c                   |  4 ----
 hw/sh4/shix.c                  |  4 ----
 hw/sparc/leon3.c               |  4 ----
 hw/sparc/sun4m.c               |  4 ----
 hw/sparc64/sparc64.c           |  4 ----
 hw/tricore/tricore_testboard.c |  4 ----
 hw/unicore32/puv3.c            |  4 ----
 hw/xtensa/sim.c                |  5 -----
 hw/xtensa/xtfpga.c             |  5 -----
 linux-user/main.c              |  4 ----
 qom/cpu.c                      | 19 +++++--------------
 38 files changed, 7 insertions(+), 176 deletions(-)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 885276c0cf..6d33cf1878 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -661,7 +661,8 @@ CPUState *cpu_create(const char *typename);
  *
  * processes optional parameters and registers them as global properties
  *
- * Returns: type of CPU to create or %NULL if an error occurred.
+ * Returns: type of CPU to create or prints error and terminates process
+ *          if an error occurred.
  */
 const char *cpu_parse_cpu_model(const char *typename, const char *cpu_model);
 
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 8a6706a1c8..836daac15c 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -902,10 +902,6 @@ int main(int argc, char **argv)
     /* NOTE: we need to init the CPU at this stage to get
        qemu_host_page_size */
     cpu = cpu_init(cpu_model);
-    if (!cpu) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
     env = cpu->env_ptr;
 #if defined(TARGET_SPARC) || defined(TARGET_PPC)
     cpu_reset(cpu);
diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index 1c5a177102..1b121306c2 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -68,10 +68,6 @@ static void clipper_init(MachineState *machine)
     memset(cpus, 0, sizeof(cpus));
     for (i = 0; i < smp_cpus; ++i) {
         cpus[i] = ALPHA_CPU(cpu_generic_init(TYPE_ALPHA_CPU, cpu_model));
-        if (!cpus[i]) {
-            error_report("Unable to find CPU definition");
-            exit(1);
-        }
     }
 
     cpus[0]->env.trap_arg0 = ram_size;
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index ab4ba31a24..7a6c0a6deb 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1594,10 +1594,6 @@ static void musicpal_init(MachineState *machine)
         cpu_model = "arm926";
     }
     cpu = ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, cpu_model));
-    if (!cpu) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
 
     /* For now we use a fixed - the original - RAM size */
     memory_region_allocate_system_memory(ram, NULL, "musicpal.ram",
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index 400ba30c94..04e65ce168 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -3864,10 +3864,6 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
     /* Core */
     s->mpu_model = omap310;
     s->cpu = ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, core));
-    if (s->cpu == NULL) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
     s->sdram_size = sdram_size;
     s->sram_size = OMAP15XX_SRAM_SIZE;
 
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index ece25ae744..5821477950 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -2262,10 +2262,6 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
     /* Core */
     s->mpu_model = omap2420;
     s->cpu = ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, core ?: "arm1136-r2"));
-    if (s->cpu == NULL) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
     s->sdram_size = sdram_size;
     s->sram_size = OMAP242X_SRAM_SIZE;
 
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index b0ac3cfd64..c16657da86 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -2067,10 +2067,6 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
         revision = "pxa270";
 
     s->cpu = ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, revision));
-    if (s->cpu == NULL) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
     s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0);
 
     /* SDRAM & Internal Memory Storage */
@@ -2197,10 +2193,6 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
     s = g_new0(PXA2xxState, 1);
 
     s->cpu = ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, "pxa255"));
-    if (s->cpu == NULL) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
     s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0);
 
     /* SDRAM & Internal Memory Storage */
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index 884242b2dc..c1145dd723 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -1599,11 +1599,6 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
 
     s->cpu = ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, rev));
 
-    if (!s->cpu) {
-        error_report("Unable to find CPU definition");
-        exit(1);
-    }
-
     memory_region_allocate_system_memory(&s->sdram, NULL, "strongarm.sdram",
                                          sdram_size);
     memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram);
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index eccf0ac5a1..b0bb3ef58a 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -105,10 +105,6 @@ static void lm32_evr_init(MachineState *machine)
         cpu_model = "lm32-full";
     }
     cpu = LM32_CPU(cpu_generic_init(TYPE_LM32_CPU, cpu_model));
-    if (cpu == NULL) {
-        fprintf(stderr, "qemu: unable to find CPU '%s'\n", cpu_model);
-        exit(1);
-    }
 
     env = &cpu->env;
     reset_info->cpu = cpu;
@@ -206,10 +202,6 @@ static void lm32_uclinux_init(MachineState *machine)
         cpu_model = "lm32-full";
     }
     cpu = LM32_CPU(cpu_generic_init(TYPE_LM32_CPU, cpu_model));
-    if (cpu == NULL) {
-        fprintf(stderr, "qemu: unable to find CPU '%s'\n", cpu_model);
-        exit(1);
-    }
 
     env = &cpu->env;
     reset_info->cpu = cpu;
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index dffd8797bb..4db4d2d533 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -112,10 +112,6 @@ milkymist_init(MachineState *machine)
         cpu_model = "lm32-full";
     }
     cpu = LM32_CPU(cpu_generic_init(TYPE_LM32_CPU, cpu_model));
-    if (cpu == NULL) {
-        fprintf(stderr, "qemu: unable to find CPU '%s'\n", cpu_model);
-        exit(1);
-    }
 
     env = &cpu->env;
     reset_info->cpu = cpu;
diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index 7b9b15d6c4..9002c460e5 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -43,10 +43,6 @@ static void an5206_init(MachineState *machine)
         cpu_model = "m5206";
     }
     cpu = M68K_CPU(cpu_generic_init(TYPE_M68K_CPU, cpu_model));
-    if (!cpu) {
-        error_report("Unable to find m68k CPU definition");
-        exit(1);
-    }
     env = &cpu->env;
 
     /* Initialize CPU registers.  */
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index 1a0f18073a..b9dde75106 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -233,10 +233,6 @@ static void mcf5208evb_init(MachineState *machine)
         cpu_model = "m5208";
     }
     cpu = M68K_CPU(cpu_generic_init(TYPE_M68K_CPU, cpu_model));
-    if (!cpu) {
-        fprintf(stderr, "Unable to find m68k CPU definition\n");
-        exit(1);
-    }
     env = &cpu->env;
 
     /* Initialize CPU registers.  */
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 4ef337d5c4..79d4c5e30a 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -72,10 +72,6 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 
     for (i = 0; i < s->num_vp; i++) {
         cpu = cpu_mips_init(s->cpu_model);
-        if (cpu == NULL) {
-            error_setg(errp, "%s: CPU initialization failed",  __func__);
-            return;
-        }
 
         /* Init internal devices */
         cpu_mips_irq_init_cpu(cpu);
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index 3532399a13..439a3d7a66 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -281,10 +281,6 @@ static void mips_fulong2e_init(MachineState *machine)
         cpu_model = "Loongson-2E";
     }
     cpu = cpu_mips_init(cpu_model);
-    if (cpu == NULL) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
     env = &cpu->env;
 
     qemu_register_reset(main_cpu_reset, cpu);
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index df2262a2a8..ae10670efd 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -152,10 +152,6 @@ static void mips_jazz_init(MachineState *machine,
         cpu_model = "R4000";
     }
     cpu = cpu_mips_init(cpu_model);
-    if (cpu == NULL) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
     env = &cpu->env;
     qemu_register_reset(main_cpu_reset, cpu);
 
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index af678f5784..c82e0af340 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -932,10 +932,6 @@ static void create_cpu_without_cps(const char *cpu_model,
 
     for (i = 0; i < smp_cpus; i++) {
         cpu = cpu_mips_init(cpu_model);
-        if (cpu == NULL) {
-            fprintf(stderr, "Unable to find CPU definition\n");
-            exit(1);
-        }
 
         /* Init internal devices */
         cpu_mips_irq_init_cpu(cpu);
diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index 07fc4c2300..49cd38d680 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -164,10 +164,6 @@ mips_mipssim_init(MachineState *machine)
 #endif
     }
     cpu = cpu_mips_init(cpu_model);
-    if (cpu == NULL) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
     env = &cpu->env;
 
     reset_info = g_malloc0(sizeof(ResetData));
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index 2f5ced7409..60da6070bc 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -194,10 +194,6 @@ void mips_r4k_init(MachineState *machine)
 #endif
     }
     cpu = cpu_mips_init(cpu_model);
-    if (cpu == NULL) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
     env = &cpu->env;
 
     reset_info = g_malloc0(sizeof(ResetData));
diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c
index 4c27b45c46..5ea8dd3a93 100644
--- a/hw/moxie/moxiesim.c
+++ b/hw/moxie/moxiesim.c
@@ -119,10 +119,6 @@ static void moxiesim_init(MachineState *machine)
         cpu_model = "MoxieLite-moxie-cpu";
     }
     cpu = MOXIE_CPU(cpu_generic_init(TYPE_MOXIE_CPU, cpu_model));
-    if (!cpu) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
     env = &cpu->env;
 
     qemu_register_reset(main_cpu_reset, cpu);
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 243d8020db..86bf2849c4 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -110,10 +110,6 @@ static void openrisc_sim_init(MachineState *machine)
 
     for (n = 0; n < smp_cpus; n++) {
         cpu = OPENRISC_CPU(cpu_generic_init(TYPE_OPENRISC_CPU, cpu_model));
-        if (cpu == NULL) {
-            fprintf(stderr, "Unable to find CPU definition!\n");
-            exit(1);
-        }
         qemu_register_reset(main_cpu_reset, cpu);
         main_cpu_reset(cpu);
     }
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 55cad780f4..db0e49ab8f 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -817,10 +817,6 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
 
         cpu = POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU,
                                            machine->cpu_model));
-        if (cpu == NULL) {
-            fprintf(stderr, "Unable to initialize CPU!\n");
-            exit(1);
-        }
         env = &cpu->env;
         cs = CPU(cpu);
 
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index d466634997..33b46cb50b 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -189,10 +189,6 @@ static void ppc_core99_init(MachineState *machine)
     for (i = 0; i < smp_cpus; i++) {
         cpu = POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU,
                                            machine->cpu_model));
-        if (cpu == NULL) {
-            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
-            exit(1);
-        }
         env = &cpu->env;
 
         /* Set time-base frequency to 100 Mhz */
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index fcac399562..193b9047d9 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -118,10 +118,6 @@ static void ppc_heathrow_init(MachineState *machine)
     for (i = 0; i < smp_cpus; i++) {
         cpu = POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU,
                                            machine->cpu_model));
-        if (cpu == NULL) {
-            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
-            exit(1);
-        }
         env = &cpu->env;
 
         /* Set time-base frequency to 16.6 Mhz */
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index ca26398036..f92d47f28d 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -187,10 +187,6 @@ static void bamboo_init(MachineState *machine)
         machine->cpu_model = "440EP";
     }
     cpu = POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, machine->cpu_model));
-    if (cpu == NULL) {
-        fprintf(stderr, "Unable to initialize CPU!\n");
-        exit(1);
-    }
     env = &cpu->env;
 
     if (env->mmu_model != POWERPC_MMU_BOOKE) {
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index ec90f13295..6d7f7857fe 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -57,11 +57,6 @@ PowerPCCPU *ppc4xx_init(const char *cpu_model,
 
     /* init CPUs */
     cpu = POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, cpu_model));
-    if (cpu == NULL) {
-        fprintf(stderr, "Unable to find PowerPC %s CPU definition\n",
-                cpu_model);
-        exit(1);
-    }
     env = &cpu->env;
 
     cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 00f3321a60..94138a4e8c 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -522,10 +522,6 @@ static void ppc_prep_init(MachineState *machine)
     for (i = 0; i < smp_cpus; i++) {
         cpu = POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU,
                                            machine->cpu_model));
-        if (cpu == NULL) {
-            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
-            exit(1);
-        }
         env = &cpu->env;
 
         if (env->flags & POWERPC_FLAG_RTC_CLK) {
@@ -726,11 +722,6 @@ static void ibm_40p_init(MachineState *machine)
         machine->cpu_model = "604";
     }
     cpu = POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, machine->cpu_model));
-    if (!cpu) {
-        error_report("could not initialize CPU '%s'",
-                     machine->cpu_model);
-        exit(1);
-    }
     env = &cpu->env;
     if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
         error_report("only 6xx bus is supported on this machine");
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index d5fdc16b59..ed9b406fd3 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -97,10 +97,6 @@ static PowerPCCPU *ppc440_init_xilinx(ram_addr_t *ram_size,
     qemu_irq *irqs;
 
     cpu = POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, cpu_model));
-    if (cpu == NULL) {
-        fprintf(stderr, "Unable to initialize CPU!\n");
-        exit(1);
-    }
     env = &cpu->env;
 
     ppc_booke_timers_init(cpu, sysclk, 0/* no flags */);
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index 22bc534e5f..16b9ed2db2 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -247,10 +247,6 @@ static void r2d_init(MachineState *machine)
     }
 
     cpu = SUPERH_CPU(cpu_generic_init(TYPE_SUPERH_CPU, cpu_model));
-    if (cpu == NULL) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
     env = &cpu->env;
 
     reset_info = g_malloc0(sizeof(ResetData));
diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
index 7f8a4b6484..50ee36a5c5 100644
--- a/hw/sh4/shix.c
+++ b/hw/sh4/shix.c
@@ -57,10 +57,6 @@ static void shix_init(MachineState *machine)
         cpu_model = "any";
 
     cpu = SUPERH_CPU(cpu_generic_init(TYPE_SUPERH_CPU, cpu_model));
-    if (cpu == NULL) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
 
     /* Allocate memory space */
     memory_region_init_ram(rom, NULL, "shix.rom", 0x4000, &error_fatal);
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index 56512ecd00..ec2816bf94 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -127,10 +127,6 @@ static void leon3_generic_hw_init(MachineState *machine)
     }
 
     cpu = SPARC_CPU(cpu_generic_init(TYPE_SPARC_CPU, cpu_model));
-    if (cpu == NULL) {
-        fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
-        exit(1);
-    }
     env = &cpu->env;
 
     cpu_sparc_set_id(env, 0);
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index cf47dca83a..e1bdd4828d 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -798,10 +798,6 @@ static void cpu_devinit(const char *cpu_model, unsigned int id,
     CPUSPARCState *env;
 
     cpu = SPARC_CPU(cpu_generic_init(TYPE_SPARC_CPU, cpu_model));
-    if (cpu == NULL) {
-        fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
-        exit(1);
-    }
     env = &cpu->env;
 
     cpu_sparc_set_id(env, id);
diff --git a/hw/sparc64/sparc64.c b/hw/sparc64/sparc64.c
index ecf38a45da..097d529ff1 100644
--- a/hw/sparc64/sparc64.c
+++ b/hw/sparc64/sparc64.c
@@ -354,10 +354,6 @@ SPARCCPU *sparc64_cpu_devinit(const char *cpu_model,
         cpu_model = default_cpu_model;
     }
     cpu = SPARC_CPU(cpu_generic_init(TYPE_SPARC_CPU, cpu_model));
-    if (cpu == NULL) {
-        fprintf(stderr, "Unable to find Sparc CPU definition\n");
-        exit(1);
-    }
     env = &cpu->env;
 
     env->tick = cpu_timer_create("tick", cpu, tick_irq,
diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c
index 3fcd8bb70e..0486f8a1d9 100644
--- a/hw/tricore/tricore_testboard.c
+++ b/hw/tricore/tricore_testboard.c
@@ -75,10 +75,6 @@ static void tricore_testboard_init(MachineState *machine, int board_id)
         machine->cpu_model = "tc1796";
     }
     cpu = TRICORE_CPU(cpu_generic_init(TYPE_TRICORE_CPU, machine->cpu_model));
-    if (!cpu) {
-        error_report("Unable to find CPU definition");
-        exit(1);
-    }
     env = &cpu->env;
     memory_region_init_ram(ext_cram, NULL, "powerlink_ext_c.ram",
                            2 * 1024 * 1024, &error_fatal);
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index eb9862fa2f..504ea46211 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -128,10 +128,6 @@ static void puv3_init(MachineState *machine)
     }
 
     cpu = UNICORE32_CPU(cpu_generic_init(TYPE_UNICORE32_CPU, cpu_model));
-    if (!cpu) {
-        error_report("Unable to find CPU definition");
-        exit(1);
-    }
     env = &cpu->env;
 
     puv3_soc_init(env);
diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c
index 1b4767f58b..b3580b11fa 100644
--- a/hw/xtensa/sim.c
+++ b/hw/xtensa/sim.c
@@ -85,11 +85,6 @@ static void xtensa_sim_init(MachineState *machine)
 
     for (n = 0; n < smp_cpus; n++) {
         cpu = XTENSA_CPU(cpu_generic_init(TYPE_XTENSA_CPU, cpu_model));
-        if (cpu == NULL) {
-            error_report("unable to find CPU definition '%s'",
-                         cpu_model);
-            exit(EXIT_FAILURE);
-        }
         env = &cpu->env;
 
         env->sregs[PRID] = n;
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index 182ec1e31c..a19ccebdba 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -233,11 +233,6 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
 
     for (n = 0; n < smp_cpus; n++) {
         cpu = XTENSA_CPU(cpu_generic_init(TYPE_XTENSA_CPU, cpu_model));
-        if (cpu == NULL) {
-            error_report("unable to find CPU definition '%s'",
-                         cpu_model);
-            exit(EXIT_FAILURE);
-        }
         env = &cpu->env;
 
         env->sregs[PRID] = n;
diff --git a/linux-user/main.c b/linux-user/main.c
index 03666ef657..829f974662 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -4323,10 +4323,6 @@ int main(int argc, char **argv, char **envp)
     /* NOTE: we need to init the CPU at this stage to get
        qemu_host_page_size */
     cpu = cpu_init(cpu_model);
-    if (!cpu) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(EXIT_FAILURE);
-    }
     env = cpu->env_ptr;
     cpu_reset(cpu);
 
diff --git a/qom/cpu.c b/qom/cpu.c
index 483f26a5fb..94fa8fe005 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -62,7 +62,7 @@ CPUState *cpu_create(const char *typename)
     if (err != NULL) {
         error_report_err(err);
         object_unref(OBJECT(cpu));
-        return NULL;
+        exit(EXIT_FAILURE);
     }
     return cpu;
 }
@@ -71,7 +71,6 @@ const char *cpu_parse_cpu_model(const char *typename, const char *cpu_model)
 {
     ObjectClass *oc;
     CPUClass *cc;
-    Error *err = NULL;
     gchar **model_pieces;
     const char *cpu_type;
 
@@ -79,18 +78,15 @@ const char *cpu_parse_cpu_model(const char *typename, const char *cpu_model)
 
     oc = cpu_class_by_name(typename, model_pieces[0]);
     if (oc == NULL) {
+        error_report("unable to find CPU model '%s'", model_pieces[0]);
         g_strfreev(model_pieces);
-        return NULL;
+        exit(EXIT_FAILURE);
     }
 
     cpu_type = object_class_get_name(oc);
     cc = CPU_CLASS(oc);
-    cc->parse_features(cpu_type, model_pieces[1], &err);
+    cc->parse_features(cpu_type, model_pieces[1], &error_fatal);
     g_strfreev(model_pieces);
-    if (err != NULL) {
-        error_report_err(err);
-        return NULL;
-    }
     return cpu_type;
 }
 
@@ -99,12 +95,7 @@ CPUState *cpu_generic_init(const char *typename, const char *cpu_model)
     /* TODO: all callers of cpu_generic_init() need to be converted to
      * call cpu_parse_features() only once, before calling cpu_generic_init().
      */
-    const char *cpu_type = cpu_parse_cpu_model(typename, cpu_model);
-
-    if (cpu_type) {
-        return cpu_create(cpu_type);
-    }
-    return NULL;
+    return cpu_create(cpu_parse_cpu_model(typename, cpu_model));
 }
 
 bool cpu_paging_enabled(const CPUState *cpu)
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 06/12] vl.c: convert cpu_model to cpu type and set of global properties before machine_init()
  2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
                   ` (4 preceding siblings ...)
  2017-09-19 20:18 ` [Qemu-devel] [PULL 05/12] cpu: make cpu_generic_init() abort QEMU on error Eduardo Habkost
@ 2017-09-19 20:18 ` Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 07/12] pc: use generic cpu_model parsing Eduardo Habkost
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-19 20:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel; +Cc: Marcel Apfelbaum, Igor Mammedov

From: Igor Mammedov <imammedo@redhat.com>

All machines that support user specified cpu_model either call
cpu_generic_init() or cpu_class_by_name()/CPUClass::parse_features
to parse feature string and to get CPU type to create.

Which leads to code duplication and hard-codding default CPU model
within machine_foo_init() code. Which makes it impossible to
get CPU type before machine_init() is run.

So instead of setting default CPUs models and doing parsing in
target specific machine_foo_init() in various ways, provide
a generic data driven cpu_model parsing before machine_init()
is called.

in follow up per target patches, it will allow to:
  * define default CPU type in consistent/generic manner
    per machine type and drop custom code that fallbacks
    to default if cpu_model is NULL
  * drop custom features parsing in targets and do it
    in centralized way.
  * for cases of
      cpu_generic_init(TYPE_BASE/DEFAULT_CPU, "some_cpu")
    replace it with
      cpu_create(machine->cpu_type) || cpu_create(TYPE_FOO)
    depending if CPU type is user settable or not.
    not doing useless parsing and clearly documenting where
    CPU model is user settable or fixed one.

Patch allows machine subclasses to define default CPU type
per machine class at class_init() time and if that is set
generic code will parse cpu_model into a MachineState::cpu_type
which will be used to create CPUs for that machine instance
and allows gradual per board conversion.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <1505318697-77161-4-git-send-email-imammedo@redhat.com>
Acked-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/hw/boards.h |  6 ++++++
 vl.c                | 10 ++++++++++
 2 files changed, 16 insertions(+)

diff --git a/include/hw/boards.h b/include/hw/boards.h
index 7f044d101d..6b67adaef6 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -125,6 +125,10 @@ typedef struct {
  *    Caller is responsible for freeing returned list.
  * @has_hotpluggable_cpus:
  *    If true, board supports CPUs creation with -device/device_add.
+ * @default_cpu_type:
+ *    specifies default CPU_TYPE, which will be used for parsing target
+ *    specific features and for creating CPUs if CPU name wasn't provided
+ *    explicitly at CLI
  * @minimum_page_bits:
  *    If non-zero, the board promises never to create a CPU with a page size
  *    smaller than this, so QEMU can use a more efficient larger page
@@ -177,6 +181,7 @@ struct MachineClass {
     GArray *compat_props;
     const char *hw_version;
     ram_addr_t default_ram_size;
+    const char *default_cpu_type;
     bool option_rom_has_mr;
     bool rom_file_has_mr;
     int minimum_page_bits;
@@ -231,6 +236,7 @@ struct MachineState {
     char *kernel_cmdline;
     char *initrd_filename;
     const char *cpu_model;
+    const char *cpu_type;
     AccelState *accelerator;
     CPUArchIdList *possible_cpus;
 };
diff --git a/vl.c b/vl.c
index ad49314608..9bb5058c3a 100644
--- a/vl.c
+++ b/vl.c
@@ -4716,6 +4716,16 @@ int main(int argc, char **argv, char **envp)
     current_machine->boot_order = boot_order;
     current_machine->cpu_model = cpu_model;
 
+
+    /* parse features once if machine provides default cpu_type */
+    if (machine_class->default_cpu_type) {
+        current_machine->cpu_type = machine_class->default_cpu_type;
+        if (cpu_model) {
+            current_machine->cpu_type =
+                cpu_parse_cpu_model(machine_class->default_cpu_type, cpu_model);
+        }
+    }
+
     machine_run_board_init(current_machine);
 
     realtime_init();
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 07/12] pc: use generic cpu_model parsing
  2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
                   ` (5 preceding siblings ...)
  2017-09-19 20:18 ` [Qemu-devel] [PULL 06/12] vl.c: convert cpu_model to cpu type and set of global properties before machine_init() Eduardo Habkost
@ 2017-09-19 20:18 ` Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 08/12] arm: drop intermediate cpu_model -> cpu type parsing and use cpu type directly Eduardo Habkost
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-19 20:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel; +Cc: Marcel Apfelbaum, Igor Mammedov

From: Igor Mammedov <imammedo@redhat.com>

define default CPU type in generic way in pc_machine_class_init()
and let common machine code to handle cpu_model parsing

Patch also introduces TARGET_DEFAULT_CPU_TYPE define for 2 purposes:
  * make foo_machine_class_init() look uniform on every target
  * use define in [bsd|linux]-user targets to pick default
    cpu type

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <1505318697-77161-5-git-send-email-imammedo@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target/i386/cpu.h |  9 +++++++++
 hw/i386/pc.c      | 41 +++++------------------------------------
 hw/i386/pc_piix.c |  4 +---
 target/i386/cpu.c |  3 ---
 4 files changed, 15 insertions(+), 42 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 525d35d836..4035a11613 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1508,6 +1508,15 @@ uint64_t cpu_get_tsc(CPUX86State *env);
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_X86_CPU, cpu_model)
 
+#define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU
+#define X86_CPU_TYPE_NAME(name) (name X86_CPU_TYPE_SUFFIX)
+
+#ifdef TARGET_X86_64
+#define TARGET_DEFAULT_CPU_TYPE X86_CPU_TYPE_NAME("qemu64")
+#else
+#define TARGET_DEFAULT_CPU_TYPE X86_CPU_TYPE_NAME("qemu32")
+#endif
+
 #define cpu_signal_handler cpu_x86_signal_handler
 #define cpu_list x86_cpu_list
 
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 21081041d5..2247ac0a01 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1107,7 +1107,6 @@ static void pc_new_cpu(const char *typename, int64_t apic_id, Error **errp)
 
 void pc_hot_add_cpu(const int64_t id, Error **errp)
 {
-    ObjectClass *oc;
     MachineState *ms = MACHINE(qdev_get_machine());
     int64_t apic_id = x86_cpu_apic_id_from_index(id);
     Error *local_err = NULL;
@@ -1124,9 +1123,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
         return;
     }
 
-    assert(ms->possible_cpus->cpus[0].cpu); /* BSP is always present */
-    oc = OBJECT_CLASS(CPU_GET_CLASS(ms->possible_cpus->cpus[0].cpu));
-    pc_new_cpu(object_class_get_name(oc), apic_id, &local_err);
+    pc_new_cpu(ms->cpu_type, apic_id, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
@@ -1136,39 +1133,10 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
 void pc_cpus_init(PCMachineState *pcms)
 {
     int i;
-    CPUClass *cc;
-    ObjectClass *oc;
-    const char *typename;
-    gchar **model_pieces;
     const CPUArchIdList *possible_cpus;
-    MachineState *machine = MACHINE(pcms);
+    MachineState *ms = MACHINE(pcms);
     MachineClass *mc = MACHINE_GET_CLASS(pcms);
 
-    /* init CPUs */
-    if (machine->cpu_model == NULL) {
-#ifdef TARGET_X86_64
-        machine->cpu_model = "qemu64";
-#else
-        machine->cpu_model = "qemu32";
-#endif
-    }
-
-    model_pieces = g_strsplit(machine->cpu_model, ",", 2);
-    if (!model_pieces[0]) {
-        error_report("Invalid/empty CPU model name");
-        exit(1);
-    }
-
-    oc = cpu_class_by_name(TYPE_X86_CPU, model_pieces[0]);
-    if (oc == NULL) {
-        error_report("Unable to find CPU definition: %s", model_pieces[0]);
-        exit(1);
-    }
-    typename = object_class_get_name(oc);
-    cc = CPU_CLASS(oc);
-    cc->parse_features(typename, model_pieces[1], &error_fatal);
-    g_strfreev(model_pieces);
-
     /* Calculates the limit to CPU APIC ID values
      *
      * Limit for the APIC ID value, so that all
@@ -1177,9 +1145,9 @@ void pc_cpus_init(PCMachineState *pcms)
      * This is used for FW_CFG_MAX_CPUS. See comments on bochs_bios_init().
      */
     pcms->apic_id_limit = x86_cpu_apic_id_from_index(max_cpus - 1) + 1;
-    possible_cpus = mc->possible_cpu_arch_ids(machine);
+    possible_cpus = mc->possible_cpu_arch_ids(ms);
     for (i = 0; i < smp_cpus; i++) {
-        pc_new_cpu(typename, possible_cpus->cpus[i].arch_id, &error_fatal);
+        pc_new_cpu(ms->cpu_type, possible_cpus->cpus[i].arch_id, &error_fatal);
     }
 }
 
@@ -2360,6 +2328,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
     hc->unplug_request = pc_machine_device_unplug_request_cb;
     hc->unplug = pc_machine_device_unplug_cb;
     nc->nmi_monitor_handler = x86_nmi;
+    mc->default_cpu_type = TARGET_DEFAULT_CPU_TYPE;
 
     object_class_property_add(oc, PC_MACHINE_MEMHP_REGION_SIZE, "int",
         pc_machine_get_hotplug_memory_region_size, NULL,
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index b03cc047c3..9ff79b1fd9 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -378,9 +378,6 @@ static void pc_compat_0_13(MachineState *machine)
 
 static void pc_init_isa(MachineState *machine)
 {
-    if (!machine->cpu_model) {
-        machine->cpu_model = "486";
-    }
     x86_cpu_change_kvm_default("kvm-pv-eoi", NULL);
     enable_compat_apic_id_mode();
     pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, TYPE_I440FX_PCI_DEVICE);
@@ -1113,6 +1110,7 @@ static void isapc_machine_options(MachineClass *m)
     pcmc->gigabyte_align = false;
     pcmc->smbios_legacy_mode = true;
     pcmc->has_reserved_memory = false;
+    m->default_cpu_type = X86_CPU_TYPE_NAME("486");
 }
 
 DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa,
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 69676e13e1..d0000e40ae 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -705,9 +705,6 @@ void host_vendor_fms(char *vendor, int *family, int *model, int *stepping)
 
 /* CPU class name definitions: */
 
-#define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU
-#define X86_CPU_TYPE_NAME(name) (name X86_CPU_TYPE_SUFFIX)
-
 /* Return type name for a given CPU model name
  * Caller is responsible for freeing the returned string.
  */
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 08/12] arm: drop intermediate cpu_model -> cpu type parsing and use cpu type directly
  2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
                   ` (6 preceding siblings ...)
  2017-09-19 20:18 ` [Qemu-devel] [PULL 07/12] pc: use generic cpu_model parsing Eduardo Habkost
@ 2017-09-19 20:18 ` Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 09/12] numa: cpu: calculate/set default node-ids after all -numa CLI options are parsed Eduardo Habkost
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-19 20:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel; +Cc: Marcel Apfelbaum, Igor Mammedov

From: Igor Mammedov <imammedo@redhat.com>

there are 2 use cases to deal with:
  1: fixed CPU models per board/soc
  2: boards with user configurable cpu_model and fallback to
     default cpu_model if user hasn't specified one explicitly

For the 1st
  drop intermediate cpu_model parsing and use const cpu type
  directly, which replaces:
     typename = object_class_get_name(
           cpu_class_by_name(TYPE_ARM_CPU, cpu_model))
     object_new(typename)
  with
     object_new(FOO_CPU_TYPE_NAME)
  or
     cpu_generic_init(BASE_CPU_TYPE, "my cpu model")
  with
     cpu_create(FOO_CPU_TYPE_NAME)

as result 1st use case doesn't have to invoke not necessary
translation and not needed code is removed.

For the 2nd
 1: set default cpu type with MachineClass::default_cpu_type and
 2: use generic cpu_model parsing that done before machine_init()
    is run and:
    2.1: drop custom cpu_model parsing where pattern is:
       typename = object_class_get_name(
           cpu_class_by_name(TYPE_ARM_CPU, cpu_model))
       [parse_features(typename, cpu_model, &err) ]

    2.2: or replace cpu_generic_init() which does what
         2.1 does + create_cpu(typename) with just
         create_cpu(machine->cpu_type)
as result cpu_name -> cpu_type translation is done using
generic machine code one including parsing optional features
if supported/present (removes a bunch of duplicated cpu_model
parsing code) and default cpu type is defined in an uniform way
within machine_class_init callbacks instead of adhoc places
in boadr's machine_init code.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <1505318697-77161-6-git-send-email-imammedo@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/hw/arm/armv7m.h        |  4 ++--
 include/hw/arm/aspeed_soc.h    |  2 +-
 include/hw/arm/stm32f205_soc.h |  2 +-
 target/arm/cpu.h               |  3 +++
 hw/arm/armv7m.c                | 40 +++++-------------------------------
 hw/arm/aspeed_soc.c            | 13 +++++-------
 hw/arm/collie.c                | 10 +++------
 hw/arm/exynos4210.c            |  6 +-----
 hw/arm/gumstix.c               |  5 +++--
 hw/arm/highbank.c              | 10 ++++-----
 hw/arm/integratorcp.c          | 30 ++-------------------------
 hw/arm/mainstone.c             |  9 ++++-----
 hw/arm/mps2.c                  | 17 +++++++---------
 hw/arm/musicpal.c              |  7 ++-----
 hw/arm/netduino2.c             |  2 +-
 hw/arm/nseries.c               |  4 +++-
 hw/arm/omap1.c                 |  7 ++-----
 hw/arm/omap2.c                 |  4 ++--
 hw/arm/omap_sx1.c              |  5 ++++-
 hw/arm/palm.c                  |  5 +++--
 hw/arm/pxa2xx.c                | 10 ++++-----
 hw/arm/realview.c              | 25 +++++------------------
 hw/arm/spitz.c                 | 12 ++++++-----
 hw/arm/stellaris.c             | 16 +++++++--------
 hw/arm/stm32f205_soc.c         |  4 ++--
 hw/arm/strongarm.c             | 10 +++------
 hw/arm/tosa.c                  |  4 ----
 hw/arm/versatilepb.c           | 15 +++-----------
 hw/arm/vexpress.c              | 32 +++++++++--------------------
 hw/arm/virt.c                  | 46 +++++++++---------------------------------
 hw/arm/xilinx_zynq.c           | 10 ++-------
 hw/arm/z2.c                    |  9 +++------
 target/arm/cpu.c               |  2 +-
 33 files changed, 115 insertions(+), 265 deletions(-)

diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
index 10eb058027..9ad316c76e 100644
--- a/include/hw/arm/armv7m.h
+++ b/include/hw/arm/armv7m.h
@@ -35,7 +35,7 @@ typedef struct {
 /* ARMv7M container object.
  * + Unnamed GPIO input lines: external IRQ lines for the NVIC
  * + Named GPIO output SYSRESETREQ: signalled for guest AIRCR.SYSRESETREQ
- * + Property "cpu-model": CPU model to instantiate
+ * + Property "cpu-type": CPU type to instantiate
  * + Property "num-irq": number of external IRQ lines
  * + Property "memory": MemoryRegion defining the physical address space
  *   that CPU accesses see. (The NVIC, bitbanding and other CPU-internal
@@ -55,7 +55,7 @@ typedef struct ARMv7MState {
     MemoryRegion container;
 
     /* Properties */
-    char *cpu_model;
+    char *cpu_type;
     /* MemoryRegion the board provides to us (with its devices, RAM, etc) */
     MemoryRegion *board_memory;
 } ARMv7MState;
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 0b88baaad0..f26914a2b9 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -49,7 +49,7 @@ typedef struct AspeedSoCState {
 
 typedef struct AspeedSoCInfo {
     const char *name;
-    const char *cpu_model;
+    const char *cpu_type;
     uint32_t silicon_rev;
     hwaddr sdram_base;
     uint64_t sram_size;
diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h
index e2dce1122e..922a733f88 100644
--- a/include/hw/arm/stm32f205_soc.h
+++ b/include/hw/arm/stm32f205_soc.h
@@ -52,7 +52,7 @@ typedef struct STM32F205State {
     SysBusDevice parent_obj;
     /*< public >*/
 
-    char *cpu_model;
+    char *cpu_type;
 
     ARMv7MState armv7m;
 
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 5a1f957c51..6e50ae2b55 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2091,6 +2091,9 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_ARM_CPU, cpu_model)
 
+#define ARM_CPU_TYPE_SUFFIX "-" TYPE_ARM_CPU
+#define ARM_CPU_TYPE_NAME(name) (name ARM_CPU_TYPE_SUFFIX)
+
 #define cpu_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
 
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index b64a409b40..57a680687a 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -151,10 +151,6 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
     SysBusDevice *sbd;
     Error *err = NULL;
     int i;
-    char **cpustr;
-    ObjectClass *oc;
-    const char *typename;
-    CPUClass *cc;
 
     if (!s->board_memory) {
         error_setg(errp, "memory property was not set");
@@ -163,29 +159,7 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
 
     memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
 
-    cpustr = g_strsplit(s->cpu_model, ",", 2);
-
-    oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
-    if (!oc) {
-        error_setg(errp, "Unknown CPU model %s", cpustr[0]);
-        g_strfreev(cpustr);
-        return;
-    }
-
-    cc = CPU_CLASS(oc);
-    typename = object_class_get_name(oc);
-    cc->parse_features(typename, cpustr[1], &err);
-    g_strfreev(cpustr);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-
-    s->cpu = ARM_CPU(object_new(typename));
-    if (!s->cpu) {
-        error_setg(errp, "Unknown CPU model %s", s->cpu_model);
-        return;
-    }
+    s->cpu = ARM_CPU(object_new(s->cpu_type));
 
     object_property_set_link(OBJECT(s->cpu), OBJECT(&s->container), "memory",
                              &error_abort);
@@ -241,7 +215,7 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
 }
 
 static Property armv7m_properties[] = {
-    DEFINE_PROP_STRING("cpu-model", ARMv7MState, cpu_model),
+    DEFINE_PROP_STRING("cpu-type", ARMv7MState, cpu_type),
     DEFINE_PROP_LINK("memory", ARMv7MState, board_memory, TYPE_MEMORY_REGION,
                      MemoryRegion *),
     DEFINE_PROP_END_OF_LIST(),
@@ -275,20 +249,16 @@ static void armv7m_reset(void *opaque)
    Returns the ARMv7M device.  */
 
 DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
-                      const char *kernel_filename, const char *cpu_model)
+                         const char *kernel_filename, const char *cpu_type)
 {
     DeviceState *armv7m;
 
-    if (cpu_model == NULL) {
-        cpu_model = "cortex-m3";
-    }
-
     armv7m = qdev_create(NULL, TYPE_ARMV7M);
     qdev_prop_set_uint32(armv7m, "num-irq", num_irq);
-    qdev_prop_set_string(armv7m, "cpu-model", cpu_model);
+    qdev_prop_set_string(armv7m, "cpu-type", cpu_type);
     object_property_set_link(OBJECT(armv7m), OBJECT(get_system_memory()),
                                      "memory", &error_abort);
-    /* This will exit with an error if the user passed us a bad cpu_model */
+    /* This will exit with an error if the user passed us a bad cpu_type */
     qdev_init_nofail(armv7m);
 
     armv7m_load_kernel(ARM_CPU(first_cpu), kernel_filename, mem_size);
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 13c6393350..5aa3d2ddd9 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -54,7 +54,7 @@ static const char *aspeed_soc_ast2500_typenames[] = {
 static const AspeedSoCInfo aspeed_socs[] = {
     {
         .name         = "ast2400-a0",
-        .cpu_model    = "arm926",
+        .cpu_type     = ARM_CPU_TYPE_NAME("arm926"),
         .silicon_rev  = AST2400_A0_SILICON_REV,
         .sdram_base   = AST2400_SDRAM_BASE,
         .sram_size    = 0x8000,
@@ -65,7 +65,7 @@ static const AspeedSoCInfo aspeed_socs[] = {
         .wdts_num     = 2,
     }, {
         .name         = "ast2400-a1",
-        .cpu_model    = "arm926",
+        .cpu_type     = ARM_CPU_TYPE_NAME("arm926"),
         .silicon_rev  = AST2400_A1_SILICON_REV,
         .sdram_base   = AST2400_SDRAM_BASE,
         .sram_size    = 0x8000,
@@ -76,7 +76,7 @@ static const AspeedSoCInfo aspeed_socs[] = {
         .wdts_num     = 2,
     }, {
         .name         = "ast2400",
-        .cpu_model    = "arm926",
+        .cpu_type     = ARM_CPU_TYPE_NAME("arm926"),
         .silicon_rev  = AST2400_A0_SILICON_REV,
         .sdram_base   = AST2400_SDRAM_BASE,
         .sram_size    = 0x8000,
@@ -87,7 +87,7 @@ static const AspeedSoCInfo aspeed_socs[] = {
         .wdts_num     = 2,
     }, {
         .name         = "ast2500-a1",
-        .cpu_model    = "arm1176",
+        .cpu_type     = ARM_CPU_TYPE_NAME("arm1176"),
         .silicon_rev  = AST2500_A1_SILICON_REV,
         .sdram_base   = AST2500_SDRAM_BASE,
         .sram_size    = 0x9000,
@@ -128,13 +128,10 @@ static void aspeed_soc_init(Object *obj)
 {
     AspeedSoCState *s = ASPEED_SOC(obj);
     AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
-    char *cpu_typename;
     int i;
 
-    cpu_typename = g_strdup_printf("%s-" TYPE_ARM_CPU, sc->info->cpu_model);
-    object_initialize(&s->cpu, sizeof(s->cpu), cpu_typename);
+    object_initialize(&s->cpu, sizeof(s->cpu), sc->info->cpu_type);
     object_property_add_child(obj, "cpu", OBJECT(&s->cpu), NULL);
-    g_free(cpu_typename);
 
     object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
     object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
index 8830192d86..f8c566e2e5 100644
--- a/hw/arm/collie.c
+++ b/hw/arm/collie.c
@@ -18,7 +18,7 @@
 #include "hw/block/flash.h"
 #include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
-#include "qom/cpu.h"
+#include "cpu.h"
 
 static struct arm_boot_info collie_binfo = {
     .loader_start = SA_SDCS0,
@@ -27,7 +27,6 @@ static struct arm_boot_info collie_binfo = {
 
 static void collie_init(MachineState *machine)
 {
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -35,11 +34,7 @@ static void collie_init(MachineState *machine)
     DriveInfo *dinfo;
     MemoryRegion *sysmem = get_system_memory();
 
-    if (!cpu_model) {
-        cpu_model = "sa1110";
-    }
-
-    s = sa1110_init(sysmem, collie_binfo.ram_size, cpu_model);
+    s = sa1110_init(sysmem, collie_binfo.ram_size, machine->cpu_type);
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x02000000,
@@ -65,6 +60,7 @@ static void collie_machine_init(MachineClass *mc)
     mc->desc = "Sharp SL-5500 (Collie) PDA (SA-1110)";
     mc->init = collie_init;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("sa1110");
 }
 
 DEFINE_MACHINE("collie", collie_machine_init)
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index ee1438a0f4..e8e1d81e62 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -169,15 +169,11 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem)
     Exynos4210State *s = g_new(Exynos4210State, 1);
     qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
     SysBusDevice *busdev;
-    ObjectClass *cpu_oc;
     DeviceState *dev;
     int i, n;
 
-    cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, "cortex-a9");
-    assert(cpu_oc);
-
     for (n = 0; n < EXYNOS4210_NCPUS; n++) {
-        Object *cpuobj = object_new(object_class_get_name(cpu_oc));
+        Object *cpuobj = object_new(ARM_CPU_TYPE_NAME("cortex-a9"));
 
         /* By default A9 CPUs have EL3 enabled.  This board does not currently
          * support EL3 so the CPU EL3 property is disabled before realization.
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index 092ce36ae0..bba9e9f57a 100644
--- a/hw/arm/gumstix.c
+++ b/hw/arm/gumstix.c
@@ -44,6 +44,7 @@
 #include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
+#include "cpu.h"
 
 static const int sector_len = 128 * 1024;
 
@@ -86,7 +87,6 @@ static void connex_init(MachineState *machine)
 
 static void verdex_init(MachineState *machine)
 {
-    const char *cpu_model = machine->cpu_model;
     PXA2xxState *cpu;
     DriveInfo *dinfo;
     int be;
@@ -95,7 +95,7 @@ static void verdex_init(MachineState *machine)
     uint32_t verdex_rom = 0x02000000;
     uint32_t verdex_ram = 0x10000000;
 
-    cpu = pxa270_init(address_space_mem, verdex_ram, cpu_model ?: "pxa270-c0");
+    cpu = pxa270_init(address_space_mem, verdex_ram, machine->cpu_type);
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
     if (!dinfo && !qtest_enabled()) {
@@ -144,6 +144,7 @@ static void verdex_class_init(ObjectClass *oc, void *data)
     mc->desc = "Gumstix Verdex (PXA270)";
     mc->init = verdex_init;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
 }
 
 static const TypeInfo verdex_type = {
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index ba2778948a..354c6b25a8 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -222,7 +222,6 @@ enum cxmachines {
 static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -239,19 +238,20 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
 
     switch (machine_id) {
     case CALXEDA_HIGHBANK:
-        cpu_model = "cortex-a9";
+        machine->cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
         break;
     case CALXEDA_MIDWAY:
-        cpu_model = "cortex-a15";
+        machine->cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
         break;
+    default:
+        assert(0);
     }
 
     for (n = 0; n < smp_cpus; n++) {
-        ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
         Object *cpuobj;
         ARMCPU *cpu;
 
-        cpuobj = object_new(object_class_get_name(oc));
+        cpuobj = object_new(machine->cpu_type);
         cpu = ARM_CPU(cpuobj);
 
         object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_SMC,
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index d603af982a..e8303b83be 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -572,46 +572,19 @@ static struct arm_boot_info integrator_binfo = {
 static void integratorcp_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
-    char **cpustr;
-    ObjectClass *cpu_oc;
-    CPUClass *cc;
     Object *cpuobj;
     ARMCPU *cpu;
-    const char *typename;
     MemoryRegion *address_space_mem = get_system_memory();
     MemoryRegion *ram = g_new(MemoryRegion, 1);
     MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
     qemu_irq pic[32];
     DeviceState *dev, *sic, *icp;
     int i;
-    Error *err = NULL;
 
-    if (!cpu_model) {
-        cpu_model = "arm926";
-    }
-
-    cpustr = g_strsplit(cpu_model, ",", 2);
-
-    cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
-    if (!cpu_oc) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
-    typename = object_class_get_name(cpu_oc);
-
-    cc = CPU_CLASS(cpu_oc);
-    cc->parse_features(typename, cpustr[1], &err);
-    g_strfreev(cpustr);
-    if (err) {
-        error_report_err(err);
-        exit(1);
-    }
-
-    cpuobj = object_new(typename);
+    cpuobj = object_new(machine->cpu_type);
 
     /* By default ARM1176 CPUs have EL3 enabled.  This board does not
      * currently support EL3 so the CPU EL3 property is disabled before
@@ -682,6 +655,7 @@ static void integratorcp_machine_init(MachineClass *mc)
     mc->desc = "ARM Integrator/CP (ARM926EJ-S)";
     mc->init = integratorcp_init;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
 }
 
 DEFINE_MACHINE("integratorcp", integratorcp_machine_init)
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 637f52c052..d07972a966 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -24,6 +24,7 @@
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
+#include "cpu.h"
 
 /* Device addresses */
 #define MST_FPGA_PHYS	0x08000000
@@ -121,13 +122,10 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
     int i;
     int be;
     MemoryRegion *rom = g_new(MemoryRegion, 1);
-    const char *cpu_model = machine->cpu_model;
-
-    if (!cpu_model)
-        cpu_model = "pxa270-c5";
 
     /* Setup CPU & memory */
-    mpu = pxa270_init(address_space_mem, mainstone_binfo.ram_size, cpu_model);
+    mpu = pxa270_init(address_space_mem, mainstone_binfo.ram_size,
+                      machine->cpu_type);
     memory_region_init_ram(rom, NULL, "mainstone.rom", MAINSTONE_ROM,
                            &error_fatal);
     memory_region_set_readonly(rom, true);
@@ -197,6 +195,7 @@ static void mainstone2_machine_init(MachineClass *mc)
     mc->desc = "Mainstone II (PXA27x)";
     mc->init = mainstone_init;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c5");
 }
 
 DEFINE_MACHINE("mainstone", mainstone2_machine_init)
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
index 769cff872c..694fb36866 100644
--- a/hw/arm/mps2.c
+++ b/hw/arm/mps2.c
@@ -46,7 +46,6 @@ typedef enum MPS2FPGAType {
 typedef struct {
     MachineClass parent;
     MPS2FPGAType fpga_type;
-    const char *cpu_model;
     uint32_t scc_id;
 } MPS2MachineClass;
 
@@ -107,14 +106,12 @@ static void mps2_common_init(MachineState *machine)
     MPS2MachineState *mms = MPS2_MACHINE(machine);
     MPS2MachineClass *mmc = MPS2_MACHINE_GET_CLASS(machine);
     MemoryRegion *system_memory = get_system_memory();
+    MachineClass *mc = MACHINE_GET_CLASS(machine);
     DeviceState *armv7m, *sccdev;
 
-    if (!machine->cpu_model) {
-        machine->cpu_model = mmc->cpu_model;
-    }
-
-    if (strcmp(machine->cpu_model, mmc->cpu_model) != 0) {
-        error_report("This board can only be used with CPU %s", mmc->cpu_model);
+    if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
+        error_report("This board can only be used with CPU %s",
+                     mc->default_cpu_type);
         exit(1);
     }
 
@@ -188,7 +185,7 @@ static void mps2_common_init(MachineState *machine)
     default:
         g_assert_not_reached();
     }
-    qdev_prop_set_string(armv7m, "cpu-model", machine->cpu_model);
+    qdev_prop_set_string(armv7m, "cpu-type", machine->cpu_type);
     object_property_set_link(OBJECT(&mms->armv7m), OBJECT(system_memory),
                              "memory", &error_abort);
     object_property_set_bool(OBJECT(&mms->armv7m), true, "realized",
@@ -339,7 +336,7 @@ static void mps2_an385_class_init(ObjectClass *oc, void *data)
 
     mc->desc = "ARM MPS2 with AN385 FPGA image for Cortex-M3";
     mmc->fpga_type = FPGA_AN385;
-    mmc->cpu_model = "cortex-m3";
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
     mmc->scc_id = 0x41040000 | (385 << 4);
 }
 
@@ -350,7 +347,7 @@ static void mps2_an511_class_init(ObjectClass *oc, void *data)
 
     mc->desc = "ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3";
     mmc->fpga_type = FPGA_AN511;
-    mmc->cpu_model = "cortex-m3";
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
     mmc->scc_id = 0x4104000 | (511 << 4);
 }
 
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 7a6c0a6deb..b648770882 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1570,7 +1570,6 @@ static struct arm_boot_info musicpal_binfo = {
 
 static void musicpal_init(MachineState *machine)
 {
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -1590,10 +1589,7 @@ static void musicpal_init(MachineState *machine)
     MemoryRegion *ram = g_new(MemoryRegion, 1);
     MemoryRegion *sram = g_new(MemoryRegion, 1);
 
-    if (!cpu_model) {
-        cpu_model = "arm926";
-    }
-    cpu = ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, cpu_model));
+    cpu = ARM_CPU(cpu_create(machine->cpu_type));
 
     /* For now we use a fixed - the original - RAM size */
     memory_region_allocate_system_memory(ram, NULL, "musicpal.ram",
@@ -1715,6 +1711,7 @@ static void musicpal_machine_init(MachineClass *mc)
     mc->desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)";
     mc->init = musicpal_init;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
 }
 
 DEFINE_MACHINE("musicpal", musicpal_machine_init)
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
index 9d34d4c214..f936017d4a 100644
--- a/hw/arm/netduino2.c
+++ b/hw/arm/netduino2.c
@@ -34,7 +34,7 @@ static void netduino2_init(MachineState *machine)
     DeviceState *dev;
 
     dev = qdev_create(NULL, TYPE_STM32F205_SOC);
-    qdev_prop_set_string(dev, "cpu-model", "cortex-m3");
+    qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m3"));
     object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
 
     armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index a32ac82702..58005b6619 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -1310,7 +1310,7 @@ static void n8x0_init(MachineState *machine,
     struct n800_s *s = (struct n800_s *) g_malloc0(sizeof(*s));
     int sdram_size = binfo->ram_size;
 
-    s->mpu = omap2420_mpu_init(sysmem, sdram_size, machine->cpu_model);
+    s->mpu = omap2420_mpu_init(sysmem, sdram_size, machine->cpu_type);
 
     /* Setup peripherals
      *
@@ -1426,6 +1426,7 @@ static void n800_class_init(ObjectClass *oc, void *data)
     mc->init = n800_init;
     mc->default_boot_order = "";
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm1136-r2");
 }
 
 static const TypeInfo n800_type = {
@@ -1442,6 +1443,7 @@ static void n810_class_init(ObjectClass *oc, void *data)
     mc->init = n810_init;
     mc->default_boot_order = "";
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm1136-r2");
 }
 
 static const TypeInfo n810_type = {
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index 04e65ce168..b3e7625130 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -3850,7 +3850,7 @@ static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
 
 struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
                 unsigned long sdram_size,
-                const char *core)
+                const char *cpu_type)
 {
     int i;
     struct omap_mpu_state_s *s = g_new0(struct omap_mpu_state_s, 1);
@@ -3858,12 +3858,9 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
     DriveInfo *dinfo;
     SysBusDevice *busdev;
 
-    if (!core)
-        core = "ti925t";
-
     /* Core */
     s->mpu_model = omap310;
-    s->cpu = ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, core));
+    s->cpu = ARM_CPU(cpu_create(cpu_type));
     s->sdram_size = sdram_size;
     s->sram_size = OMAP15XX_SRAM_SIZE;
 
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index 5821477950..3f6076ede8 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -2250,7 +2250,7 @@ static const struct dma_irq_map omap2_dma_irq_map[] = {
 
 struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
                 unsigned long sdram_size,
-                const char *core)
+                const char *cpu_type)
 {
     struct omap_mpu_state_s *s = g_new0(struct omap_mpu_state_s, 1);
     qemu_irq dma_irqs[4];
@@ -2261,7 +2261,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
 
     /* Core */
     s->mpu_model = omap2420;
-    s->cpu = ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, core ?: "arm1136-r2"));
+    s->cpu = ARM_CPU(cpu_create(cpu_type));
     s->sdram_size = sdram_size;
     s->sram_size = OMAP242X_SRAM_SIZE;
 
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index 45356172e8..9a14270795 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -36,6 +36,7 @@
 #include "sysemu/block-backend.h"
 #include "sysemu/qtest.h"
 #include "exec/address-spaces.h"
+#include "cpu.h"
 
 /*****************************************************************************/
 /* Siemens SX1 Cellphone V1 */
@@ -120,7 +121,7 @@ static void sx1_init(MachineState *machine, const int version)
     }
 
     mpu = omap310_mpu_init(address_space, sx1_binfo.ram_size,
-                           machine->cpu_model);
+                           machine->cpu_type);
 
     /* External Flash (EMIFS) */
     memory_region_init_ram(flash, NULL, "omap_sx1.flash0-0", flash_size,
@@ -224,6 +225,7 @@ static void sx1_machine_v2_class_init(ObjectClass *oc, void *data)
     mc->desc = "Siemens SX1 (OMAP310) V2";
     mc->init = sx1_init_v2;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("ti925t");
 }
 
 static const TypeInfo sx1_machine_v2_type = {
@@ -239,6 +241,7 @@ static void sx1_machine_v1_class_init(ObjectClass *oc, void *data)
     mc->desc = "Siemens SX1 (OMAP310) V1";
     mc->init = sx1_init_v1;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("ti925t");
 }
 
 static const TypeInfo sx1_machine_v1_type = {
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
index bf070a2d9c..b8753e2b5c 100644
--- a/hw/arm/palm.c
+++ b/hw/arm/palm.c
@@ -29,6 +29,7 @@
 #include "hw/devices.h"
 #include "hw/loader.h"
 #include "exec/address-spaces.h"
+#include "cpu.h"
 
 static uint32_t static_readb(void *opaque, hwaddr offset)
 {
@@ -195,7 +196,6 @@ static struct arm_boot_info palmte_binfo = {
 
 static void palmte_init(MachineState *machine)
 {
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -211,7 +211,7 @@ static void palmte_init(MachineState *machine)
     MemoryRegion *flash = g_new(MemoryRegion, 1);
     MemoryRegion *cs = g_new(MemoryRegion, 4);
 
-    mpu = omap310_mpu_init(address_space_mem, sdram_size, cpu_model);
+    mpu = omap310_mpu_init(address_space_mem, sdram_size, machine->cpu_type);
 
     /* External Flash (EMIFS) */
     memory_region_init_ram(flash, NULL, "palmte.flash", flash_size,
@@ -275,6 +275,7 @@ static void palmte_machine_init(MachineClass *mc)
     mc->desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)";
     mc->init = palmte_init;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("ti925t");
 }
 
 DEFINE_MACHINE("cheetah", palmte_machine_init)
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index c16657da86..cf07234578 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -2052,21 +2052,19 @@ static void pxa2xx_reset(void *opaque, int line, int level)
 
 /* Initialise a PXA270 integrated chip (ARM based core).  */
 PXA2xxState *pxa270_init(MemoryRegion *address_space,
-                         unsigned int sdram_size, const char *revision)
+                         unsigned int sdram_size, const char *cpu_type)
 {
     PXA2xxState *s;
     int i;
     DriveInfo *dinfo;
     s = g_new0(PXA2xxState, 1);
 
-    if (revision && strncmp(revision, "pxa27", 5)) {
+    if (strncmp(cpu_type, "pxa27", 5)) {
         fprintf(stderr, "Machine requires a PXA27x processor.\n");
         exit(1);
     }
-    if (!revision)
-        revision = "pxa270";
 
-    s->cpu = ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, revision));
+    s->cpu = ARM_CPU(cpu_create(cpu_type));
     s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0);
 
     /* SDRAM & Internal Memory Storage */
@@ -2192,7 +2190,7 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
 
     s = g_new0(PXA2xxState, 1);
 
-    s->cpu = ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, "pxa255"));
+    s->cpu = ARM_CPU(cpu_create(ARM_CPU_TYPE_NAME("pxa255")));
     s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0);
 
     /* SDRAM & Internal Memory Storage */
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index f3a49b6420..87cd1e583c 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -57,7 +57,6 @@ static void realview_init(MachineState *machine,
 {
     ARMCPU *cpu = NULL;
     CPUARMState *env;
-    ObjectClass *cpu_oc;
     MemoryRegion *sysmem = get_system_memory();
     MemoryRegion *ram_lo;
     MemoryRegion *ram_hi = g_new(MemoryRegion, 1);
@@ -98,14 +97,8 @@ static void realview_init(MachineState *machine,
         break;
     }
 
-    cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, machine->cpu_model);
-    if (!cpu_oc) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
-
     for (n = 0; n < smp_cpus; n++) {
-        Object *cpuobj = object_new(object_class_get_name(cpu_oc));
+        Object *cpuobj = object_new(machine->cpu_type);
 
         /* By default A9,A15 and ARM1176 CPUs have EL3 enabled.  This board
          * does not currently support EL3 so the CPU EL3 property is disabled
@@ -361,33 +354,21 @@ static void realview_init(MachineState *machine,
 
 static void realview_eb_init(MachineState *machine)
 {
-    if (!machine->cpu_model) {
-        machine->cpu_model = "arm926";
-    }
     realview_init(machine, BOARD_EB);
 }
 
 static void realview_eb_mpcore_init(MachineState *machine)
 {
-    if (!machine->cpu_model) {
-        machine->cpu_model = "arm11mpcore";
-    }
     realview_init(machine, BOARD_EB_MPCORE);
 }
 
 static void realview_pb_a8_init(MachineState *machine)
 {
-    if (!machine->cpu_model) {
-        machine->cpu_model = "cortex-a8";
-    }
     realview_init(machine, BOARD_PB_A8);
 }
 
 static void realview_pbx_a9_init(MachineState *machine)
 {
-    if (!machine->cpu_model) {
-        machine->cpu_model = "cortex-a9";
-    }
     realview_init(machine, BOARD_PBX_A9);
 }
 
@@ -399,6 +380,7 @@ static void realview_eb_class_init(ObjectClass *oc, void *data)
     mc->init = realview_eb_init;
     mc->block_default_type = IF_SCSI;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
 }
 
 static const TypeInfo realview_eb_type = {
@@ -416,6 +398,7 @@ static void realview_eb_mpcore_class_init(ObjectClass *oc, void *data)
     mc->block_default_type = IF_SCSI;
     mc->max_cpus = 4;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm11mpcore");
 }
 
 static const TypeInfo realview_eb_mpcore_type = {
@@ -431,6 +414,7 @@ static void realview_pb_a8_class_init(ObjectClass *oc, void *data)
     mc->desc = "ARM RealView Platform Baseboard for Cortex-A8";
     mc->init = realview_pb_a8_init;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a8");
 }
 
 static const TypeInfo realview_pb_a8_type = {
@@ -447,6 +431,7 @@ static void realview_pbx_a9_class_init(ObjectClass *oc, void *data)
     mc->init = realview_pbx_a9_init;
     mc->max_cpus = 4;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
 }
 
 static const TypeInfo realview_pbx_a9_type = {
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 6406421d0c..feccdb00d3 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -30,6 +30,7 @@
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
 #include "sysemu/sysemu.h"
+#include "cpu.h"
 
 #undef REG_FMT
 #define REG_FMT			"0x%02lx"
@@ -909,13 +910,10 @@ static void spitz_common_init(MachineState *machine,
     DeviceState *scp0, *scp1 = NULL;
     MemoryRegion *address_space_mem = get_system_memory();
     MemoryRegion *rom = g_new(MemoryRegion, 1);
-    const char *cpu_model = machine->cpu_model;
-
-    if (!cpu_model)
-        cpu_model = (model == terrier) ? "pxa270-c5" : "pxa270-c0";
 
     /* Setup CPU & memory */
-    mpu = pxa270_init(address_space_mem, spitz_binfo.ram_size, cpu_model);
+    mpu = pxa270_init(address_space_mem, spitz_binfo.ram_size,
+                      machine->cpu_type);
 
     sl_flash_register(mpu, (model == spitz) ? FLASH_128M : FLASH_1024M);
 
@@ -984,6 +982,7 @@ static void akitapda_class_init(ObjectClass *oc, void *data)
     mc->desc = "Sharp SL-C1000 (Akita) PDA (PXA270)";
     mc->init = akita_init;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
 }
 
 static const TypeInfo akitapda_type = {
@@ -1000,6 +999,7 @@ static void spitzpda_class_init(ObjectClass *oc, void *data)
     mc->init = spitz_init;
     mc->block_default_type = IF_IDE;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
 }
 
 static const TypeInfo spitzpda_type = {
@@ -1016,6 +1016,7 @@ static void borzoipda_class_init(ObjectClass *oc, void *data)
     mc->init = borzoi_init;
     mc->block_default_type = IF_IDE;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
 }
 
 static const TypeInfo borzoipda_type = {
@@ -1032,6 +1033,7 @@ static void terrierpda_class_init(ObjectClass *oc, void *data)
     mc->init = terrier_init;
     mc->block_default_type = IF_IDE;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c5");
 }
 
 static const TypeInfo terrierpda_type = {
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index b3aad23bdf..de7c0fc4a6 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -22,6 +22,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/char/pl011.h"
 #include "hw/misc/unimp.h"
+#include "cpu.h"
 
 #define GPIO_A 0
 #define GPIO_B 1
@@ -1225,8 +1226,7 @@ static stellaris_board_info stellaris_boards[] = {
   }
 };
 
-static void stellaris_init(const char *kernel_filename, const char *cpu_model,
-                           stellaris_board_info *board)
+static void stellaris_init(MachineState *ms, stellaris_board_info *board)
 {
     static const int uart_irq[] = {5, 6, 33, 34};
     static const int timer_irq[] = {19, 21, 23, 35};
@@ -1298,7 +1298,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
     memory_region_add_subregion(system_memory, 0x20000000, sram);
 
     nvic = armv7m_init(system_memory, flash_size, NUM_IRQ_LINES,
-                      kernel_filename, cpu_model);
+                       ms->kernel_filename, ms->cpu_type);
 
     qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0,
                                 qemu_allocate_irq(&do_sys_reset, NULL, 0));
@@ -1435,16 +1435,12 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
 /* FIXME: Figure out how to generate these from stellaris_boards.  */
 static void lm3s811evb_init(MachineState *machine)
 {
-    const char *cpu_model = machine->cpu_model;
-    const char *kernel_filename = machine->kernel_filename;
-    stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
+    stellaris_init(machine, &stellaris_boards[0]);
 }
 
 static void lm3s6965evb_init(MachineState *machine)
 {
-    const char *cpu_model = machine->cpu_model;
-    const char *kernel_filename = machine->kernel_filename;
-    stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
+    stellaris_init(machine, &stellaris_boards[1]);
 }
 
 static void lm3s811evb_class_init(ObjectClass *oc, void *data)
@@ -1454,6 +1450,7 @@ static void lm3s811evb_class_init(ObjectClass *oc, void *data)
     mc->desc = "Stellaris LM3S811EVB";
     mc->init = lm3s811evb_init;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
 }
 
 static const TypeInfo lm3s811evb_type = {
@@ -1469,6 +1466,7 @@ static void lm3s6965evb_class_init(ObjectClass *oc, void *data)
     mc->desc = "Stellaris LM3S6965EVB";
     mc->init = lm3s6965evb_init;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
 }
 
 static const TypeInfo lm3s6965evb_type = {
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
index f61e735f0f..1cd6374e07 100644
--- a/hw/arm/stm32f205_soc.c
+++ b/hw/arm/stm32f205_soc.c
@@ -112,7 +112,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
 
     armv7m = DEVICE(&s->armv7m);
     qdev_prop_set_uint32(armv7m, "num-irq", 96);
-    qdev_prop_set_string(armv7m, "cpu-model", s->cpu_model);
+    qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
     object_property_set_link(OBJECT(&s->armv7m), OBJECT(get_system_memory()),
                                      "memory", &error_abort);
     object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
@@ -200,7 +200,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
 }
 
 static Property stm32f205_soc_properties[] = {
-    DEFINE_PROP_STRING("cpu-model", STM32F205State, cpu_model),
+    DEFINE_PROP_STRING("cpu-type", STM32F205State, cpu_type),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index c1145dd723..3d1a231d9e 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -1581,23 +1581,19 @@ static const TypeInfo strongarm_ssp_info = {
 
 /* Main CPU functions */
 StrongARMState *sa1110_init(MemoryRegion *sysmem,
-                            unsigned int sdram_size, const char *rev)
+                            unsigned int sdram_size, const char *cpu_type)
 {
     StrongARMState *s;
     int i;
 
     s = g_new0(StrongARMState, 1);
 
-    if (!rev) {
-        rev = "sa1110-b5";
-    }
-
-    if (strncmp(rev, "sa1110", 6)) {
+    if (strncmp(cpu_type, "sa1110", 6)) {
         error_report("Machine requires a SA1110 processor.");
         exit(1);
     }
 
-    s->cpu = ARM_CPU(cpu_generic_init(TYPE_ARM_CPU, rev));
+    s->cpu = ARM_CPU(cpu_create(cpu_type));
 
     memory_region_allocate_system_memory(&s->sdram, NULL, "strongarm.sdram",
                                          sdram_size);
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index 1134cf74db..044796350a 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -219,7 +219,6 @@ static struct arm_boot_info tosa_binfo = {
 
 static void tosa_init(MachineState *machine)
 {
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -229,9 +228,6 @@ static void tosa_init(MachineState *machine)
     TC6393xbState *tmio;
     DeviceState *scp0, *scp1;
 
-    if (!cpu_model)
-        cpu_model = "pxa255";
-
     mpu = pxa255_init(address_space_mem, tosa_binfo.ram_size);
 
     memory_region_init_ram(rom, NULL, "tosa.rom", TOSA_ROM, &error_fatal);
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 76664e4722..418792cd02 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -181,7 +181,6 @@ static struct arm_boot_info versatile_binfo;
 
 static void versatile_init(MachineState *machine, int board_id)
 {
-    ObjectClass *cpu_oc;
     Object *cpuobj;
     ARMCPU *cpu;
     MemoryRegion *sysmem = get_system_memory();
@@ -207,17 +206,7 @@ static void versatile_init(MachineState *machine, int board_id)
         exit(1);
     }
 
-    if (!machine->cpu_model) {
-        machine->cpu_model = "arm926";
-    }
-
-    cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, machine->cpu_model);
-    if (!cpu_oc) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
-
-    cpuobj = object_new(object_class_get_name(cpu_oc));
+    cpuobj = object_new(machine->cpu_type);
 
     /* By default ARM1176 CPUs have EL3 enabled.  This board does not
      * currently support EL3 so the CPU EL3 property is disabled before
@@ -404,6 +393,7 @@ static void versatilepb_class_init(ObjectClass *oc, void *data)
     mc->init = vpb_init;
     mc->block_default_type = IF_SCSI;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
 }
 
 static const TypeInfo versatilepb_type = {
@@ -420,6 +410,7 @@ static void versatileab_class_init(ObjectClass *oc, void *data)
     mc->init = vab_init;
     mc->block_default_type = IF_SCSI;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
 }
 
 static const TypeInfo versatileab_type = {
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index e3acab6adf..2e5f670c2b 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -186,7 +186,7 @@ typedef struct {
 
 typedef void DBoardInitFn(const VexpressMachineState *machine,
                           ram_addr_t ram_size,
-                          const char *cpu_model,
+                          const char *cpu_type,
                           qemu_irq *pic);
 
 struct VEDBoardInfo {
@@ -202,22 +202,16 @@ struct VEDBoardInfo {
     DBoardInitFn *init;
 };
 
-static void init_cpus(const char *cpu_model, const char *privdev,
+static void init_cpus(const char *cpu_type, const char *privdev,
                       hwaddr periphbase, qemu_irq *pic, bool secure)
 {
-    ObjectClass *cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
     DeviceState *dev;
     SysBusDevice *busdev;
     int n;
 
-    if (!cpu_oc) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
-    }
-
     /* Create the actual CPUs */
     for (n = 0; n < smp_cpus; n++) {
-        Object *cpuobj = object_new(object_class_get_name(cpu_oc));
+        Object *cpuobj = object_new(cpu_type);
 
         if (!secure) {
             object_property_set_bool(cpuobj, false, "has_el3", NULL);
@@ -262,7 +256,7 @@ static void init_cpus(const char *cpu_model, const char *privdev,
 
 static void a9_daughterboard_init(const VexpressMachineState *vms,
                                   ram_addr_t ram_size,
-                                  const char *cpu_model,
+                                  const char *cpu_type,
                                   qemu_irq *pic)
 {
     MemoryRegion *sysmem = get_system_memory();
@@ -270,10 +264,6 @@ static void a9_daughterboard_init(const VexpressMachineState *vms,
     MemoryRegion *lowram = g_new(MemoryRegion, 1);
     ram_addr_t low_ram_size;
 
-    if (!cpu_model) {
-        cpu_model = "cortex-a9";
-    }
-
     if (ram_size > 0x40000000) {
         /* 1GB is the maximum the address space permits */
         fprintf(stderr, "vexpress-a9: cannot model more than 1GB RAM\n");
@@ -295,7 +285,7 @@ static void a9_daughterboard_init(const VexpressMachineState *vms,
     memory_region_add_subregion(sysmem, 0x60000000, ram);
 
     /* 0x1e000000 A9MPCore (SCU) private memory region */
-    init_cpus(cpu_model, TYPE_A9MPCORE_PRIV, 0x1e000000, pic, vms->secure);
+    init_cpus(cpu_type, TYPE_A9MPCORE_PRIV, 0x1e000000, pic, vms->secure);
 
     /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */
 
@@ -351,17 +341,13 @@ static VEDBoardInfo a9_daughterboard = {
 
 static void a15_daughterboard_init(const VexpressMachineState *vms,
                                    ram_addr_t ram_size,
-                                   const char *cpu_model,
+                                   const char *cpu_type,
                                    qemu_irq *pic)
 {
     MemoryRegion *sysmem = get_system_memory();
     MemoryRegion *ram = g_new(MemoryRegion, 1);
     MemoryRegion *sram = g_new(MemoryRegion, 1);
 
-    if (!cpu_model) {
-        cpu_model = "cortex-a15";
-    }
-
     {
         /* We have to use a separate 64 bit variable here to avoid the gcc
          * "comparison is always false due to limited range of data type"
@@ -380,7 +366,7 @@ static void a15_daughterboard_init(const VexpressMachineState *vms,
     memory_region_add_subregion(sysmem, 0x80000000, ram);
 
     /* 0x2c000000 A15MPCore private memory region (GIC) */
-    init_cpus(cpu_model, TYPE_A15MPCORE_PRIV, 0x2c000000, pic, vms->secure);
+    init_cpus(cpu_type, TYPE_A15MPCORE_PRIV, 0x2c000000, pic, vms->secure);
 
     /* A15 daughterboard peripherals: */
 
@@ -560,7 +546,7 @@ static void vexpress_common_init(MachineState *machine)
     const hwaddr *map = daughterboard->motherboard_map;
     int i;
 
-    daughterboard->init(vms, machine->ram_size, machine->cpu_model, pic);
+    daughterboard->init(vms, machine->ram_size, machine->cpu_type, pic);
 
     /*
      * If a bios file was provided, attempt to map it into memory
@@ -761,6 +747,7 @@ static void vexpress_a9_class_init(ObjectClass *oc, void *data)
     VexpressMachineClass *vmc = VEXPRESS_MACHINE_CLASS(oc);
 
     mc->desc = "ARM Versatile Express for Cortex-A9";
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
 
     vmc->daughterboard = &a9_daughterboard;
 }
@@ -771,6 +758,7 @@ static void vexpress_a15_class_init(ObjectClass *oc, void *data)
     VexpressMachineClass *vmc = VEXPRESS_MACHINE_CLASS(oc);
 
     mc->desc = "ARM Versatile Express for Cortex-A15";
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
 
     vmc->daughterboard = &a15_daughterboard;
 }
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index cfd834d0cc..65d68bc50d 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -163,13 +163,13 @@ static const int a15irqmap[] = {
 };
 
 static const char *valid_cpus[] = {
-    "cortex-a15",
-    "cortex-a53",
-    "cortex-a57",
-    "host",
+    ARM_CPU_TYPE_NAME("cortex-a15"),
+    ARM_CPU_TYPE_NAME("cortex-a53"),
+    ARM_CPU_TYPE_NAME("cortex-a57"),
+    ARM_CPU_TYPE_NAME("host"),
 };
 
-static bool cpuname_valid(const char *cpu)
+static bool cpu_type_valid(const char *cpu)
 {
     int i;
 
@@ -1259,18 +1259,8 @@ static void machvirt_init(MachineState *machine)
     MemoryRegion *secure_sysmem = NULL;
     int n, virt_max_cpus;
     MemoryRegion *ram = g_new(MemoryRegion, 1);
-    const char *cpu_model = machine->cpu_model;
-    char **cpustr;
-    ObjectClass *oc;
-    const char *typename;
-    CPUClass *cc;
-    Error *err = NULL;
     bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
 
-    if (!cpu_model) {
-        cpu_model = "cortex-a15";
-    }
-
     /* We can probe only here because during property set
      * KVM is not available yet
      */
@@ -1287,11 +1277,8 @@ static void machvirt_init(MachineState *machine)
         }
     }
 
-    /* Separate the actual CPU model name from any appended features */
-    cpustr = g_strsplit(cpu_model, ",", 2);
-
-    if (!cpuname_valid(cpustr[0])) {
-        error_report("mach-virt: CPU %s not supported", cpustr[0]);
+    if (!cpu_type_valid(machine->cpu_type)) {
+        error_report("mach-virt: CPU type %s not supported", machine->cpu_type);
         exit(1);
     }
 
@@ -1361,22 +1348,6 @@ static void machvirt_init(MachineState *machine)
 
     create_fdt(vms);
 
-    oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
-    if (!oc) {
-        error_report("Unable to find CPU definition");
-        exit(1);
-    }
-    typename = object_class_get_name(oc);
-
-    /* convert -smp CPU options specified by the user into global props */
-    cc = CPU_CLASS(oc);
-    cc->parse_features(typename, cpustr[1], &err);
-    g_strfreev(cpustr);
-    if (err) {
-        error_report_err(err);
-        exit(1);
-    }
-
     possible_cpus = mc->possible_cpu_arch_ids(machine);
     for (n = 0; n < possible_cpus->len; n++) {
         Object *cpuobj;
@@ -1386,7 +1357,7 @@ static void machvirt_init(MachineState *machine)
             break;
         }
 
-        cpuobj = object_new(typename);
+        cpuobj = object_new(machine->cpu_type);
         object_property_set_int(cpuobj, possible_cpus->cpus[n].arch_id,
                                 "mp-affinity", NULL);
 
@@ -1631,6 +1602,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
     mc->minimum_page_bits = 12;
     mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
     mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
 }
 
 static const TypeInfo virt_machine_info = {
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 3759cf8dc3..1836a4ed45 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -158,11 +158,9 @@ static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
 static void zynq_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
-    ObjectClass *cpu_oc;
     ARMCPU *cpu;
     MemoryRegion *address_space_mem = get_system_memory();
     MemoryRegion *ext_ram = g_new(MemoryRegion, 1);
@@ -174,12 +172,7 @@ static void zynq_init(MachineState *machine)
     qemu_irq pic[64];
     int n;
 
-    if (!cpu_model) {
-        cpu_model = "cortex-a9";
-    }
-    cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
-
-    cpu = ARM_CPU(object_new(object_class_get_name(cpu_oc)));
+    cpu = ARM_CPU(object_new(machine->cpu_type));
 
     /* By default A9 CPUs have EL3 enabled.  This board does not
      * currently support EL3 so the CPU EL3 property is disabled before
@@ -327,6 +320,7 @@ static void zynq_machine_init(MachineClass *mc)
     mc->max_cpus = 1;
     mc->no_sdcard = 1;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
 }
 
 DEFINE_MACHINE("xilinx-zynq-a9", zynq_machine_init)
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 417bc1ac33..60561c7b7c 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -26,6 +26,7 @@
 #include "audio/audio.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
+#include "cpu.h"
 
 #ifdef DEBUG_Z2
 #define DPRINTF(fmt, ...) \
@@ -296,7 +297,6 @@ static const TypeInfo aer915_info = {
 
 static void z2_init(MachineState *machine)
 {
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -309,12 +309,8 @@ static void z2_init(MachineState *machine)
     I2CBus *bus;
     DeviceState *wm;
 
-    if (!cpu_model) {
-        cpu_model = "pxa270-c5";
-    }
-
     /* Setup CPU & memory */
-    mpu = pxa270_init(address_space_mem, z2_binfo.ram_size, cpu_model);
+    mpu = pxa270_init(address_space_mem, z2_binfo.ram_size, machine->cpu_type);
 
 #ifdef TARGET_WORDS_BIGENDIAN
     be = 1;
@@ -371,6 +367,7 @@ static void z2_machine_init(MachineClass *mc)
     mc->desc = "Zipit Z2 (PXA27x)";
     mc->init = z2_init;
     mc->ignore_memory_transaction_failures = true;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c5");
 }
 
 DEFINE_MACHINE("z2", z2_machine_init)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 412e94c7ad..20a3445bda 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -911,7 +911,7 @@ static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
     }
 
     cpuname = g_strsplit(cpu_model, ",", 1);
-    typename = g_strdup_printf("%s-" TYPE_ARM_CPU, cpuname[0]);
+    typename = g_strdup_printf(ARM_CPU_TYPE_NAME("%s"), cpuname[0]);
     oc = object_class_by_name(typename);
     g_strfreev(cpuname);
     g_free(typename);
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 09/12] numa: cpu: calculate/set default node-ids after all -numa CLI options are parsed
  2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
                   ` (7 preceding siblings ...)
  2017-09-19 20:18 ` [Qemu-devel] [PULL 08/12] arm: drop intermediate cpu_model -> cpu type parsing and use cpu type directly Eduardo Habkost
@ 2017-09-19 20:18 ` Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 10/12] NUMA: Replace MAX_NODES with nb_numa_nodes in for loop Eduardo Habkost
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-19 20:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel; +Cc: Marcel Apfelbaum, Igor Mammedov

From: Igor Mammedov <imammedo@redhat.com>

Calculating default node-ids for CPUs in possible_cpu_arch_ids()
is rather fragile since defaults calculation uses nb_numa_nodes but
callback might be potentially called early before all -numa CLI
options are parsed, which would lead to cpus assigned only upto
nb_numa_nodes at the time possible_cpu_arch_ids() is called.

Issue was introduced by
(7c88e65 numa: mirror cpu to node mapping in MachineState::possible_cpus)
and for example CLI:
  -smp 4 -numa node,cpus=0 -numa node
would set props.node-id in possible_cpus array for every non
explicitly mapped CPU to the first node.

Issue is not visible to guest nor to mgmt interface due to
  1) implictly mapped cpus are forced to the first node in
     case of partial mapping
  2) in case of default mapping possible_cpu_arch_ids() is
     called after all -numa options are parsed (resulting
     in correct mapping).

However it's fragile to rely on late execution of
possible_cpu_arch_ids(), therefore add machine specific
callback that returns node-id for CPU and use it to calculate/
set defaults at machine_numa_finish_init() time when all -numa
options are parsed.

Reported-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <1496314408-163972-1-git-send-email-imammedo@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/hw/boards.h |  4 ++++
 hw/arm/virt.c       | 14 ++++++--------
 hw/core/machine.c   |  1 +
 hw/i386/pc.c        | 20 +++++++++++---------
 hw/ppc/spapr.c      | 15 ++++++---------
 5 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/include/hw/boards.h b/include/hw/boards.h
index 6b67adaef6..156e0a5701 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -123,6 +123,9 @@ typedef struct {
  *    Returns an array of @CPUArchId architecture-dependent CPU IDs
  *    which includes CPU IDs for present and possible to hotplug CPUs.
  *    Caller is responsible for freeing returned list.
+ * @get_default_cpu_node_id:
+ *    returns default board specific node_id value for CPU slot specified by
+ *    index @idx in @ms->possible_cpus[]
  * @has_hotpluggable_cpus:
  *    If true, board supports CPUs creation with -device/device_add.
  * @default_cpu_type:
@@ -196,6 +199,7 @@ struct MachineClass {
     CpuInstanceProperties (*cpu_index_to_instance_props)(MachineState *machine,
                                                          unsigned cpu_index);
     const CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine);
+    int64_t (*get_default_cpu_node_id)(const MachineState *ms, int idx);
 };
 
 /**
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 65d68bc50d..9e18b410d7 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1554,6 +1554,11 @@ virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
     return possible_cpus->cpus[cpu_index].props;
 }
 
+static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
+{
+    return idx % nb_numa_nodes;
+}
+
 static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
 {
     int n;
@@ -1572,14 +1577,6 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
             virt_cpu_mp_affinity(vms, n);
         ms->possible_cpus->cpus[n].props.has_thread_id = true;
         ms->possible_cpus->cpus[n].props.thread_id = n;
-
-        /* default distribution of CPUs over NUMA nodes */
-        if (nb_numa_nodes) {
-            /* preset values but do not enable them i.e. 'has_node_id = false',
-             * numa init code will enable them later if manual mapping wasn't
-             * present on CLI */
-            ms->possible_cpus->cpus[n].props.node_id = n % nb_numa_nodes;
-        }
     }
     return ms->possible_cpus;
 }
@@ -1603,6 +1600,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
     mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
     mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
     mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
+    mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
 }
 
 static const TypeInfo virt_machine_info = {
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 41b53a17ad..80647edc2a 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -724,6 +724,7 @@ static void machine_numa_finish_init(MachineState *machine)
             /* fetch default mapping from board and enable it */
             CpuInstanceProperties props = cpu_slot->props;
 
+            props.node_id = mc->get_default_cpu_node_id(machine, i);
             if (!default_mapping) {
                 /* record slots with not set mapping,
                  * TODO: make it hard error in future */
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 2247ac0a01..610c65aeab 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2234,6 +2234,16 @@ pc_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
     return possible_cpus->cpus[cpu_index].props;
 }
 
+static int64_t pc_get_default_cpu_node_id(const MachineState *ms, int idx)
+{
+   X86CPUTopoInfo topo;
+
+   assert(idx < ms->possible_cpus->len);
+   x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id,
+                            smp_cores, smp_threads, &topo);
+   return topo.pkg_id % nb_numa_nodes;
+}
+
 static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms)
 {
     int i;
@@ -2263,15 +2273,6 @@ static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms)
         ms->possible_cpus->cpus[i].props.core_id = topo.core_id;
         ms->possible_cpus->cpus[i].props.has_thread_id = true;
         ms->possible_cpus->cpus[i].props.thread_id = topo.smt_id;
-
-        /* default distribution of CPUs over NUMA nodes */
-        if (nb_numa_nodes) {
-            /* preset values but do not enable them i.e. 'has_node_id = false',
-             * numa init code will enable them later if manual mapping wasn't
-             * present on CLI */
-            ms->possible_cpus->cpus[i].props.node_id =
-                topo.pkg_id % nb_numa_nodes;
-        }
     }
     return ms->possible_cpus;
 }
@@ -2316,6 +2317,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
     pcmc->linuxboot_dma_enabled = true;
     mc->get_hotplug_handler = pc_get_hotpug_handler;
     mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
+    mc->get_default_cpu_node_id = pc_get_default_cpu_node_id;
     mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
     mc->has_hotpluggable_cpus = true;
     mc->default_boot_order = "cad";
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f680f28a15..17ea77618c 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3404,6 +3404,11 @@ spapr_cpu_index_to_props(MachineState *machine, unsigned cpu_index)
     return core_slot->props;
 }
 
+static int64_t spapr_get_default_cpu_node_id(const MachineState *ms, int idx)
+{
+    return idx / smp_cores % nb_numa_nodes;
+}
+
 static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine)
 {
     int i;
@@ -3428,15 +3433,6 @@ static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine)
         machine->possible_cpus->cpus[i].arch_id = core_id;
         machine->possible_cpus->cpus[i].props.has_core_id = true;
         machine->possible_cpus->cpus[i].props.core_id = core_id;
-
-        /* default distribution of CPUs over NUMA nodes */
-        if (nb_numa_nodes) {
-            /* preset values but do not enable them i.e. 'has_node_id = false',
-             * numa init code will enable them later if manual mapping wasn't
-             * present on CLI */
-            machine->possible_cpus->cpus[i].props.node_id =
-                core_id / smp_threads / smp_cores % nb_numa_nodes;
-        }
     }
     return machine->possible_cpus;
 }
@@ -3587,6 +3583,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     hc->pre_plug = spapr_machine_device_pre_plug;
     hc->plug = spapr_machine_device_plug;
     mc->cpu_index_to_instance_props = spapr_cpu_index_to_props;
+    mc->get_default_cpu_node_id = spapr_get_default_cpu_node_id;
     mc->possible_cpu_arch_ids = spapr_possible_cpu_arch_ids;
     hc->unplug_request = spapr_machine_device_unplug_request;
 
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 10/12] NUMA: Replace MAX_NODES with nb_numa_nodes in for loop
  2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
                   ` (8 preceding siblings ...)
  2017-09-19 20:18 ` [Qemu-devel] [PULL 09/12] numa: cpu: calculate/set default node-ids after all -numa CLI options are parsed Eduardo Habkost
@ 2017-09-19 20:18 ` Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 11/12] hw/acpi-build: Fix SRAT memory building in case of node 0 without RAM Eduardo Habkost
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-19 20:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel; +Cc: Marcel Apfelbaum, Igor Mammedov, Dou Liyang

From: Dou Liyang <douly.fnst@cn.fujitsu.com>

In QEMU, the number of the NUMA nodes is determined by parse_numa_opts().
Then, QEMU uses it for iteration, for example:
  for (i = 0; i < nb_numa_nodes; i++)

However, in memory_region_allocate_system_memory(), it uses MAX_NODES
not nb_numa_nodes.

So, replace MAX_NODES with nb_numa_nodes to keep code consistency and
reduce the loop times.

Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
Message-Id: <1503387936-3483-1-git-send-email-douly.fnst@cn.fujitsu.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 numa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/numa.c b/numa.c
index fe066ad2f8..100a67febf 100644
--- a/numa.c
+++ b/numa.c
@@ -567,7 +567,7 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
     }
 
     memory_region_init(mr, owner, name, ram_size);
-    for (i = 0; i < MAX_NODES; i++) {
+    for (i = 0; i < nb_numa_nodes; i++) {
         uint64_t size = numa_info[i].node_mem;
         HostMemoryBackend *backend = numa_info[i].node_memdev;
         if (!backend) {
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 11/12] hw/acpi-build: Fix SRAT memory building in case of node 0 without RAM
  2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
                   ` (9 preceding siblings ...)
  2017-09-19 20:18 ` [Qemu-devel] [PULL 10/12] NUMA: Replace MAX_NODES with nb_numa_nodes in for loop Eduardo Habkost
@ 2017-09-19 20:18 ` Eduardo Habkost
  2017-09-19 20:18 ` [Qemu-devel] [PULL 12/12] MAINTAINERS: Update git URLs for my trees Eduardo Habkost
  2017-09-20 18:16 ` [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Peter Maydell
  12 siblings, 0 replies; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-19 20:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel; +Cc: Marcel Apfelbaum, Igor Mammedov

Currently, Using the fisrt node without memory on the machine makes
QEMU unhappy. With this example command line:
  ... \
  -m 1024M,slots=4,maxmem=32G \
  -numa node,nodeid=0 \
  -numa node,mem=1024M,nodeid=1 \
  -numa node,nodeid=2 \
  -numa node,nodeid=3 \
Guest reports "No NUMA configuration found" and the NUMA topology is
wrong.

This is because when QEMU builds ACPI SRAT, it regards node 0 as the
default node to deal with the memory hole(640K-1M). this means the
node0 must have some memory(>1M), but, actually it can have no
memory.

Fix this problem by cut out the 640K hole in the same way the PCI
4G hole does.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
Message-Id: <1504231805-30957-2-git-send-email-douly.fnst@cn.fujitsu.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/i386/acpi-build.c | 28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4d19d91e1b..d72bcdcd49 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2288,6 +2288,9 @@ build_tpm2(GArray *table_data, BIOSLinker *linker)
                  (void *)tpm2_ptr, "TPM2", sizeof(*tpm2_ptr), 4, NULL, NULL);
 }
 
+#define HOLE_640K_START  (640 * 1024)
+#define HOLE_640K_END   (1024 * 1024)
+
 static void
 build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
 {
@@ -2343,17 +2346,30 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
     next_base = 0;
     numa_start = table_data->len;
 
-    numamem = acpi_data_push(table_data, sizeof *numamem);
-    build_srat_memory(numamem, 0, 640 * 1024, 0, MEM_AFFINITY_ENABLED);
-    next_base = 1024 * 1024;
     for (i = 1; i < pcms->numa_nodes + 1; ++i) {
         mem_base = next_base;
         mem_len = pcms->node_mem[i - 1];
-        if (i == 1) {
-            mem_len -= 1024 * 1024;
-        }
         next_base = mem_base + mem_len;
 
+        /* Cut out the 640K hole */
+        if (mem_base <= HOLE_640K_START &&
+            next_base > HOLE_640K_START) {
+            mem_len -= next_base - HOLE_640K_START;
+            if (mem_len > 0) {
+                numamem = acpi_data_push(table_data, sizeof *numamem);
+                build_srat_memory(numamem, mem_base, mem_len, i - 1,
+                                  MEM_AFFINITY_ENABLED);
+            }
+
+            /* Check for the rare case: 640K < RAM < 1M */
+            if (next_base <= HOLE_640K_END) {
+                next_base = HOLE_640K_END;
+                continue;
+            }
+            mem_base = HOLE_640K_END;
+            mem_len = next_base - HOLE_640K_END;
+        }
+
         /* Cut out the ACPI_PCI hole */
         if (mem_base <= pcms->below_4g_mem_size &&
             next_base > pcms->below_4g_mem_size) {
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 12/12] MAINTAINERS: Update git URLs for my trees
  2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
                   ` (10 preceding siblings ...)
  2017-09-19 20:18 ` [Qemu-devel] [PULL 11/12] hw/acpi-build: Fix SRAT memory building in case of node 0 without RAM Eduardo Habkost
@ 2017-09-19 20:18 ` Eduardo Habkost
  2017-09-20 18:16 ` [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Peter Maydell
  12 siblings, 0 replies; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-19 20:18 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel; +Cc: Marcel Apfelbaum, Igor Mammedov

List the branches where I queue patches for Machine Core, NUMA,
Memory Backends, and X86.  Update the NUMA section to list the
"machine-next" branch instead of "numa".

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20170901153928.17058-1-ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 MAINTAINERS | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4bd1797330..5ba7cf056a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -249,6 +249,7 @@ S: Maintained
 F: target/i386/
 F: hw/i386/
 F: disas/i386.c
+T: git git://github.com/ehabkost/qemu.git x86-next
 
 Xtensa
 M: Max Filippov <jcmvbkbc@gmail.com>
@@ -857,6 +858,7 @@ S: Supported
 F: hw/core/machine.c
 F: hw/core/null-machine.c
 F: include/hw/boards.h
+T: git git://github.com/ehabkost/qemu.git machine-next
 
 Xtensa Machines
 ---------------
@@ -1374,7 +1376,7 @@ M: Eduardo Habkost <ehabkost@redhat.com>
 S: Maintained
 F: numa.c
 F: include/sysemu/numa.h
-T: git git://github.com/ehabkost/qemu.git numa
+T: git git://github.com/ehabkost/qemu.git machine-next
 
 Host Memory Backends
 M: Eduardo Habkost <ehabkost@redhat.com>
@@ -1382,6 +1384,7 @@ M: Igor Mammedov <imammedo@redhat.com>
 S: Maintained
 F: backends/hostmem*.c
 F: include/sysemu/hostmem.h
+T: git git://github.com/ehabkost/qemu.git machine-next
 
 Cryptodev Backends
 M: Gonglei <arei.gonglei@huawei.com>
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19
  2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
                   ` (11 preceding siblings ...)
  2017-09-19 20:18 ` [Qemu-devel] [PULL 12/12] MAINTAINERS: Update git URLs for my trees Eduardo Habkost
@ 2017-09-20 18:16 ` Peter Maydell
  12 siblings, 0 replies; 21+ messages in thread
From: Peter Maydell @ 2017-09-20 18:16 UTC (permalink / raw)
  To: Eduardo Habkost; +Cc: QEMU Developers, Marcel Apfelbaum, Igor Mammedov

On 19 September 2017 at 21:18, Eduardo Habkost <ehabkost@redhat.com> wrote:
> The following changes since commit a9158a5cba955b79d580a252cc58ff44d154e370:
>
>   Merge remote-tracking branch 'remotes/kraxel/tags/audio-20170918-pull-request' into staging (2017-09-18 12:40:54 +0100)
>
> are available in the git repository at:
>
>   git://github.com/ehabkost/qemu.git tags/machine-next-pull-request
>
> for you to fetch changes up to e3d038b89f1bf3f09da4d59aa16b16e8305e1a05:
>
>   MAINTAINERS: Update git URLs for my trees (2017-09-19 16:53:13 -0300)
>
> ----------------------------------------------------------------
> Machine/CPU/NUMA queue, 2017-09-19
>
> ----------------------------------------------------------------
>

Applied, thanks.

-- PMM

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PULL 01/12] vl: Clean up user-creatable objects when exiting
  2017-09-19 20:18 ` [Qemu-devel] [PULL 01/12] vl: Clean up user-creatable objects when exiting Eduardo Habkost
@ 2017-09-26 10:14   ` Christian Borntraeger
  2017-09-26 12:24     ` Eduardo Habkost
  0 siblings, 1 reply; 21+ messages in thread
From: Christian Borntraeger @ 2017-09-26 10:14 UTC (permalink / raw)
  To: Eduardo Habkost, Peter Maydell, qemu-devel
  Cc: Marcel Apfelbaum, Igor Mammedov

This patch triggers the following crash on shutdown:


                Stack trace of thread 61598:
                #0  0x000003ff8990915e pthread_join (libpthread.so.0)
                #1  0x00000000014ddfda qemu_thread_join (qemu-system-s390x)
                #2  0x00000000011bbd68 iothread_stop (qemu-system-s390x)
                #3  0x00000000011bbe36 iothread_instance_finalize (qemu-system-s390x)
                #4  0x000000000135b4a4 object_deinit (qemu-system-s390x)
                #5  0x000000000135b548 object_finalize (qemu-system-s390x)
                #6  0x000000000135cc02 object_unref (qemu-system-s390x)
                #7  0x000000000135e61a object_finalize_child_property (qemu-system-s390x)
                #8  0x000000000135b16a object_property_del_all (qemu-system-s390x)
                #9  0x000000000135b536 object_finalize (qemu-system-s390x)
                #10 0x000000000135cc02 object_unref (qemu-system-s390x)
                #11 0x000000000135e61a object_finalize_child_property (qemu-system-s390x)
                #12 0x000000000135b2ea object_property_del_child (qemu-system-s390x)
                #13 0x000000000135b44a object_unparent (qemu-system-s390x)
                #14 0x0000000001362754 user_creatable_cleanup (qemu-system-s390x)
                #15 0x00000000011d012a main (qemu-system-s390x)
                #16 0x000003ff8972289a __libc_start_main (libc.so.6)
                #17 0x0000000001017646 _start (qemu-system-s390x)


command line parameters are long (one of my test systems)

-name guest=zhyp137,debug-threads=on -S -object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-7-zhyp137/master-key.aes -machine s390-ccw-virtio-2.11,accel=kvm,usb=off,dump-guest-core=off,loadparm=PROMPT -m 2048 -realtime mlock=off -smp 4,sockets=4,cores=1,threads=1 -object iothread,id=iothread1 -object iothread,id=iothread2 -object iothread,id=iothread3 -object iothread,id=iothread4 -object iothread,id=iothread5 -object iothread,id=iothread6 -object iothread,id=iothread7 -object iothread,id=iothread8 -object iothread,id=iothread9 -object iothread,id=iothread10 -object iothread,id=iothread11 -object iothread,id=iothread12 -object iothread,id=iothread13 -object iothread,id=iothread14 -object iothread,id=iothread15 -object iothread,id=iothread16 -object iothread,id=iothread17 -object iothread,id=iothread18 -object iothread,id=iothread19 -object iothread,id=iothread20 -uuid 4c3ae636-529d-4d90-b203-c8d3d150f0d0 -display none -no-user-config -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/domain-7-zhyp137/monitor.sock,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -boot strict=on -drive file=/var/lib/libvirt/qemu/image.zhyp137,format=qcow2,if=none,id=drive-virtio-disk0,serial=skel,cache=none -device virtio-blk-ccw,iothread=iothread1,scsi=off,devno=fe.0.0000,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 -drive file=/var/lib/libvirt/qemu/image.zhyp137.old,format=qcow2,if=none,id=drive-virtio-disk1,serial=old,cache=none -device virtio-blk-ccw,iothread=iothread1,scsi=off,devno=fe.0.0001,drive=drive-virtio-disk1,id=virtio-disk1 -netdev tap,fd=24,id=hostnet0,vhost=on,vhostfd=26 -device virtio-net-ccw,netdev=hostnet0,id=net0,mac=52:54:00:d1:cd:1c,devno=fe.0.000d -chardev pty,id=charconsole0 -device sclpconsole,chardev=charconsole0,id=console0 -device virtio-balloon-ccw,id=balloon0,devno=fe.3.ffba -drive driver=null-aio,id=null1,if=none,size=1500G -device virtio-blk-ccw,scsi=off,drive=null1,serial=null1,iothread=iothread16 -drive driver=null-aio,id=null2,if=none,size=1500G -device virtio-blk-ccw,scsi=off,drive=null2,serial=null2,iothread=iothread17 -drive driver=null-aio,id=null3,if=none,size=1500G -device virtio-blk-ccw,scsi=off,drive=null3,serial=null3,iothread=iothread18 -drive driver=null-aio,id=null4,if=none,size=1500G -device virtio-blk-ccw,scsi=off,drive=null4,serial=null4,iothread=iothread19 -drive driver=null-aio,id=null5,if=none,size=1500G -device virtio-blk-ccw,scsi=off,drive=null5,serial=null5,iothread=iothread20,num-queues=10 -gdb tcp::1409 -msg timestamp=on

On 09/19/2017 10:18 PM, Eduardo Habkost wrote:
> Delete all user-creatable objects in /objects when exiting QEMU, so they
> can perform cleanup actions.
> 
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> Message-Id: <20170824192315.5897-2-ehabkost@redhat.com>
> Acked-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Tested-by: Zack Cornelius <zack.cornelius@kove.net>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
>  include/qom/object_interfaces.h | 8 ++++++++
>  qom/object_interfaces.c         | 5 +++++
>  vl.c                            | 1 +
>  3 files changed, 14 insertions(+)
> 
> diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
> index d63c1c28f8..d23e11bc53 100644
> --- a/include/qom/object_interfaces.h
> +++ b/include/qom/object_interfaces.h
> @@ -147,4 +147,12 @@ int user_creatable_add_opts_foreach(void *opaque,
>   */
>  void user_creatable_del(const char *id, Error **errp);
>  
> +/**
> + * user_creatable_cleanup:
> + *
> + * Delete all user-creatable objects and the user-creatable
> + * objects container.
> + */
> +void user_creatable_cleanup(void);
> +
>  #endif
> diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
> index 3bb8959f09..6824a88caa 100644
> --- a/qom/object_interfaces.c
> +++ b/qom/object_interfaces.c
> @@ -193,6 +193,11 @@ void user_creatable_del(const char *id, Error **errp)
>      object_unparent(obj);
>  }
>  
> +void user_creatable_cleanup(void)
> +{
> +    object_unparent(object_get_objects_root());
> +}
> +
>  static void register_types(void)
>  {
>      static const TypeInfo uc_interface_info = {
> diff --git a/vl.c b/vl.c
> index 9e62e92aea..ad49314608 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -4887,6 +4887,7 @@ int main(int argc, char **argv, char **envp)
>      audio_cleanup();
>      monitor_cleanup();
>      qemu_chr_cleanup();
> +    user_creatable_cleanup();
>      /* TODO: unref root container, check all devices are ok */
>  
>      return 0;
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PULL 01/12] vl: Clean up user-creatable objects when exiting
  2017-09-26 10:14   ` Christian Borntraeger
@ 2017-09-26 12:24     ` Eduardo Habkost
  2017-09-26 13:00       ` [Qemu-devel] [PATCH] iothread: Make iothread_stop() idempotent Eduardo Habkost
  0 siblings, 1 reply; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-26 12:24 UTC (permalink / raw)
  To: Christian Borntraeger
  Cc: Peter Maydell, qemu-devel, Marcel Apfelbaum, Igor Mammedov

On Tue, Sep 26, 2017 at 12:14:23PM +0200, Christian Borntraeger wrote:
> This patch triggers the following crash on shutdown:
> 
> 
>                 Stack trace of thread 61598:
>                 #0  0x000003ff8990915e pthread_join (libpthread.so.0)
>                 #1  0x00000000014ddfda qemu_thread_join (qemu-system-s390x)
>                 #2  0x00000000011bbd68 iothread_stop (qemu-system-s390x)
>                 #3  0x00000000011bbe36 iothread_instance_finalize (qemu-system-s390x)
>                 #4  0x000000000135b4a4 object_deinit (qemu-system-s390x)
>                 #5  0x000000000135b548 object_finalize (qemu-system-s390x)
>                 #6  0x000000000135cc02 object_unref (qemu-system-s390x)
>                 #7  0x000000000135e61a object_finalize_child_property (qemu-system-s390x)
>                 #8  0x000000000135b16a object_property_del_all (qemu-system-s390x)
>                 #9  0x000000000135b536 object_finalize (qemu-system-s390x)
>                 #10 0x000000000135cc02 object_unref (qemu-system-s390x)
>                 #11 0x000000000135e61a object_finalize_child_property (qemu-system-s390x)
>                 #12 0x000000000135b2ea object_property_del_child (qemu-system-s390x)
>                 #13 0x000000000135b44a object_unparent (qemu-system-s390x)
>                 #14 0x0000000001362754 user_creatable_cleanup (qemu-system-s390x)
>                 #15 0x00000000011d012a main (qemu-system-s390x)
>                 #16 0x000003ff8972289a __libc_start_main (libc.so.6)
>                 #17 0x0000000001017646 _start (qemu-system-s390x)

It seems to be reproducible with:

$ echo quit | ./x86_64-softmmu/qemu-system-x86_64 -object iothread,id=iothread0 -monitor stdio -display none
QEMU 2.10.50 monitor - type 'help' for more information
(qemu) quit
qemu: qemu_thread_join: No such process
Aborted (core dumped)

iothread_stop() is being called twice for the same thread:

Thread 1 "qemu-system-x86" hit Breakpoint 3, qemu_thread_join (thread=thread@entry=0x10118e198) at /home/ehabkost/rh/proj/virt/qemu/util/qemu-thread-posix.c:543
543     {
(gdb) bt
#0  0x00000001005dc980 in qemu_thread_join (thread=thread@entry=0x10118e198) at /home/ehabkost/rh/proj/virt/qemu/util/qemu-thread-posix.c:543
#1  0x000000010034a12c in iothread_stop (object=<optimized out>, opaque=<optimized out>) at /home/ehabkost/rh/proj/virt/qemu/iothread.c:96
#2  0x0000000100509117 in do_object_child_foreach (obj=obj@entry=0x10118e390, fn=fn@entry=0x10034a0f0 <iothread_stop>, opaque=opaque@entry=0x0, recurse=recurse@entry=false) at /home/ehabkost/rh/proj/virt/qemu/qom/object.c:843
#3  0x000000010050a7a7 in object_child_foreach (obj=obj@entry=0x10118e390, fn=fn@entry=0x10034a0f0 <iothread_stop>, opaque=opaque@entry=0x0) at /home/ehabkost/rh/proj/virt/qemu/qom/object.c:858
#4  0x000000010034a3be in iothread_stop_all () at /home/ehabkost/rh/proj/virt/qemu/iothread.c:331
#5  0x000000010021da4d in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at /home/ehabkost/rh/proj/virt/qemu/vl.c:4886
(gdb) c
Continuing.

Thread 1 "qemu-system-x86" hit Breakpoint 3, qemu_thread_join (thread=thread@entry=0x10118e198) at /home/ehabkost/rh/proj/virt/qemu/util/qemu-thread-posix.c:543
543     {
(gdb) bt
#0  0x00000001005dc980 in qemu_thread_join (thread=thread@entry=0x10118e198) at /home/ehabkost/rh/proj/virt/qemu/util/qemu-thread-posix.c:543
#1  0x000000010034a12c in iothread_stop (object=object@entry=0x10118e170, opaque=opaque@entry=0x0) at /home/ehabkost/rh/proj/virt/qemu/iothread.c:96
#2  0x000000010034a175 in iothread_instance_finalize (obj=0x10118e170) at /home/ehabkost/rh/proj/virt/qemu/iothread.c:111
#3  0x000000010050a90a in object_deinit (type=0x1010dd860, obj=<optimized out>) at /home/ehabkost/rh/proj/virt/qemu/qom/object.c:453
#4  0x000000010050a90a in object_finalize (data=0x10118e170) at /home/ehabkost/rh/proj/virt/qemu/qom/object.c:467
#5  0x000000010050a90a in object_unref (obj=0x10118e170) at /home/ehabkost/rh/proj/virt/qemu/qom/object.c:902
#6  0x000000010050a99d in object_property_del_all (obj=0x10118e390) at /home/ehabkost/rh/proj/virt/qemu/qom/object.c:404
#7  0x000000010050a99d in object_finalize (data=0x10118e390) at /home/ehabkost/rh/proj/virt/qemu/qom/object.c:466
#8  0x000000010050a99d in object_unref (obj=0x10118e390) at /home/ehabkost/rh/proj/virt/qemu/qom/object.c:902
#9  0x0000000100509915 in object_property_del_child (obj=0x101180900, child=0x10118e390, errp=<optimized out>) at /home/ehabkost/rh/proj/virt/qemu/qom/object.c:427
#10 0x000000010021da87 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at /home/ehabkost/rh/proj/virt/qemu/vl.c:4897

> 
> 
> command line parameters are long (one of my test systems)
> 
> -name guest=zhyp137,debug-threads=on -S -object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-7-zhyp137/master-key.aes -machine s390-ccw-virtio-2.11,accel=kvm,usb=off,dump-guest-core=off,loadparm=PROMPT -m 2048 -realtime mlock=off -smp 4,sockets=4,cores=1,threads=1 -object iothread,id=iothread1 -object iothread,id=iothread2 -object iothread,id=iothread3 -object iothread,id=iothread4 -object iothread,id=iothread5 -object iothread,id=iothread6 -object iothread,id=iothread7 -object iothread,id=iothread8 -object iothread,id=iothread9 -object iothread,id=iothread10 -object iothread,id=iothread11 -object iothread,id=iothread12 -object iothread,id=iothread13 -object iothread,id=iothread14 -object iothread,id=iothread15 -object iothread,id=iothread16 -object iothread,id=iothread17 -object iothread,id=iothread18 -object iothread,id=iothread19 -object iothread,id=iothread20 -uuid 4c3ae636-529d-4d90-b203-c8d3d150f0d0 -display none -no-user-config -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/domain-7-zhyp137/monitor.sock,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -boot strict=on -drive file=/var/lib/libvirt/qemu/image.zhyp137,format=qcow2,if=none,id=drive-virtio-disk0,serial=skel,cache=none -device virtio-blk-ccw,iothread=iothread1,scsi=off,devno=fe.0.0000,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 -drive file=/var/lib/libvirt/qemu/image.zhyp137.old,format=qcow2,if=none,id=drive-virtio-disk1,serial=old,cache=none -device virtio-blk-ccw,iothread=iothread1,scsi=off,devno=fe.0.0001,drive=drive-virtio-disk1,id=virtio-disk1 -netdev tap,fd=24,id=hostnet0,vhost=on,vhostfd=26 -device virtio-net-ccw,netdev=hostnet0,id=net0,mac=52:54:00:d1:cd:1c,devno=fe.0.000d -chardev pty,id=charconsole0 -device sclpconsole,chardev=charconsole0,id=console0 -device virtio-balloon-ccw,id=balloon0,devno=fe.3.ffba -drive driver=null-aio,id=null1,if=none,size=1500G -device virtio-blk-ccw,scsi=off,drive=null1,serial=null1,iothread=iothread16 -drive driver=null-aio,id=null2,if=none,size=1500G -device virtio-blk-ccw,scsi=off,drive=null2,serial=null2,iothread=iothread17 -drive driver=null-aio,id=null3,if=none,size=1500G -device virtio-blk-ccw,scsi=off,drive=null3,serial=null3,iothread=iothread18 -drive driver=null-aio,id=null4,if=none,size=1500G -device virtio-blk-ccw,scsi=off,drive=null4,serial=null4,iothread=iothread19 -drive driver=null-aio,id=null5,if=none,size=1500G -device virtio-blk-ccw,scsi=off,drive=null5,serial=null5,iothread=iothread20,num-queues=10 -gdb tcp::1409 -msg timestamp=on
> 
> On 09/19/2017 10:18 PM, Eduardo Habkost wrote:
> > Delete all user-creatable objects in /objects when exiting QEMU, so they
> > can perform cleanup actions.
> > 
> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > Message-Id: <20170824192315.5897-2-ehabkost@redhat.com>
> > Acked-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> > Tested-by: Zack Cornelius <zack.cornelius@kove.net>
> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > ---
> >  include/qom/object_interfaces.h | 8 ++++++++
> >  qom/object_interfaces.c         | 5 +++++
> >  vl.c                            | 1 +
> >  3 files changed, 14 insertions(+)
> > 
> > diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
> > index d63c1c28f8..d23e11bc53 100644
> > --- a/include/qom/object_interfaces.h
> > +++ b/include/qom/object_interfaces.h
> > @@ -147,4 +147,12 @@ int user_creatable_add_opts_foreach(void *opaque,
> >   */
> >  void user_creatable_del(const char *id, Error **errp);
> >  
> > +/**
> > + * user_creatable_cleanup:
> > + *
> > + * Delete all user-creatable objects and the user-creatable
> > + * objects container.
> > + */
> > +void user_creatable_cleanup(void);
> > +
> >  #endif
> > diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
> > index 3bb8959f09..6824a88caa 100644
> > --- a/qom/object_interfaces.c
> > +++ b/qom/object_interfaces.c
> > @@ -193,6 +193,11 @@ void user_creatable_del(const char *id, Error **errp)
> >      object_unparent(obj);
> >  }
> >  
> > +void user_creatable_cleanup(void)
> > +{
> > +    object_unparent(object_get_objects_root());
> > +}
> > +
> >  static void register_types(void)
> >  {
> >      static const TypeInfo uc_interface_info = {
> > diff --git a/vl.c b/vl.c
> > index 9e62e92aea..ad49314608 100644
> > --- a/vl.c
> > +++ b/vl.c
> > @@ -4887,6 +4887,7 @@ int main(int argc, char **argv, char **envp)
> >      audio_cleanup();
> >      monitor_cleanup();
> >      qemu_chr_cleanup();
> > +    user_creatable_cleanup();
> >      /* TODO: unref root container, check all devices are ok */
> >  
> >      return 0;
> > 

-- 
Eduardo

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH] iothread: Make iothread_stop() idempotent
  2017-09-26 12:24     ` Eduardo Habkost
@ 2017-09-26 13:00       ` Eduardo Habkost
  2017-09-26 13:08         ` Christian Borntraeger
  2017-09-29 13:47         ` Christian Borntraeger
  0 siblings, 2 replies; 21+ messages in thread
From: Eduardo Habkost @ 2017-09-26 13:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Peter Maydell, Marcel Apfelbaum,
	Christian Borntraeger, Stefan Hajnoczi, Igor Mammedov

Currently, iothread_stop_all() makes all iothread objects unsafe
to be destroyed, because qemu_thread_join() ends up being called
twice.

To fix this, make iothread_stop() idempotent by checking
thread->stopped.

Fixes the following crash:

  qemu-system-x86_64 -object iothread,id=iothread0 -monitor stdio -display none
  QEMU 2.10.50 monitor - type 'help' for more information
  (qemu) quit
  qemu: qemu_thread_join: No such process
  Aborted (core dumped)

Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 iothread.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/iothread.c b/iothread.c
index 44c8944dc4..59d0850988 100644
--- a/iothread.c
+++ b/iothread.c
@@ -85,7 +85,7 @@ static int iothread_stop(Object *object, void *opaque)
     IOThread *iothread;
 
     iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
-    if (!iothread || !iothread->ctx) {
+    if (!iothread || !iothread->ctx || iothread->stopping) {
         return 0;
     }
     iothread->stopping = true;
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH] iothread: Make iothread_stop() idempotent
  2017-09-26 13:00       ` [Qemu-devel] [PATCH] iothread: Make iothread_stop() idempotent Eduardo Habkost
@ 2017-09-26 13:08         ` Christian Borntraeger
  2017-09-29 13:47         ` Christian Borntraeger
  1 sibling, 0 replies; 21+ messages in thread
From: Christian Borntraeger @ 2017-09-26 13:08 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: Paolo Bonzini, Peter Maydell, Marcel Apfelbaum, Stefan Hajnoczi,
	Igor Mammedov



On 09/26/2017 03:00 PM, Eduardo Habkost wrote:
> Currently, iothread_stop_all() makes all iothread objects unsafe
> to be destroyed, because qemu_thread_join() ends up being called
> twice.
> 
> To fix this, make iothread_stop() idempotent by checking
> thread->stopped.
> 
> Fixes the following crash:
> 
>   qemu-system-x86_64 -object iothread,id=iothread0 -monitor stdio -display none
>   QEMU 2.10.50 monitor - type 'help' for more information
>   (qemu) quit
>   qemu: qemu_thread_join: No such process
>   Aborted (core dumped)
> 
> Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>

Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>

> ---
>  iothread.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/iothread.c b/iothread.c
> index 44c8944dc4..59d0850988 100644
> --- a/iothread.c
> +++ b/iothread.c
> @@ -85,7 +85,7 @@ static int iothread_stop(Object *object, void *opaque)
>      IOThread *iothread;
> 
>      iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
> -    if (!iothread || !iothread->ctx) {
> +    if (!iothread || !iothread->ctx || iothread->stopping) {
>          return 0;
>      }
>      iothread->stopping = true;
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH] iothread: Make iothread_stop() idempotent
  2017-09-26 13:00       ` [Qemu-devel] [PATCH] iothread: Make iothread_stop() idempotent Eduardo Habkost
  2017-09-26 13:08         ` Christian Borntraeger
@ 2017-09-29 13:47         ` Christian Borntraeger
  2017-09-29 14:13           ` Paolo Bonzini
  1 sibling, 1 reply; 21+ messages in thread
From: Christian Borntraeger @ 2017-09-29 13:47 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: Paolo Bonzini, Peter Maydell, Marcel Apfelbaum, Stefan Hajnoczi,
	Igor Mammedov

Is anybody going to pick this up? upstream qemu is still happily filling
up my disk with coredumps on exit.

On 09/26/2017 03:00 PM, Eduardo Habkost wrote:
> Currently, iothread_stop_all() makes all iothread objects unsafe
> to be destroyed, because qemu_thread_join() ends up being called
> twice.
> 
> To fix this, make iothread_stop() idempotent by checking
> thread->stopped.
> 
> Fixes the following crash:
> 
>   qemu-system-x86_64 -object iothread,id=iothread0 -monitor stdio -display none
>   QEMU 2.10.50 monitor - type 'help' for more information
>   (qemu) quit
>   qemu: qemu_thread_join: No such process
>   Aborted (core dumped)
> 
> Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
>  iothread.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/iothread.c b/iothread.c
> index 44c8944dc4..59d0850988 100644
> --- a/iothread.c
> +++ b/iothread.c
> @@ -85,7 +85,7 @@ static int iothread_stop(Object *object, void *opaque)
>      IOThread *iothread;
> 
>      iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
> -    if (!iothread || !iothread->ctx) {
> +    if (!iothread || !iothread->ctx || iothread->stopping) {
>          return 0;
>      }
>      iothread->stopping = true;
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH] iothread: Make iothread_stop() idempotent
  2017-09-29 13:47         ` Christian Borntraeger
@ 2017-09-29 14:13           ` Paolo Bonzini
  2017-09-29 15:57             ` Peter Maydell
  0 siblings, 1 reply; 21+ messages in thread
From: Paolo Bonzini @ 2017-09-29 14:13 UTC (permalink / raw)
  To: Christian Borntraeger, Eduardo Habkost, qemu-devel
  Cc: Peter Maydell, Marcel Apfelbaum, Stefan Hajnoczi, Igor Mammedov

On 29/09/2017 15:47, Christian Borntraeger wrote:
> Is anybody going to pick this up? upstream qemu is still happily filling
> up my disk with coredumps on exit.

I can, but I'll only send the pull request next Monday, probably.

Paolo

> On 09/26/2017 03:00 PM, Eduardo Habkost wrote:
>> Currently, iothread_stop_all() makes all iothread objects unsafe
>> to be destroyed, because qemu_thread_join() ends up being called
>> twice.
>>
>> To fix this, make iothread_stop() idempotent by checking
>> thread->stopped.
>>
>> Fixes the following crash:
>>
>>   qemu-system-x86_64 -object iothread,id=iothread0 -monitor stdio -display none
>>   QEMU 2.10.50 monitor - type 'help' for more information
>>   (qemu) quit
>>   qemu: qemu_thread_join: No such process
>>   Aborted (core dumped)
>>
>> Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
>> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
>> ---
>>  iothread.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/iothread.c b/iothread.c
>> index 44c8944dc4..59d0850988 100644
>> --- a/iothread.c
>> +++ b/iothread.c
>> @@ -85,7 +85,7 @@ static int iothread_stop(Object *object, void *opaque)
>>      IOThread *iothread;
>>
>>      iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
>> -    if (!iothread || !iothread->ctx) {
>> +    if (!iothread || !iothread->ctx || iothread->stopping) {
>>          return 0;
>>      }
>>      iothread->stopping = true;
>>
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH] iothread: Make iothread_stop() idempotent
  2017-09-29 14:13           ` Paolo Bonzini
@ 2017-09-29 15:57             ` Peter Maydell
  0 siblings, 0 replies; 21+ messages in thread
From: Peter Maydell @ 2017-09-29 15:57 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Christian Borntraeger, Eduardo Habkost, QEMU Developers,
	Marcel Apfelbaum, Stefan Hajnoczi, Igor Mammedov

On 29 September 2017 at 07:13, Paolo Bonzini <pbonzini@redhat.com> wrote:
> On 29/09/2017 15:47, Christian Borntraeger wrote:
>> Is anybody going to pick this up? upstream qemu is still happily filling
>> up my disk with coredumps on exit.
>
> I can, but I'll only send the pull request next Monday, probably.

I'm not likely to be able to apply any pull requests til Monday anyway :-)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2017-09-29 15:57 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-19 20:18 [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Eduardo Habkost
2017-09-19 20:18 ` [Qemu-devel] [PULL 01/12] vl: Clean up user-creatable objects when exiting Eduardo Habkost
2017-09-26 10:14   ` Christian Borntraeger
2017-09-26 12:24     ` Eduardo Habkost
2017-09-26 13:00       ` [Qemu-devel] [PATCH] iothread: Make iothread_stop() idempotent Eduardo Habkost
2017-09-26 13:08         ` Christian Borntraeger
2017-09-29 13:47         ` Christian Borntraeger
2017-09-29 14:13           ` Paolo Bonzini
2017-09-29 15:57             ` Peter Maydell
2017-09-19 20:18 ` [Qemu-devel] [PULL 02/12] osdep: Define QEMU_MADV_REMOVE Eduardo Habkost
2017-09-19 20:18 ` [Qemu-devel] [PULL 03/12] hostmem-file: Add "discard-data" option Eduardo Habkost
2017-09-19 20:18 ` [Qemu-devel] [PULL 04/12] qom: cpus: split cpu_generic_init() on feature parsing and cpu creation parts Eduardo Habkost
2017-09-19 20:18 ` [Qemu-devel] [PULL 05/12] cpu: make cpu_generic_init() abort QEMU on error Eduardo Habkost
2017-09-19 20:18 ` [Qemu-devel] [PULL 06/12] vl.c: convert cpu_model to cpu type and set of global properties before machine_init() Eduardo Habkost
2017-09-19 20:18 ` [Qemu-devel] [PULL 07/12] pc: use generic cpu_model parsing Eduardo Habkost
2017-09-19 20:18 ` [Qemu-devel] [PULL 08/12] arm: drop intermediate cpu_model -> cpu type parsing and use cpu type directly Eduardo Habkost
2017-09-19 20:18 ` [Qemu-devel] [PULL 09/12] numa: cpu: calculate/set default node-ids after all -numa CLI options are parsed Eduardo Habkost
2017-09-19 20:18 ` [Qemu-devel] [PULL 10/12] NUMA: Replace MAX_NODES with nb_numa_nodes in for loop Eduardo Habkost
2017-09-19 20:18 ` [Qemu-devel] [PULL 11/12] hw/acpi-build: Fix SRAT memory building in case of node 0 without RAM Eduardo Habkost
2017-09-19 20:18 ` [Qemu-devel] [PULL 12/12] MAINTAINERS: Update git URLs for my trees Eduardo Habkost
2017-09-20 18:16 ` [Qemu-devel] [PULL 00/12] Machine/CPU/NUMA queue, 2017-09-19 Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.