Patchwork [6/8,v4,RFC,v4] s390-cpu: s390 cpu init improvements for hotplug

login
register
mail settings
Submitter Jason J. Herne
Date Oct. 31, 2013, 5:21 p.m.
Message ID <1383240094-28760-7-git-send-email-jjherne@us.ibm.com>
Download mbox | patch
Permalink /patch/287578/
State New
Headers show

Comments

Jason J. Herne - Oct. 31, 2013, 5:21 p.m.
From: "Jason J. Herne" <jjherne@us.ibm.com>

s390_new_cpu is created to encapsulate the creation of a new QOM S390CPU
object given a cpuid and a model string.

All actual cpu initialization code is moved from boot time specific functions to
s390_cpu_initfn (qom init routine) or to s390_new_cpu. This is done to allow us
to use the same basic code path for a cpu created at boot time and one created
during a hotplug operation.

Signed-off-by: Jason J. Herne <jjherne@us.ibm.com>
---
 hw/s390x/s390-virtio.c | 27 +++++++++++++++------------
 target-s390x/cpu.c     | 14 ++++++++++++--
 2 files changed, 27 insertions(+), 14 deletions(-)

Patch

diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 8fbff67..8d0e5e2 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -57,11 +57,16 @@  uint8_t *storage_keys;
 
 void s390_cpu_set_ipistate(uint16_t cpu_addr, S390CPU *state)
 {
-    ipi_states[cpu_addr] = state;
+    if (cpu_addr < max_cpus) {
+        ipi_states[cpu_addr] = state;
+    }
 }
 
 S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
 {
+    if (cpu_addr >= max_cpus) {
+        return NULL;
+    }
     return ipi_states[cpu_addr];
 }
 
@@ -181,24 +186,22 @@  void s390_init_ipl_dev(const char *kernel_filename,
 void s390_init_cpus(const char *cpu_model)
 {
     int i;
+    char *name;
 
     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_malloc0(sizeof(S390CPU *) * max_cpus);
 
-        cpu = cpu_s390x_init(cpu_model);
-        cs = CPU(cpu);
+    for (i = 0; i < max_cpus; i++) {
+        name = g_strdup_printf("cpu[%i]", i);
+        object_property_add_link(qdev_get_machine(), name, TYPE_S390_CPU,
+                                 (Object **)&ipi_states[i], NULL);
+    }
 
-        ipi_states[i] = cpu;
-        cs->halted = 1;
-        cpu->env.exception_index = EXCP_HLT;
-        cpu->env.storage_keys = storage_keys;
+    for (i = 0; i < smp_cpus; i++) {
+        cpu_s390x_init(cpu_model);
     }
 }
 
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 3c89f8a..3e7fa30 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -34,6 +34,8 @@ 
 #define CR0_RESET       0xE0UL
 #define CR14_RESET      0xC2000000UL;
 
+int next_cpu_num;
+
 /* generate CPU information for cpu -? */
 void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 {
@@ -150,6 +152,12 @@  static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
     cpu_reset(cs);
 
     scc->parent_realize(dev, errp);
+
+#if !defined(CONFIG_USER_ONLY)
+    if (dev->hotplugged) {
+        raise_irq_cpu_hotplug();
+    }
+#endif
 }
 
 static void s390_cpu_initfn(Object *obj)
@@ -158,13 +166,13 @@  static void s390_cpu_initfn(Object *obj)
     S390CPU *cpu = S390_CPU(obj);
     CPUS390XState *env = &cpu->env;
     static bool inited;
-    static int cpu_num = 0;
 #if !defined(CONFIG_USER_ONLY)
     struct tm tm;
 #endif
 
     cs->env_ptr = env;
     cpu_exec_init(env);
+    env->cpu_num = next_cpu_num++;
 #if !defined(CONFIG_USER_ONLY)
     qemu_register_reset(s390_cpu_machine_reset_cb, cpu);
     qemu_get_timedate(&tm, 0);
@@ -177,8 +185,10 @@  static void s390_cpu_initfn(Object *obj)
      * cpu counter in s390_cpu_reset to a negative number at
      * initial ipl */
     cs->halted = 1;
+    cpu->env.exception_index = EXCP_HLT;
+    env->storage_keys = storage_keys;
+    s390_cpu_set_ipistate(env->cpu_num, cpu);
 #endif
-    env->cpu_num = cpu_num++;
     env->ext_index = -1;
 
     if (tcg_enabled() && !inited) {