qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 8/8] [PATCH RFC v2] s390-qemu: cpu hotplug - Treat S


From: Jason J. Herne
Subject: [Qemu-devel] [PATCH 8/8] [PATCH RFC v2] s390-qemu: cpu hotplug - Treat S390 cpus as devices
Date: Fri, 7 Jun 2013 13:28:07 -0400

From: "Jason J. Herne" <address@hidden>

Modify cpu initialization and QOM routines associated with s390-cpu such that
all cpus on S390 are now created via the QOM device creation code path.

Signed-off-by: Jason J. Herne <address@hidden>
---
 hw/s390x/s390-virtio-ccw.c |   15 ++++++++++-----
 hw/s390x/s390-virtio.c     |   25 +++++--------------------
 hw/s390x/s390-virtio.h     |    2 +-
 include/qapi/qmp/qerror.h  |    3 +++
 qdev-monitor.c             |   17 +++++++++++++++++
 target-s390x/cpu.c         |   24 ++++++++++++++++++++++--
 6 files changed, 58 insertions(+), 28 deletions(-)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 70bd858..141adce 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -95,12 +95,8 @@ static void ccw_init(QEMUMachineInitArgs *args)
     /* allocate storage keys */
     s390_set_storage_keys_p(g_malloc0(my_ram_size / TARGET_PAGE_SIZE));
 
-    /* init CPUs */
-    s390_init_cpus(args->cpu_model);
+    s390_init_ipi_states();
 
-    if (kvm_enabled()) {
-        kvm_s390_enable_css_support(s390_cpu_addr2state(0));
-    }
     /*
      * Create virtual css and set it as default so that non mcss-e
      * enabled guests only see virtio devices.
@@ -112,11 +108,20 @@ static void ccw_init(QEMUMachineInitArgs *args)
     s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw");
 }
 
+static void ccw_post_cpu_init(void)
+{
+    if (kvm_enabled()) {
+        kvm_s390_enable_css_support(s390_cpu_addr2state(0));
+    }
+}
+
 static QEMUMachine ccw_machine = {
     .name = "s390-ccw-virtio",
     .alias = "s390-ccw",
     .desc = "VirtIO-ccw based S390 machine",
+    .cpu_device_str = "s390-cpu",
     .init = ccw_init,
+    .post_cpu_init = ccw_post_cpu_init,
     .block_default_type = IF_VIRTIO,
     .no_cdrom = 1,
     .no_floppy = 1,
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 4af2d86..069a187 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -201,31 +201,17 @@ void s390_init_ipl_dev(const char *kernel_filename,
     qdev_init_nofail(dev);
 }
 
-void s390_init_cpus(const char *cpu_model)
+void s390_init_ipi_states(void)
 {
     int i;
 
-    if (cpu_model == NULL) {
-        cpu_model = "host";
-    }
-
-    ipi_states = g_malloc(sizeof(S390CPU *) * smp_cpus);
-
-    for (i = 0; i < smp_cpus; i++) {
-        S390CPU *cpu;
-        CPUState *cs;
+    ipi_states = g_malloc(sizeof(S390CPU *) * max_cpus);
 
-        cpu = cpu_s390x_init(cpu_model);
-        cs = CPU(cpu);
-
-        ipi_states[i] = cpu;
-        cs->halted = 1;
-        cpu->env.exception_index = EXCP_HLT;
-        cpu->env.storage_keys = s390_get_storage_keys_p();
+    for (i = 0; i < max_cpus; i++) {
+        ipi_states[i] = NULL;
     }
 }
 
-
 void s390_create_virtio_net(BusState *bus, const char *name)
 {
     int i;
@@ -296,8 +282,7 @@ static void s390_init(QEMUMachineInitArgs *args)
     /* allocate storage keys */
     s390_set_storage_keys_p(g_malloc0(my_ram_size / TARGET_PAGE_SIZE));
 
-    /* init CPUs */
-    s390_init_cpus(args->cpu_model);
+    s390_init_ipi_states();
 
     /* Create VirtIO network adapters */
     s390_create_virtio_net((BusState *)s390_bus, "virtio-net-s390");
diff --git a/hw/s390x/s390-virtio.h b/hw/s390x/s390-virtio.h
index c1cb042..7b1ef9f 100644
--- a/hw/s390x/s390-virtio.h
+++ b/hw/s390x/s390-virtio.h
@@ -20,7 +20,7 @@
 typedef int (*s390_virtio_fn)(const uint64_t *args);
 void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn);
 
