Patchwork [RFC,11/11] s390/qemu: cpu model enablement

login
register
mail settings
Submitter Michael Mueller
Date Oct. 2, 2013, 11:33 a.m.
Message ID <1380713622-22325-12-git-send-email-mimu@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/279695/
State New
Headers show

Comments

Michael Mueller - Oct. 2, 2013, 11:33 a.m.
This patch enables all previous cpu model related patches and
allows the feature to become active. It basically implements
the host properties being fetched from the host and applied to
the predefined S390 cpu classes during initialization of the
HW platform. In a second step, the requeted cpu model determines
from which cpu class the cpus become instantiated.

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 hw/s390x/s390-virtio-ccw.c | 15 +++++++++++++++
 hw/s390x/s390-virtio.c     | 31 +++++++++++++++++++++++++++++--
 target-s390x/helper.c      | 24 ++++++++++++++++++++++--
 3 files changed, 66 insertions(+), 4 deletions(-)

Patch

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 9dd7bcc..64a1eaa 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -17,6 +17,7 @@ 
 #include "css.h"
 #include "virtio-ccw.h"
 #include "hw/s390x/config.h"
+#include "cpu-models.h"
 
 void io_subsystem_reset(void)
 {
@@ -85,6 +86,7 @@  static void ccw_init(QEMUMachineInitArgs *args)
     int ret;
     VirtualCssBus *css_bus;
     char machine_name[128];
+    struct S390HostProps prop;
 
     /* s390x ram size detection needs a 16bit multiplier + an increment. So
        guests > 64GB can be specified in 2MB steps etc. */
@@ -108,6 +110,19 @@  static void ccw_init(QEMUMachineInitArgs *args)
         set_s390_config_attr(KVM_DEV_S390_CONFIG_NAME, machine_name);
     }
 
+    if (kvm_enabled()) {
+        ret = s390_fetch_kvm_host_props(&prop);
+        if (ret) {
+            fprintf(stderr, "failed to retrieve KVM host properties\n");
+            exit(1);
+        }
+        ret = s390_setup_cpu_classes(&prop);
+        if (ret) {
+            fprintf(stderr, "failed to setup S390 cpu classes\n");
+            exit(1);
+        }
+    }
+
     /* register hypercalls */
     virtio_ccw_register_hcalls();
 
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 9237150..272a987 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -39,6 +39,8 @@ 
 #include "hw/s390x/s390-virtio.h"
 
 #include "hw/s390x/config.h"
+#include "cpu-models.h"
+#include "sysemu/cpus.h"
 
 //#define DEBUG_S390
 
@@ -180,12 +182,37 @@  void s390_init_ipl_dev(const char *kernel_filename,
 
 void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys)
 {
-    int i;
+    int i, ret;
+    S390CPUClass *cc;
+    ObjectClass *oc;
 
-    if (cpu_model == NULL) {
+    if (!cpu_model) {
         cpu_model = "host";
     }
 
+    if (is_help_option(cpu_model)) {
+        list_cpus(stdout, &fprintf, cpu_model);
+        exit(0);
+    }
+
+    if (kvm_enabled()) {
+        oc = s390_cpu_class_by_name(cpu_model);
+        if (!oc) {
+            fprintf(stderr, "Unable to find s390 CPU definition %s\n", cpu_model);
+            exit(1);
+        }
+        cc = S390_CPU_CLASS(oc);
+    }
+
+    /* request CPU configuration */
+    if (kvm_enabled()) {
+        ret = s390_request_kvm_cpu_config(cc);
+        if (ret) {
+            fprintf(stderr, "failed to request CPU configaration\n");
+            exit(1);
+        }
+    }
+
     ipi_states = g_malloc(sizeof(S390CPU *) * smp_cpus);
 
     for (i = 0; i < smp_cpus; i++) {
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 61abfd7..a3d16ff 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -19,6 +19,7 @@ 
  */
 
 #include "cpu.h"
+#include "cpu-models.h"
 #include "exec/gdbstub.h"
 #include "qemu/timer.h"
 #ifndef CONFIG_USER_ONLY
@@ -74,10 +75,29 @@  S390CPU *cpu_s390x_init(const char *cpu_model)
 {
     S390CPU *cpu;
     CPUS390XState *env;
+    ObjectClass *oc;
+    S390CPUClass *cc;
+    char model[16];
+
+    if (kvm_enabled()) {
+        oc = s390_cpu_class_by_name(cpu_model);
+        if (!oc) {
+            return NULL;
+        }
+        cc = S390_CPU_CLASS(oc);
+        snprintf(model, sizeof(model), "%04x-ga%u", cc->type, cc->ga);
+        cpu = S390_CPU(object_new(object_class_get_name(oc)));
+    } else {
+        cpu = S390_CPU(object_new(TYPE_S390_CPU));
+    }
 
-    cpu = S390_CPU(object_new(TYPE_S390_CPU));
     env = &cpu->env;
-    env->cpu_model_str = cpu_model;
+
+    if (kvm_enabled()) {
+        env->cpu_model_str = g_strdup(model);
+    } else {
+        env->cpu_model_str = cpu_model;
+    }
 
     object_property_set_bool(OBJECT(cpu), true, "realized", NULL);