summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorThomas Huth <thuth@redhat.com>2025-01-20 08:07:05 +0100
committerThomas Huth <thuth@redhat.com>2025-01-22 08:28:49 +0100
commit807830e809bc684dc3344e78dd32f0cb6e5c6c37 (patch)
tree4b9452f32ceecbfab608eb5056bccf501117206a
parent145f12ea885c8fcfbe2d0ac5230630f071b5a9fb (diff)
downloadfocaccia-qemu-807830e809bc684dc3344e78dd32f0cb6e5c6c37.tar.gz
focaccia-qemu-807830e809bc684dc3344e78dd32f0cb6e5c6c37.zip
hw/s390x: Fix crash that occurs when inspecting older versioned machines types
qemu-system-s390x currently crashes when trying to inspect older
machines types, for example:

 $ echo '{ "execute": "qmp_capabilities" }
         { "execute": "qom-list-properties","arguments":
           { "typename": "s390-ccw-virtio-3.0-machine"}}' \
   | ./qemu-system-s390x -qmp stdio -no-shutdown
 {"QMP": {"version": {"qemu": {"micro": 50, "minor": 2, "major": 9},
  "package": "v9.2.0-1071-g81e97df3e7"}, "capabilities": ["oob"]}}
 {"return": {}}
 **
 Bail out! ERROR:../target/s390x/cpu_models.c:832:s390_set_qemu_cpu_model:
  assertion failed: (QTAILQ_EMPTY_RCU(&cpus_queue))
 Aborted (core dumped)

The problem is that the versioned s390-ccw-virtio machine types
use instance_init() to set global state that should be initialized
before the CPUs get instantiated. But instance_init() is not called
only for the machine that is finally used, it is also called for
temporary instances of objects that are e.g. just created for
introspection. That means that those instance_init() functions can
also be called while a machine (and its CPUs) is already created,
which triggers the assertion in cpu_models.c.

So we must not use instance_init() for setting global state, but
use the machine->init() function instead, which is really only called
once when the machine comes to life.

Fixes: 3b00f702c2 ("s390x/cpumodel: add zpci, aen and ais facilities")
Message-ID: <20250120085059.239345-1-thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
-rw-r--r--hw/s390x/s390-virtio-ccw.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 38aeba14ee..3af613d4e9 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -782,7 +782,6 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data)
 
     s390mc->hpage_1m_allowed = true;
     s390mc->max_threads = 1;
-    mc->init = ccw_init;
     mc->reset = s390_machine_reset;
     mc->block_default_type = IF_VIRTIO;
     mc->no_cdrom = 1;
@@ -852,6 +851,12 @@ static const TypeInfo ccw_machine_info = {
 };
 
 #define DEFINE_CCW_MACHINE_IMPL(latest, ...)                                  \
+    static void MACHINE_VER_SYM(mach_init, ccw, __VA_ARGS__)(MachineState *mach) \
+    {                                                                         \
+        current_mc = S390_CCW_MACHINE_CLASS(MACHINE_GET_CLASS(mach));         \
+        MACHINE_VER_SYM(instance_options, ccw, __VA_ARGS__)(mach);            \
+        ccw_init(mach);                                                       \
+    }                                                                         \
     static void MACHINE_VER_SYM(class_init, ccw, __VA_ARGS__)(                \
         ObjectClass *oc,                                                      \
         void *data)                                                           \
@@ -859,24 +864,18 @@ static const TypeInfo ccw_machine_info = {
         MachineClass *mc = MACHINE_CLASS(oc);                                 \
         MACHINE_VER_SYM(class_options, ccw, __VA_ARGS__)(mc);                 \
         mc->desc = "Virtual s390x machine (version " MACHINE_VER_STR(__VA_ARGS__) ")"; \
+        mc->init = MACHINE_VER_SYM(mach_init, ccw, __VA_ARGS__);              \
         MACHINE_VER_DEPRECATION(__VA_ARGS__);                                 \
         if (latest) {                                                         \
             mc->alias = "s390-ccw-virtio";                                    \
             mc->is_default = true;                                            \
         }                                                                     \
     }                                                                         \
-    static void MACHINE_VER_SYM(instance_init, ccw, __VA_ARGS__)(Object *obj) \
-    {                                                                         \
-        MachineState *machine = MACHINE(obj);                                 \
-        current_mc = S390_CCW_MACHINE_CLASS(MACHINE_GET_CLASS(machine));      \
-        MACHINE_VER_SYM(instance_options, ccw, __VA_ARGS__)(machine);         \
-    }                                                                         \
     static const TypeInfo MACHINE_VER_SYM(info, ccw, __VA_ARGS__) =           \
     {                                                                         \
         .name = MACHINE_VER_TYPE_NAME("s390-ccw-virtio", __VA_ARGS__),        \
         .parent = TYPE_S390_CCW_MACHINE,                                      \
         .class_init = MACHINE_VER_SYM(class_init, ccw, __VA_ARGS__),          \
-        .instance_init = MACHINE_VER_SYM(instance_init, ccw, __VA_ARGS__),    \
     };                                                                        \
     static void MACHINE_VER_SYM(register, ccw, __VA_ARGS__)(void)             \
     {                                                                         \