-void s390_init_cpus(const char *cpu_model);
+void s390_init_ipi_states(void);
 void s390_init_ipl_dev(const char *kernel_filename,
                        const char *kernel_cmdline,
                        const char *initrd_filename,
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 6c0a18d..6627dc4 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -162,6 +162,9 @@ void assert_no_error(Error *err);
 #define QERR_KVM_MISSING_CAP \
     ERROR_CLASS_K_V_M_MISSING_CAP, "Using KVM without %s, %s unavailable"
 
+#define QERR_MAX_CPUS \
+    ERROR_CLASS_GENERIC_ERROR, "The maximum number of cpus has already been 
created for this guest"
+
 #define QERR_MIGRATION_ACTIVE \
     ERROR_CLASS_GENERIC_ERROR, "There's a migration process in progress"
 
diff --git a/qdev-monitor.c b/qdev-monitor.c
index e54dbc2..a4adeb8 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -23,6 +23,9 @@
 #include "monitor/qdev.h"
 #include "qmp-commands.h"
 #include "sysemu/arch_init.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "sysemu/cpus.h"
 #include "qemu/config-file.h"
 
 /*
@@ -442,6 +445,14 @@ DeviceState *qdev_device_add(QemuOpts *opts)
         return NULL;
     }
 
+    if (driver && current_machine &&
+        strcmp(driver, current_machine->cpu_device_str) == 0) {
+        if (smp_cpus == max_cpus) {
+            qerror_report(QERR_MAX_CPUS);
+            return NULL;
+        }
+    }
+
     k = DEVICE_CLASS(obj);
 
     /* find bus */
@@ -498,6 +509,12 @@ DeviceState *qdev_device_add(QemuOpts *opts)
         qerror_report(QERR_DEVICE_INIT_FAILED, driver);
         return NULL;
     }
+
+    if (driver && current_machine &&
+        strcmp(driver, current_machine->cpu_device_str) == 0) {
+        resume_all_vcpus();
+    }
+
     qdev->opts = opts;
     return qdev;
 }
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 23fe51f..8b92c9c 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -29,6 +29,8 @@
 #include "hw/hw.h"
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/arch_init.h"
+#include "sysemu/sysemu.h"
+#include "hw/s390x/sclp.h"
 #endif
 
 #define CR0_RESET       0xE0UL
@@ -106,6 +108,9 @@ static void s390_cpu_realizefn(DeviceState *dev, Error 
**errp)
     cpu_reset(CPU(cpu));
 
     scc->parent_realize(dev, errp);
+
+    cpu_synchronize_post_init(CPU(dev));
+    raise_irq_cpu_hotplug();
 }
 
 static void s390_cpu_initfn(Object *obj)
@@ -113,8 +118,9 @@ static void s390_cpu_initfn(Object *obj)
     CPUState *cs = CPU(obj);
     S390CPU *cpu = S390_CPU(obj);
     CPUS390XState *env = &cpu->env;
+    int cpu_num = s390_cpu_get_free_state_idx();
     static bool inited;
-    static int cpu_num = 0;
+
 #if !defined(CONFIG_USER_ONLY)
     struct tm tm;
 #endif
@@ -134,13 +140,20 @@ static void s390_cpu_initfn(Object *obj)
      * initial ipl */
     cs->halted = 1;
 #endif
-    env->cpu_num = cpu_num++;
+    s390_cpu_set_state(cpu_num, cpu);
+    cs->cpu_index = cpu_num;
+    env->cpu_num = cpu_num;
     env->ext_index = -1;
+    env->cpu_model_str = "host";
+    cpu->env.exception_index = EXCP_HLT;
+    cpu->env.storage_keys = s390_get_storage_keys_p();
 
     if (tcg_enabled() && !inited) {
         inited = true;
         s390x_translate_init();
     }
+
+    smp_cpus += 1;
 }
 
 static void s390_cpu_finalize(Object *obj)
@@ -152,6 +165,12 @@ static void s390_cpu_finalize(Object *obj)
 #endif
 }
 
+static int s390_cpu_unplug(DeviceState *dev)
+{
+    fprintf(stderr, "Removal of CPU devices is not supported.\n");
+    return -1;
+}
+
 static const VMStateDescription vmstate_s390_cpu = {
     .name = "cpu",
     .unmigratable = 1,
@@ -165,6 +184,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
 
     scc->parent_realize = dc->realize;
     dc->realize = s390_cpu_realizefn;
+    dc->unplug = s390_cpu_unplug;
 
     scc->parent_reset = cc->reset;
     cc->reset = s390_cpu_reset;
-- 
1.7.10.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]