All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
@ 2016-06-21 13:02 David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 01/28] s390x/cpumodel: "host" and "qemu" as CPU subclasses David Hildenbrand
                   ` (29 more replies)
  0 siblings, 30 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

This is our second attempt to implement CPU models for s390x. We realized
that we also want to have features exposed via the CPU model. While doing
that we realized that we want to have a better interface for libvirt.

Unfortunately, CPU models on s390x are special and we have to take care of:
- A CPU like z13 looks differently in various environments (under different
  LPAR versions, under different z/VM versions, under different KVM
  versions, export regulation) - we have _a lot_ of feature variability.
- We still have certain features that are not published but might be
  implemented/introduced in the future. As they are a theoretical part
  of a CPU already, we have to find a way to model these future changes.
- We still have certain features that are already published, but not
  implemented. Implementation might be added in the future in KVM.
- We heavily rely on KVM to tell us which features it can actually
  virtualize - user space queries like "STFL(e)" give no guarantees.
- Certain "subfeatures" were introduced in one run. In practice, they are
  always around, but in theory, subfeatures could be dropped in the future.
- Just because two CPU models have the same features doesn't mean they
  are equal - some internal numbers might be different. E.g. we won't allow
  running a z13 under a zBC12 just by turning off features.
- We cannot blindly enable all possible features for a CPU generation,
  the IBC "Instruction Blocking Control" in KVM will try to block
  instructions introduced with certain features. So a CPU generation always
  has some maximum feature set that is guaranteed to work.

It all boils down to a specific released CPU to have.
a) A fixed feature set that we expect it to be have on every hypervisor.
b) A variable part that depends on the hypervisor and that could be
   extended in the future (adding not yet implemented features) that we
   always want to enable later on.
c) A variable part that we want to enable only if requested - nested
   virtualization ("vsie") and assists are one example.

But, the fixed feature set is not really what we want to use as a default.
It is just like a really minimum, stable base.

So we have
a) A "stable" CPU model for each released CPU that will never change and
   maps to the minimum feature set we expect to be around on all
   hypervisors. e.g. "z13-base" or "z10EC.2-base". These are migration
   safe.
b) A "default" CPU model for each released CPU, that can change between
   QEMU versions and that will always include the features we expect to
   be around in our currently supported environments and will contain only
   features we expect to be stable. E.g. nested virtualization will not be
   contained in these models. These models are not migration safe, e.g
   "z13" or "z10EC.2". The feature set can differ between QEMU versions.
c) An internal "maximum" CPU model for each generation that tells us which
   features were supported as a maximum back when the hardware was
   released. This will not be exposed

To not have to replicate all CPU model changes ("new default fetaures") in
libvirt, to not duplicate the logic about compatibility and the like,
our approach tries to keep all the QEMU logic in libvirt and provide
standardized interfaces for libvirt to e.g. baseline, compare. This
allows libvirt to not have to care about any model names or feature names,
it can just pass the data from interface to interface and report it to
the user.

Also, libvirt might want to know what the "host" model looks like and
convert a CPU model to a migration safe variant. For this reason, a QMP
command is added that can create a migration safe variant of a variable
CPU model, indicating only the delta changes done to a stable model.

So we have:
a) "query-cpu-model-expansion" - tell us what the "host" or a migration
   unsafe model looks like. Either falling back to a stable model or
   completely exposing all properties. We are interested in stable models.
b) "query-cpu-model-comparison" - tell us how two CPU models compare,
    indicating which properties were responsible for the decision.
c) "query-cpu-model-baseline" - create a new model out of two models,
    taking a requested level of stability into account.

As we are aware that e.g. x86 has their own idea of a CPU model and their
existing implementation in place, but are also looking into to ways to e.g.
expand the "host" CPU model to a detailed representation, we designed the
"expansion" interface to also allow that.

Comments are very welcome, but please always keep the restrictions and
specialties in mind when suggesting some major design changes.

The header update will be replaced by a kvm-next header update as soon as
the VSIE patches are upstream. The major KVM interface changes are already
part of kvm-next.

The current state is available on git://github.com/cohuck/qemu on branch
"cpumodel-s390x".

David Hildenbrand (26):
  s390x/cpumodel: "host" and "qemu" as CPU subclasses
  s390x/cpumodel: expose CPU class properties
  s390x/cpumodel: generate CPU feature group lists
  s390x/cpumodel: introduce CPU feature group definitions
  s390x/cpumodel: register defined CPU models as subclasses
  s390x/cpumodel: store the CPU model in the CPU instance
  s390x/cpumodel: expose features and feature groups as properties
  s390x/cpumodel: let the CPU model handle feature checks
  s390x/cpumodel: check and apply the CPU model
  s390x/sclp: factor out preparation of cpu entries
  s390x/sclp: introduce sclp feature blocks
  s390x/sclp: indicate sclp features
  s390x/sclp: propagate the ibc val(lowest and unblocked ibc)
  s390x/sclp: propagate the mha via sclp
  s390x/sclp: propagate hmfai
  update linux headers (CPU model)
  s390x/kvm: allow runtime-instrumentation for "none" machine
  s390x/kvm: implement CPU model support
  s390x/kvm: disable host model for existing compat machines
  s390x/kvm: let the CPU model control CMM(A)
  qmp: add QMP interface "query-cpu-model-expansion"
  qmp: add QMP interface "query-cpu-model-comparison"
  qmp: add QMP interface "query-cpu-model-baseline"
  s390x/cpumodel: implement QMP interface "query-cpu-model-expansion"
  s390x/cpumodel: implement QMP interface "query-cpu-model-comparison"
  s390x/cpumodel: implement QMP interface "query-cpu-model-baseline"

Michael Mueller (2):
  s390x/cpumodel: introduce CPU features
  s390x/cpumodel: generate CPU feature lists for CPU models

 Makefile.target                         |    2 +-
 hw/s390x/s390-virtio-ccw.c              |    5 +
 hw/s390x/s390-virtio.c                  |    6 +-
 hw/s390x/sclp.c                         |   35 +-
 include/hw/s390x/sclp.h                 |   17 +-
 include/sysemu/arch_init.h              |   10 +
 linux-headers/asm-s390/kvm.h            |   40 ++
 qapi-schema.json                        |  184 ++++++
 qmp-commands.hx                         |   18 +
 qmp.c                                   |   22 +
 rules.mak                               |    1 +
 stubs/Makefile.objs                     |    3 +
 stubs/arch-query-cpu-model-baseline.c   |   13 +
 stubs/arch-query-cpu-model-comparison.c |   12 +
 stubs/arch-query-cpu-model-expansion.c  |   12 +
 target-s390x/Makefile.objs              |   22 +-
 target-s390x/cpu-qom.h                  |    5 +
 target-s390x/cpu.c                      |   35 +-
 target-s390x/cpu.h                      |    5 +
 target-s390x/cpu_features.c             |  376 +++++++++++
 target-s390x/cpu_features.h             |  302 +++++++++
 target-s390x/cpu_models.c               | 1055 +++++++++++++++++++++++++++++++
 target-s390x/cpu_models.h               |  113 ++++
 target-s390x/gen-features.c             |  587 +++++++++++++++++
 target-s390x/helper.c                   |   29 +-
 target-s390x/kvm.c                      |  346 +++++++++-
 target-s390x/machine.c                  |   14 +-
 27 files changed, 3203 insertions(+), 66 deletions(-)
 create mode 100644 stubs/arch-query-cpu-model-baseline.c
 create mode 100644 stubs/arch-query-cpu-model-comparison.c
 create mode 100644 stubs/arch-query-cpu-model-expansion.c
 create mode 100644 target-s390x/cpu_features.c
 create mode 100644 target-s390x/cpu_features.h
 create mode 100644 target-s390x/cpu_models.c
 create mode 100644 target-s390x/cpu_models.h
 create mode 100644 target-s390x/gen-features.c

-- 
2.6.6

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

* [Qemu-devel] [RFC 01/28] s390x/cpumodel: "host" and "qemu" as CPU subclasses
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 02/28] s390x/cpumodel: expose CPU class properties David Hildenbrand
                   ` (28 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

This patch introduces two CPU models, "host" and "qemu".
"qemu" is used as default when running under TCG. "host" is used
as default when running under KVM. "host" cannot be used without KVM.
Bot models are not migration safe. They inherit from the base s390x CPU,
which is turned into an abstract class.

This patch also changes CPU creation to take care of the passed CPU string
and reuses common code parse_features() function for that purpose. Unknown
CPU definitions are now reported. The "-cpu ?" and "query-cpu-definition"
commands are changed to list all CPU subclasses automatically.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 hw/s390x/s390-virtio.c     |   6 +-
 target-s390x/Makefile.objs |   2 +-
 target-s390x/cpu-qom.h     |   3 +
 target-s390x/cpu.c         |  33 +++------
 target-s390x/cpu.h         |   2 +
 target-s390x/cpu_models.c  | 164 +++++++++++++++++++++++++++++++++++++++++++++
 target-s390x/helper.c      |  29 +++++++-
 7 files changed, 211 insertions(+), 28 deletions(-)
 create mode 100644 target-s390x/cpu_models.c

diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 544c616..0a96347 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -101,7 +101,11 @@ void s390_init_cpus(MachineState *machine)
     gchar *name;
 
     if (machine->cpu_model == NULL) {
-        machine->cpu_model = "host";
+        if (kvm_enabled()) {
+            machine->cpu_model = "host";
+        } else {
+            machine->cpu_model = "qemu";
+        }
     }
 
     cpu_states = g_new0(S390CPU *, max_cpus);
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index dd62cbd..34bd693 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,5 +1,5 @@
 obj-y += translate.o helper.o cpu.o interrupt.o
 obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
-obj-y += gdbstub.o
+obj-y += gdbstub.o cpu_models.o
 obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o
 obj-$(CONFIG_KVM) += kvm.o
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index 66b5d18..ae0be73 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -45,6 +45,9 @@ typedef struct S390CPUClass {
     /*< private >*/
     CPUClass parent_class;
     /*< public >*/
+    bool kvm_required;
+    bool migration_safe;
+    const char *desc;
 
     int64_t next_cpu_id;
 
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index e43e2d6..44e53ec 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -44,30 +44,6 @@
 #define CR0_RESET       0xE0UL
 #define CR14_RESET      0xC2000000UL;
 
-/* generate CPU information for cpu -? */
-void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf)
-{
-#ifdef CONFIG_KVM
-    (*cpu_fprintf)(f, "s390 %16s\n", "host");
-#endif
-}
-
-#ifndef CONFIG_USER_ONLY
-CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
-{
-    CpuDefinitionInfoList *entry;
-    CpuDefinitionInfo *info;
-
-    info = g_malloc0(sizeof(*info));
-    info->name = g_strdup("host");
-
-    entry = g_malloc0(sizeof(*entry));
-    entry->value = info;
-
-    return entry;
-}
-#endif
-
 static void s390_cpu_set_pc(CPUState *cs, vaddr value)
 {
     S390CPU *cpu = S390_CPU(cs);
@@ -206,6 +182,12 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
     CPUS390XState *env = &cpu->env;
     Error *err = NULL;
 
+    /* the model has to be realized before qemu_init_vcpu() due to kvm */
+    s390_realize_cpu_model(cs, &err);
+    if (err) {
+        goto out;
+    }
+
 #if !defined(CONFIG_USER_ONLY)
     if (cpu->id >= max_cpus) {
         error_setg(&err, "Unable to add CPU: %" PRIi64
@@ -435,6 +417,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     scc->cpu_reset = s390_cpu_reset;
     scc->initial_cpu_reset = s390_cpu_initial_reset;
     cc->reset = s390_cpu_full_reset;
+    cc->class_by_name = s390_cpu_class_by_name,
     cc->has_work = s390_cpu_has_work;
     cc->do_interrupt = s390_cpu_do_interrupt;
     cc->dump_state = s390_cpu_dump_state;
@@ -470,7 +453,7 @@ static const TypeInfo s390_cpu_type_info = {
     .instance_size = sizeof(S390CPU),
     .instance_init = s390_cpu_initfn,
     .instance_finalize = s390_cpu_finalize,
-    .abstract = false,
+    .abstract = true,
     .class_size = sizeof(S390CPUClass),
     .class_init = s390_cpu_class_init,
 };
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index bd6b2e5..f1cb9a2 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -632,6 +632,8 @@ extern void subsystem_reset(void);
 
 void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 #define cpu_list s390_cpu_list
+void s390_realize_cpu_model(CPUState *cs, Error **errp);
+ObjectClass *s390_cpu_class_by_name(const char *name);
 
 #define EXCP_EXT 1 /* external interrupt */
 #define EXCP_SVC 2 /* supervisor call (syscall) */
diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
new file mode 100644
index 0000000..08ed640
--- /dev/null
+++ b/target-s390x/cpu_models.c
@@ -0,0 +1,164 @@
+/*
+ * CPU models for s390x
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "qapi/error.h"
+#ifndef CONFIG_USER_ONLY
+#include "sysemu/arch_init.h"
+#endif
+
+struct S390PrintCpuListInfo {
+    FILE *f;
+    fprintf_function print;
+};
+
+static void print_cpu_model_list(ObjectClass *klass, void *opaque)
+{
+    struct S390PrintCpuListInfo *info = opaque;
+    S390CPUClass *scc = S390_CPU_CLASS(klass);
+    char *name = g_strdup(object_class_get_name(klass));
+
+    /* strip off the -s390-cpu */
+    g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
+    (*info->print)(info->f, "s390 %-15s %-35s (%s)\n", name, scc->desc,
+                 scc->migration_safe ? "migration safe" : "not migration safe");
+    g_free(name);
+}
+
+void s390_cpu_list(FILE *f, fprintf_function print)
+{
+    struct S390PrintCpuListInfo info = {
+        f = f,
+        print = print,
+    };
+
+    object_class_foreach(print_cpu_model_list, TYPE_S390_CPU, false, &info);
+}
+
+#ifndef CONFIG_USER_ONLY
+static void create_cpu_model_list(ObjectClass *klass, void *opaque)
+{
+    CpuDefinitionInfoList **cpu_list = opaque;
+    CpuDefinitionInfoList *entry;
+    CpuDefinitionInfo *info;
+    char *name = g_strdup(object_class_get_name(klass));
+
+    /* strip off the -s390-cpu */
+    g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
+    info = g_malloc0(sizeof(*info));
+    info->name = name;
+
+    entry = g_malloc0(sizeof(*entry));
+    entry->value = info;
+    entry->next = *cpu_list;
+    *cpu_list = entry;
+}
+
+CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
+{
+    CpuDefinitionInfoList *list = NULL;
+
+    object_class_foreach(create_cpu_model_list, TYPE_S390_CPU, false, &list);
+
+    return list;
+}
+#endif
+
+void s390_realize_cpu_model(CPUState *cs, Error **errp)
+{
+    S390CPUClass *xcc = S390_CPU_GET_CLASS(cs);
+
+    if (xcc->kvm_required && !kvm_enabled()) {
+        error_setg(errp, "CPU definition requires KVM");
+        return;
+    }
+}
+
+#ifdef CONFIG_KVM
+static void s390_host_cpu_model_initfn(Object *obj)
+{
+}
+#endif
+
+static void s390_qemu_cpu_model_initfn(Object *obj)
+{
+}
+
+static void s390_cpu_model_finalize(Object *obj)
+{
+}
+
+#ifdef CONFIG_KVM
+static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data)
+{
+    S390CPUClass *xcc = S390_CPU_CLASS(oc);
+
+    xcc->kvm_required = true;
+    xcc->desc = "KVM only: All recognized features";
+}
+#endif
+
+static void s390_qemu_cpu_model_class_init(ObjectClass *oc, void *data)
+{
+    S390CPUClass *xcc = S390_CPU_CLASS(oc);
+
+    xcc->desc = g_strdup_printf("QEMU Virtual CPU version %s",
+                                qemu_hw_version());
+}
+
+#define S390_CPU_TYPE_SUFFIX "-" TYPE_S390_CPU
+#define S390_CPU_TYPE_NAME(name) (name S390_CPU_TYPE_SUFFIX)
+
+/* Generate type name for a cpu model. Caller has to free the string. */
+static char *s390_cpu_type_name(const char *model_name)
+{
+    return g_strdup_printf(S390_CPU_TYPE_NAME("%s"), model_name);
+}
+
+ObjectClass *s390_cpu_class_by_name(const char *name)
+{
+    char *typename = s390_cpu_type_name(name);
+    ObjectClass *oc;
+
+    oc = object_class_by_name(typename);
+    g_free(typename);
+    return oc;
+}
+
+static const TypeInfo qemu_s390_cpu_type_info = {
+    .name = S390_CPU_TYPE_NAME("qemu"),
+    .parent = TYPE_S390_CPU,
+    .instance_init = s390_qemu_cpu_model_initfn,
+    .instance_finalize = s390_cpu_model_finalize,
+    .class_init = s390_qemu_cpu_model_class_init,
+};
+
+#ifdef CONFIG_KVM
+static const TypeInfo host_s390_cpu_type_info = {
+    .name = S390_CPU_TYPE_NAME("host"),
+    .parent = TYPE_S390_CPU,
+    .instance_init = s390_host_cpu_model_initfn,
+    .instance_finalize = s390_cpu_model_finalize,
+    .class_init = s390_host_cpu_model_class_init,
+};
+#endif
+
+static void register_types(void)
+{
+    type_register_static(&qemu_s390_cpu_type_info);
+#ifdef CONFIG_KVM
+    type_register_static(&host_s390_cpu_type_info);
+#endif
+}
+
+type_init(register_types)
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 54a5177..2eaba9a 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -70,7 +70,34 @@ void s390x_cpu_timer(void *opaque)
 
 S390CPU *cpu_s390x_create(const char *cpu_model, Error **errp)
 {
-    return S390_CPU(object_new(TYPE_S390_CPU));
+    char *name, *features;
+    CPUState *cpu;
+    ObjectClass *oc;
+    CPUClass *cc;
+
+    name = g_strdup(cpu_model);
+    features = strchr(name, ',');
+    if (features) {
+        features[0] = 0;
+        features++;
+    }
+
+    oc = cpu_class_by_name(TYPE_S390_CPU, name);
+    if (!oc) {
+        error_setg(errp, "Unknown CPU definition \'%s\'", name);
+        g_free(name);
+        return NULL;
+    }
+    cpu = CPU(object_new(object_class_get_name(oc)));
+    cc = CPU_GET_CLASS(cpu);
+
+    cc->parse_features(cpu, features, errp);
+    if (*errp) {
+        object_unref(OBJECT(cpu));
+        g_free(name);
+        return NULL;
+    }
+    return S390_CPU(cpu);
 }
 
 S390CPU *s390x_new_cpu(const char *cpu_model, int64_t id, Error **errp)
-- 
2.6.6

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

* [Qemu-devel] [RFC 02/28] s390x/cpumodel: expose CPU class properties
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 01/28] s390x/cpumodel: "host" and "qemu" as CPU subclasses David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 03/28] s390x/cpumodel: introduce CPU features David Hildenbrand
                   ` (27 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Let's expose the description and migration safety, as class properties,
this can be helpful in the future.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/cpu.c        |  1 +
 target-s390x/cpu.h        |  1 +
 target-s390x/cpu_models.c | 18 ++++++++++++++++++
 3 files changed, 20 insertions(+)

diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 44e53ec..d7d0b62 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -445,6 +445,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
      * object_unref().
      */
     dc->cannot_destroy_with_object_finalize_yet = true;
+    s390_cpu_model_class_register_props(oc);
 }
 
 static const TypeInfo s390_cpu_type_info = {
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index f1cb9a2..832da89 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -632,6 +632,7 @@ extern void subsystem_reset(void);
 
 void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 #define cpu_list s390_cpu_list
+void s390_cpu_model_class_register_props(ObjectClass *oc);
 void s390_realize_cpu_model(CPUState *cs, Error **errp);
 ObjectClass *s390_cpu_class_by_name(const char *name);
 
diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index 08ed640..18638a9 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -98,6 +98,24 @@ static void s390_cpu_model_finalize(Object *obj)
 {
 }
 
+static bool get_migratable(Object *obj, Error **errp)
+{
+    return S390_CPU_GET_CLASS(obj)->migration_safe;
+}
+
+static char *get_description(Object *obj, Error **errp)
+{
+    return g_strdup(S390_CPU_GET_CLASS(obj)->desc);
+}
+
+void s390_cpu_model_class_register_props(ObjectClass *oc)
+{
+    object_class_property_add_bool(oc, "migratable", get_migratable, NULL,
+                                   NULL);
+    object_class_property_add_str(oc, "description", get_description, NULL,
+                                  NULL);
+}
+
 #ifdef CONFIG_KVM
 static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data)
 {
-- 
2.6.6

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

* [Qemu-devel] [RFC 03/28] s390x/cpumodel: introduce CPU features
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 01/28] s390x/cpumodel: "host" and "qemu" as CPU subclasses David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 02/28] s390x/cpumodel: expose CPU class properties David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 04/28] s390x/cpumodel: generate CPU feature lists for CPU models David Hildenbrand
                   ` (26 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

From: Michael Mueller <mimu@linux.vnet.ibm.com>

The patch introduces s390x CPU features (most of them refered to as
facilities) along with their discription and some functions that will be
helpful when working with the features later on.

Please note that we don't introduce all known CPU features, only the
ones currently supported by KVM + QEMU. We don't want to enable later
on blindly any facilities, for which we don't know yet if we need QEMU
support to properly support them (e.g. migrate additional state when
active). We can update QEMU later on.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
[reworked to include non-stfle features, added definitions]
---
 target-s390x/Makefile.objs  |   2 +-
 target-s390x/cpu_features.c | 334 ++++++++++++++++++++++++++++++++++++++++++++
 target-s390x/cpu_features.h | 279 ++++++++++++++++++++++++++++++++++++
 3 files changed, 614 insertions(+), 1 deletion(-)
 create mode 100644 target-s390x/cpu_features.c
 create mode 100644 target-s390x/cpu_features.h

diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index 34bd693..4266c87 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,5 +1,5 @@
 obj-y += translate.o helper.o cpu.o interrupt.o
 obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
-obj-y += gdbstub.o cpu_models.o
+obj-y += gdbstub.o cpu_models.o cpu_features.o
 obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o
 obj-$(CONFIG_KVM) += kvm.o
diff --git a/target-s390x/cpu_features.c b/target-s390x/cpu_features.c
new file mode 100644
index 0000000..c78a189
--- /dev/null
+++ b/target-s390x/cpu_features.c
@@ -0,0 +1,334 @@
+/*
+ * CPU features/facilities for s390x
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu_features.h"
+
+#define FEAT_INIT(_name, _type, _bit, _desc) \
+    {                                                \
+        .name = _name,                               \
+        .type = _type,                               \
+        .bit = _bit,                                 \
+        .desc = _desc,                               \
+    }
+
+/* indexed by feature number for easy lookup */
+static const S390FeatDef s390_features[] = {
+    FEAT_INIT("n3", S390_FEAT_TYPE_STFL, 0, "Instructions marked as n3"),
+    FEAT_INIT("z", S390_FEAT_TYPE_STFL, 1, "z/Architecture architectural mode"),
+    FEAT_INIT("dateh1", S390_FEAT_TYPE_STFL, 3, "DAT-enhancement facility 1"),
+    FEAT_INIT("idtes", S390_FEAT_TYPE_STFL, 4, "IDTE selective TLB segment-table clearing"),
+    FEAT_INIT("idter", S390_FEAT_TYPE_STFL, 5, "IDTE selective TLB region-table clearing"),
+    FEAT_INIT("asnlxr", S390_FEAT_TYPE_STFL, 6, "ASN-and-LX reuse facility"),
+    FEAT_INIT("stfle", S390_FEAT_TYPE_STFL, 7, "Store-facility-list-extended facility"),
+    FEAT_INIT("edat1", S390_FEAT_TYPE_STFL, 8, "Enhanced-DAT facility 1"),
+    FEAT_INIT("srs", S390_FEAT_TYPE_STFL, 9, "Sense-running-status facility"),
+    FEAT_INIT("csske", S390_FEAT_TYPE_STFL, 10, "Conditional-SSKE facility"),
+    FEAT_INIT("ctop", S390_FEAT_TYPE_STFL, 11, "Configuration-topology facility"),
+    FEAT_INIT("ipter", S390_FEAT_TYPE_STFL, 13, "IPTE-range facility"),
+    FEAT_INIT("nonqks", S390_FEAT_TYPE_STFL, 14, "Nonquiescing key-setting facility"),
+    FEAT_INIT("etf2", S390_FEAT_TYPE_STFL, 16, "Extended-translation facility 2"),
+    FEAT_INIT("msa-base", S390_FEAT_TYPE_STFL, 17, "Message-security-assist facility (excluding subfunctions)"),
+    FEAT_INIT("ldisp", S390_FEAT_TYPE_STFL, 18, "Long-displacement facility"),
+    FEAT_INIT("ldisphp", S390_FEAT_TYPE_STFL, 19, "Long-displacement facility has high performance"),
+    FEAT_INIT("hfpm", S390_FEAT_TYPE_STFL, 20, "HFP-multiply-add/subtract facility"),
+    FEAT_INIT("eimm", S390_FEAT_TYPE_STFL, 21, "Extended-immediate facility"),
+    FEAT_INIT("etf3", S390_FEAT_TYPE_STFL, 22, "Extended-translation facility 3"),
+    FEAT_INIT("hfpue", S390_FEAT_TYPE_STFL, 23, "HFP-unnormalized-extension facility"),
+    FEAT_INIT("etf2eh", S390_FEAT_TYPE_STFL, 24, "ETF2-enhancement facility"),
+    FEAT_INIT("stckf", S390_FEAT_TYPE_STFL, 25, "Store-clock-fast facility"),
+    FEAT_INIT("parseh", S390_FEAT_TYPE_STFL, 26, "Parsing-enhancement facility"),
+    FEAT_INIT("mvcos", S390_FEAT_TYPE_STFL, 27, "Move-with-optional-specification facility"),
+    FEAT_INIT("tods-base", S390_FEAT_TYPE_STFL, 28, "TOD-clock-steering facility (excluding subfunctions)"),
+    FEAT_INIT("etf3eh", S390_FEAT_TYPE_STFL, 30, "ETF3-enhancement facility"),
+    FEAT_INIT("ecput", S390_FEAT_TYPE_STFL, 31, "Extract-CPU-time facility"),
+    FEAT_INIT("csst", S390_FEAT_TYPE_STFL, 32, "Compare-and-swap-and-store facility"),
+    FEAT_INIT("csst2", S390_FEAT_TYPE_STFL, 33, "Compare-and-swap-and-store facility 2"),
+    FEAT_INIT("ginste", S390_FEAT_TYPE_STFL, 34, "General-instructions-extension facility"),
+    FEAT_INIT("exece", S390_FEAT_TYPE_STFL, 35, "Execute-extensions facility"),
+    FEAT_INIT("emon", S390_FEAT_TYPE_STFL, 36, "Enhanced-monitor facility"),
+    FEAT_INIT("fpe", S390_FEAT_TYPE_STFL, 37, "Floating-point extension facility"),
+    FEAT_INIT("spropg", S390_FEAT_TYPE_STFL, 40, "Set-program-parameters facility"),
+    FEAT_INIT("fpseh", S390_FEAT_TYPE_STFL, 41, "Floating-point-support-enhancement facilities"),
+    FEAT_INIT("dfp", S390_FEAT_TYPE_STFL, 42, "DFP (decimal-floating-point) facility"),
+    FEAT_INIT("dfphp", S390_FEAT_TYPE_STFL, 43, "DFP (decimal-floating-point) facility has high performance"),
+    FEAT_INIT("pfpo", S390_FEAT_TYPE_STFL, 44, "PFPO instruction"),
+    FEAT_INIT("gen11e", S390_FEAT_TYPE_STFL, 45, "Various facilities introduced with z196"),
+    FEAT_INIT("cmpsceh", S390_FEAT_TYPE_STFL, 47, "CMPSC-enhancement facility"),
+    FEAT_INIT("dfpzc", S390_FEAT_TYPE_STFL, 48, "Decimal-floating-point zoned-conversion facility"),
+    FEAT_INIT("gen12e", S390_FEAT_TYPE_STFL, 49, "Various facilites introduced with zEC12"),
+    FEAT_INIT("ctx", S390_FEAT_TYPE_STFL, 50, "Constrained transactional-execution facility"),
+    FEAT_INIT("ltlbc", S390_FEAT_TYPE_STFL, 51, "Local-TLB-clearing facility"),
+    FEAT_INIT("iacc2", S390_FEAT_TYPE_STFL, 52, "Interlocked-access facility 2"),
+    FEAT_INIT("gen13e", S390_FEAT_TYPE_STFL, 53, "Various facilities introduced with z13"),
+    FEAT_INIT("msa5-base", S390_FEAT_TYPE_STFL, 57, "Message-security-assist-extension-5 facility (excluding subfunctions)"),
+    FEAT_INIT("ri", S390_FEAT_TYPE_STFL, 64, "CPU runtime-instrumentation facility"),
+    FEAT_INIT("tx", S390_FEAT_TYPE_STFL, 73, "Transactional-execution facility"),
+    FEAT_INIT("sthyi", S390_FEAT_TYPE_STFL, 74, "Store-hypervisor-information facility"),
+    FEAT_INIT("aefsi", S390_FEAT_TYPE_STFL, 75, "Access-exception-fetch/store-indication facility"),
+    FEAT_INIT("msa3-base", S390_FEAT_TYPE_STFL, 76, "Message-security-assist-extension-3 facility (no subfunctions)"),
+    FEAT_INIT("msa4-base", S390_FEAT_TYPE_STFL, 77, "Message-security-assist-extension-4 facility"),
+    FEAT_INIT("edat2", S390_FEAT_TYPE_STFL, 78, "Enhanced-DAT facility 2"),
+    FEAT_INIT("dfppc", S390_FEAT_TYPE_STFL, 80, "Decimal-floating-point packed-conversion facility"),
+    FEAT_INIT("vx", S390_FEAT_TYPE_STFL, 129, "Vector facility"),
+    FEAT_INIT("scputm", S390_FEAT_TYPE_STFL, 142, "Store-CPU-counter-multiple facility"),
+
+    FEAT_INIT("gsls", S390_FEAT_TYPE_SCLP_CONF_CHAR, 40, "SIE: Guest-storage-limit-suppression facility"),
+    FEAT_INIT("esop", S390_FEAT_TYPE_SCLP_CONF_CHAR, 46, "Enhanced-suppression-on-protection facility"),
+
+    FEAT_INIT("64bscao", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 0, "SIE: 64-bit-SCAO facility"),
+    FEAT_INIT("cmma", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 1, "SIE: Collaborative-memory-management assist"),
+    FEAT_INIT("pfmfi", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF interpretation facility"),
+    FEAT_INIT("ibs", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 10, "SIE: Interlock-and-broadcast-suppression facility"),
+
+    FEAT_INIT("sief2", S390_FEAT_TYPE_SCLP_CPU, 4, "SIE: interception format 2 (Virtual SIE)"),
+    FEAT_INIT("skey", S390_FEAT_TYPE_SCLP_CPU, 5, "SIE: Storage-key facility"),
+    FEAT_INIT("gpereh", S390_FEAT_TYPE_SCLP_CPU, 10, "SIE: Guest-PER enhancement facility"),
+    FEAT_INIT("siif", S390_FEAT_TYPE_SCLP_CPU, 11, "SIE: Shared IPTE-interlock facility"),
+    FEAT_INIT("sigpif", S390_FEAT_TYPE_SCLP_CPU, 12, "SIE: SIGP interpretation facility"),
+    FEAT_INIT("ib", S390_FEAT_TYPE_SCLP_CPU, 42, "SIE: Intervention bypass facility"),
+    FEAT_INIT("cei", S390_FEAT_TYPE_SCLP_CPU, 43, "SIE: Conditional-external-interception facility"),
+
+    FEAT_INIT("dateh2", S390_FEAT_TYPE_MISC, 0, "DAT-enhancement facility 2"),
+    FEAT_INIT("cmm", S390_FEAT_TYPE_MISC, 0, "Collaborative-memory-management facility"),
+
+    FEAT_INIT("plo-cl", S390_FEAT_TYPE_PLO, 0, "PLO Compare and load (32 bit in general registers)"),
+    FEAT_INIT("plo-clg", S390_FEAT_TYPE_PLO, 1, "PLO Compare and load (64 bit in parameter list)"),
+    FEAT_INIT("plo-clgr", S390_FEAT_TYPE_PLO, 2, "PLO Compare and load (32 bit in general registers)"),
+    FEAT_INIT("plo-clx", S390_FEAT_TYPE_PLO, 3, "PLO Compare and load (128 bit in parameter list)"),
+    FEAT_INIT("plo-cs", S390_FEAT_TYPE_PLO, 4, "PLO Compare and swap (32 bit in general registers)"),
+    FEAT_INIT("plo-csg", S390_FEAT_TYPE_PLO, 5, "PLO Compare and swap (64 bit in parameter list)"),
+    FEAT_INIT("plo-csgr", S390_FEAT_TYPE_PLO, 6, "PLO Compare and swap (32 bit in general registers)"),
+    FEAT_INIT("plo-csx", S390_FEAT_TYPE_PLO, 7, "PLO Compare and swap (128 bit in parameter list)"),
+    FEAT_INIT("plo-dcs", S390_FEAT_TYPE_PLO, 8, "PLO Double compare and swap (32 bit in general registers)"),
+    FEAT_INIT("plo-dcsg", S390_FEAT_TYPE_PLO, 9, "PLO Double compare and swap (64 bit in parameter list)"),
+    FEAT_INIT("plo-dcsgr", S390_FEAT_TYPE_PLO, 10, "PLO Double compare and swap (32 bit in general registers)"),
+    FEAT_INIT("plo-dcsx", S390_FEAT_TYPE_PLO, 11, "PLO Double compare and swap (128 bit in parameter list)"),
+    FEAT_INIT("plo-csst", S390_FEAT_TYPE_PLO, 12, "PLO Compare and swap and store (32 bit in general registers)"),
+    FEAT_INIT("plo-csstg", S390_FEAT_TYPE_PLO, 13, "PLO Compare and swap and store (64 bit in parameter list)"),
+    FEAT_INIT("plo-csstgr", S390_FEAT_TYPE_PLO, 14, "PLO Compare and swap and store (32 bit in general registers)"),
+    FEAT_INIT("plo-csstx", S390_FEAT_TYPE_PLO, 15, "PLO Compare and swap and store (128 bit in parameter list)"),
+    FEAT_INIT("plo-csdst", S390_FEAT_TYPE_PLO, 16, "PLO Compare and swap and double store (32 bit in general registers)"),
+    FEAT_INIT("plo-csdstg", S390_FEAT_TYPE_PLO, 17, "PLO Compare and swap and double store (64 bit in parameter list)"),
+    FEAT_INIT("plo-csdstgr", S390_FEAT_TYPE_PLO, 18, "PLO Compare and swap and double store (32 bit in general registers)"),
+    FEAT_INIT("plo-csdstx", S390_FEAT_TYPE_PLO, 19, "PLO Compare and swap and double store (128 bit in parameter list)"),
+    FEAT_INIT("plo-cstst", S390_FEAT_TYPE_PLO, 20, "PLO Compare and swap and triple store (32 bit in general registers)"),
+    FEAT_INIT("plo-cststg", S390_FEAT_TYPE_PLO, 21, "PLO Compare and swap and triple store (64 bit in parameter list)"),
+    FEAT_INIT("plo-cststgr", S390_FEAT_TYPE_PLO, 22, "PLO Compare and swap and triple store (32 bit in general registers)"),
+    FEAT_INIT("plo-cststx", S390_FEAT_TYPE_PLO, 23, "PLO Compare and swap and triple store (128 bit in parameter list)"),
+
+    FEAT_INIT("ptff-qto", S390_FEAT_TYPE_PTFF, 1, "PTFF Query TOD Offset"),
+    FEAT_INIT("ptff-qsi", S390_FEAT_TYPE_PTFF, 2, "PTFF Query Steering Information"),
+    FEAT_INIT("ptff-qpc", S390_FEAT_TYPE_PTFF, 3, "PTFF Query Physical Clock"),
+    FEAT_INIT("ptff-qui", S390_FEAT_TYPE_PTFF, 4, "PTFF Query UTC Information"),
+    FEAT_INIT("ptff-qtou", S390_FEAT_TYPE_PTFF, 5, "PTFF Query TOD Offset User"),
+    FEAT_INIT("ptff-sto", S390_FEAT_TYPE_PTFF, 65, "PTFF Set TOD Offset"),
+    FEAT_INIT("ptff-stou", S390_FEAT_TYPE_PTFF, 69, "PTFF Set TOD Offset User"),
+
+    FEAT_INIT("kmac-dea", S390_FEAT_TYPE_KMAC, 1, "KMAC DEA"),
+    FEAT_INIT("kmac-tdea-128", S390_FEAT_TYPE_KMAC, 2, "KMAC TDEA-128"),
+    FEAT_INIT("kmac-tdea-192", S390_FEAT_TYPE_KMAC, 3, "KMAC TDEA-192"),
+    FEAT_INIT("kmac-edea", S390_FEAT_TYPE_KMAC, 9, "KMAC Encrypted-DEA"),
+    FEAT_INIT("kmac-etdea-128", S390_FEAT_TYPE_KMAC, 10, "KMAC Encrypted-TDEA-128"),
+    FEAT_INIT("kmac-etdea-192", S390_FEAT_TYPE_KMAC, 11, "KMAC Encrypted-TDEA-192"),
+    FEAT_INIT("kmac-aes-128", S390_FEAT_TYPE_KMAC, 18, "KMAC AES-128"),
+    FEAT_INIT("kmac-aes-192", S390_FEAT_TYPE_KMAC, 19, "KMAC AES-192"),
+    FEAT_INIT("kmac-aes-256", S390_FEAT_TYPE_KMAC, 20, "KMAC AES-256"),
+    FEAT_INIT("kmac-eaes-128", S390_FEAT_TYPE_KMAC, 26, "KMAC Encrypted-AES-128"),
+    FEAT_INIT("kmac-eaes-192", S390_FEAT_TYPE_KMAC, 27, "KMAC Encrypted-AES-192"),
+    FEAT_INIT("kmac-eaes-256", S390_FEAT_TYPE_KMAC, 28, "KMAC Encrypted-AES-256"),
+
+    FEAT_INIT("kmc-dea", S390_FEAT_TYPE_KMC, 1, "KMC DEA"),
+    FEAT_INIT("kmc-tdea-128", S390_FEAT_TYPE_KMC, 2, "KMC TDEA-128"),
+    FEAT_INIT("kmc-tdea-192", S390_FEAT_TYPE_KMC, 3, "KMC TDEA-192"),
+    FEAT_INIT("kmc-edea", S390_FEAT_TYPE_KMC, 9, "KMC Encrypted-DEA"),
+    FEAT_INIT("kmc-etdea-128", S390_FEAT_TYPE_KMC, 10, "KMC Encrypted-TDEA-128"),
+    FEAT_INIT("kmc-etdea-192", S390_FEAT_TYPE_KMC, 11, "KMC Encrypted-TDEA-192"),
+    FEAT_INIT("kmc-aes-128", S390_FEAT_TYPE_KMC, 18, "KMC AES-128"),
+    FEAT_INIT("kmc-aes-192", S390_FEAT_TYPE_KMC, 19, "KMC AES-192"),
+    FEAT_INIT("kmc-aes-256", S390_FEAT_TYPE_KMC, 20, "KMC AES-256"),
+    FEAT_INIT("kmc-eaes-128", S390_FEAT_TYPE_KMC, 26, "KMC Encrypted-AES-128"),
+    FEAT_INIT("kmc-eaes-192", S390_FEAT_TYPE_KMC, 27, "KMC Encrypted-AES-192"),
+    FEAT_INIT("kmc-eaes-256", S390_FEAT_TYPE_KMC, 28, "KMC Encrypted-AES-256"),
+    FEAT_INIT("kmc-prng", S390_FEAT_TYPE_KMC, 67, "KMC PRNG"),
+
+    FEAT_INIT("km-dea", S390_FEAT_TYPE_KM, 1, "KM DEA"),
+    FEAT_INIT("km-tdea-128", S390_FEAT_TYPE_KM, 2, "KM TDEA-128"),
+    FEAT_INIT("km-tdea-192", S390_FEAT_TYPE_KM, 3, "KM TDEA-192"),
+    FEAT_INIT("km-edea", S390_FEAT_TYPE_KM, 9, "KM Encrypted-DEA"),
+    FEAT_INIT("km-etdea-128", S390_FEAT_TYPE_KM, 10, "KM Encrypted-TDEA-128"),
+    FEAT_INIT("km-etdea-192", S390_FEAT_TYPE_KM, 11, "KM Encrypted-TDEA-192"),
+    FEAT_INIT("km-aes-128", S390_FEAT_TYPE_KM, 18, "KM AES-128"),
+    FEAT_INIT("km-aes-192", S390_FEAT_TYPE_KM, 19, "KM AES-192"),
+    FEAT_INIT("km-aes-256", S390_FEAT_TYPE_KM, 20, "KM AES-256"),
+    FEAT_INIT("km-eaes-128", S390_FEAT_TYPE_KM, 26, "KM Encrypted-AES-128"),
+    FEAT_INIT("km-eaes-192", S390_FEAT_TYPE_KM, 27, "KM Encrypted-AES-192"),
+    FEAT_INIT("km-eaes-256", S390_FEAT_TYPE_KM, 28, "KM Encrypted-AES-256"),
+    FEAT_INIT("km-xts-aes-128", S390_FEAT_TYPE_KM, 50, "KM XTS-AES-128"),
+    FEAT_INIT("km-xts-aes-256", S390_FEAT_TYPE_KM, 52, "KM XTS-AES-256"),
+    FEAT_INIT("km-xts-eaes-128", S390_FEAT_TYPE_KM, 58, "KM XTS-Encrypted-AES-128"),
+    FEAT_INIT("km-xts-eaes-256", S390_FEAT_TYPE_KM, 60, "KM XTS-Encrypted-AES-256"),
+
+    FEAT_INIT("kimd-sha-1", S390_FEAT_TYPE_KIMD, 1, "KIMD SHA-1"),
+    FEAT_INIT("kimd-sha-256", S390_FEAT_TYPE_KIMD, 2, "KIMD SHA-256"),
+    FEAT_INIT("kimd-sha-512", S390_FEAT_TYPE_KIMD, 3, "KIMD SHA-512"),
+    FEAT_INIT("kimd-ghash", S390_FEAT_TYPE_KIMD, 65, "KIMD GHASH"),
+    FEAT_INIT("klmd-sha-1", S390_FEAT_TYPE_KLMD, 1, "KLMD SHA-1"),
+    FEAT_INIT("klmd-sha-256", S390_FEAT_TYPE_KLMD, 2, "KLMD SHA-256"),
+    FEAT_INIT("klmd-sha-512", S390_FEAT_TYPE_KLMD, 3, "KLMD SHA-512"),
+
+    FEAT_INIT("pckmo-edea", S390_FEAT_TYPE_PCKMO, 1, "PCKMO Encrypted-DEA-Key"),
+    FEAT_INIT("pckmo-etdea-128", S390_FEAT_TYPE_PCKMO, 2, "PCKMO Encrypted-TDEA-128-Key"),
+    FEAT_INIT("pckmo-etdea-192", S390_FEAT_TYPE_PCKMO, 3, "PCKMO Encrypted-TDEA-192-Key"),
+    FEAT_INIT("pckmo-aes-128", S390_FEAT_TYPE_PCKMO, 18, "PCKMO Encrypted-AES-128-Key"),
+    FEAT_INIT("pckmo-aes-192", S390_FEAT_TYPE_PCKMO, 19, "PCKMO Encrypted-AES-192-Key"),
+    FEAT_INIT("pckmo-aes-256", S390_FEAT_TYPE_PCKMO, 20, "PCKMO Encrypted-AES-256-Key"),
+
+    FEAT_INIT("kmctr-dea", S390_FEAT_TYPE_KMCTR, 1, "KMCTR DEA"),
+    FEAT_INIT("kmctr-tdea-128", S390_FEAT_TYPE_KMCTR, 2, "KMCTR TDEA-128"),
+    FEAT_INIT("kmctr-tdea-192", S390_FEAT_TYPE_KMCTR, 3, "KMCTR TDEA-192"),
+    FEAT_INIT("kmctr-edea", S390_FEAT_TYPE_KMCTR, 9, "KMCTR Encrypted-DEA"),
+    FEAT_INIT("kmctr-etdea-128", S390_FEAT_TYPE_KMCTR, 10, "KMCTR Encrypted-TDEA-128"),
+    FEAT_INIT("kmctr-etdea-192", S390_FEAT_TYPE_KMCTR, 11, "KMCTR Encrypted-TDEA-192"),
+    FEAT_INIT("kmctr-aes-128", S390_FEAT_TYPE_KMCTR, 18, "KMCTR AES-128"),
+    FEAT_INIT("kmctr-aes-192", S390_FEAT_TYPE_KMCTR, 19, "KMCTR AES-192"),
+    FEAT_INIT("kmctr-aes-256", S390_FEAT_TYPE_KMCTR, 20, "KMCTR AES-256"),
+    FEAT_INIT("kmctr-eaes-128", S390_FEAT_TYPE_KMCTR, 26, "KMCTR Encrypted-AES-128"),
+    FEAT_INIT("kmctr-eaes-192", S390_FEAT_TYPE_KMCTR, 27, "KMCTR Encrypted-AES-192"),
+    FEAT_INIT("kmctr-eaes-256", S390_FEAT_TYPE_KMCTR, 28, "KMCTR Encrypted-AES-256"),
+
+    FEAT_INIT("kmf-dea", S390_FEAT_TYPE_KMF, 1, "KMF DEA"),
+    FEAT_INIT("kmf-tdea-128", S390_FEAT_TYPE_KMF, 2, "KMF TDEA-128"),
+    FEAT_INIT("kmf-tdea-192", S390_FEAT_TYPE_KMF, 3, "KMF TDEA-192"),
+    FEAT_INIT("kmf-edea", S390_FEAT_TYPE_KMF, 9, "KMF Encrypted-DEA"),
+    FEAT_INIT("kmf-etdea-128", S390_FEAT_TYPE_KMF, 10, "KMF Encrypted-TDEA-128"),
+    FEAT_INIT("kmf-etdea-192", S390_FEAT_TYPE_KMF, 11, "KMF Encrypted-TDEA-192"),
+    FEAT_INIT("kmf-aes-128", S390_FEAT_TYPE_KMF, 18, "KMF AES-128"),
+    FEAT_INIT("kmf-aes-192", S390_FEAT_TYPE_KMF, 19, "KMF AES-192"),
+    FEAT_INIT("kmf-aes-256", S390_FEAT_TYPE_KMF, 20, "KMF AES-256"),
+    FEAT_INIT("kmf-eaes-128", S390_FEAT_TYPE_KMF, 26, "KMF Encrypted-AES-128"),
+    FEAT_INIT("kmf-eaes-192", S390_FEAT_TYPE_KMF, 27, "KMF Encrypted-AES-192"),
+    FEAT_INIT("kmf-eaes-256", S390_FEAT_TYPE_KMF, 28, "KMF Encrypted-AES-256"),
+
+    FEAT_INIT("kmo-dea", S390_FEAT_TYPE_KMO, 1, "KMO DEA"),
+    FEAT_INIT("kmo-tdea-128", S390_FEAT_TYPE_KMO, 2, "KMO TDEA-128"),
+    FEAT_INIT("kmo-tdea-192", S390_FEAT_TYPE_KMO, 3, "KMO TDEA-192"),
+    FEAT_INIT("kmo-edea", S390_FEAT_TYPE_KMO, 9, "KMO Encrypted-DEA"),
+    FEAT_INIT("kmo-etdea-128", S390_FEAT_TYPE_KMO, 10, "KMO Encrypted-TDEA-128"),
+    FEAT_INIT("kmo-etdea-192", S390_FEAT_TYPE_KMO, 11, "KMO Encrypted-TDEA-192"),
+    FEAT_INIT("kmo-aes-128", S390_FEAT_TYPE_KMO, 18, "KMO AES-128"),
+    FEAT_INIT("kmo-aes-192", S390_FEAT_TYPE_KMO, 19, "KMO AES-192"),
+    FEAT_INIT("kmo-aes-256", S390_FEAT_TYPE_KMO, 20, "KMO AES-256"),
+    FEAT_INIT("kmo-eaes-128", S390_FEAT_TYPE_KMO, 26, "KMO Encrypted-AES-128"),
+    FEAT_INIT("kmo-eaes-192", S390_FEAT_TYPE_KMO, 27, "KMO Encrypted-AES-192"),
+    FEAT_INIT("kmo-eaes-256", S390_FEAT_TYPE_KMO, 28, "KMO Encrypted-AES-256"),
+
+    FEAT_INIT("pcc-cmac-dea", S390_FEAT_TYPE_PCC, 1, "PCC Compute-Last-Block-CMAC-Using-DEA"),
+    FEAT_INIT("pcc-cmac-tdea-128", S390_FEAT_TYPE_PCC, 2, "PCC Compute-Last-Block-CMAC-Using-TDEA-128"),
+    FEAT_INIT("pcc-cmac-tdea-192", S390_FEAT_TYPE_PCC, 3, "PCC Compute-Last-Block-CMAC-Using-TDEA-192"),
+    FEAT_INIT("pcc-cmac-edea", S390_FEAT_TYPE_PCC, 9, "PCC Compute-Last-Block-CMAC-Using-Encrypted-DEA"),
+    FEAT_INIT("pcc-cmac-etdea-128", S390_FEAT_TYPE_PCC, 10, "PCC Compute-Last-Block-CMAC-Using-Encrypted-TDEA-128"),
+    FEAT_INIT("pcc-cmac-etdea-192", S390_FEAT_TYPE_PCC, 11, "PCC Compute-Last-Block-CMAC-Using-EncryptedTDEA-192"),
+    FEAT_INIT("pcc-cmac-aes-128", S390_FEAT_TYPE_PCC, 18, "PCC Compute-Last-Block-CMAC-Using-AES-128"),
+    FEAT_INIT("pcc-cmac-aes-192", S390_FEAT_TYPE_PCC, 19, "PCC Compute-Last-Block-CMAC-Using-AES-192"),
+    FEAT_INIT("pcc-cmac-eaes-256", S390_FEAT_TYPE_PCC, 20, "PCC Compute-Last-Block-CMAC-Using-AES-256"),
+    FEAT_INIT("pcc-cmac-eaes-128", S390_FEAT_TYPE_PCC, 26, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-128"),
+    FEAT_INIT("pcc-cmac-eaes-192", S390_FEAT_TYPE_PCC, 27, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-192"),
+    FEAT_INIT("pcc-cmac-eaes-256", S390_FEAT_TYPE_PCC, 28, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-256"),
+    FEAT_INIT("pcc-xts-aes-128", S390_FEAT_TYPE_PCC, 50, "PCC Compute-XTS-Parameter-Using-AES-128"),
+    FEAT_INIT("pcc-xts-aes-256", S390_FEAT_TYPE_PCC, 52, "PCC Compute-XTS-Parameter-Using-AES-256"),
+    FEAT_INIT("pcc-xts-eaes-128", S390_FEAT_TYPE_PCC, 58, "PCC Compute-XTS-Parameter-Using-Encrypted-AES-128"),
+    FEAT_INIT("pcc-xts-eaes-256", S390_FEAT_TYPE_PCC, 60, "PCC Compute-XTS-Parameter-Using-Encrypted-AES-256"),
+
+    FEAT_INIT("ppno-sha-512-drng", S390_FEAT_TYPE_PPNO, 3, "PPNO SHA-512-DRNG"),
+};
+
+const S390FeatDef *s390_feat_def(S390Feat feat)
+{
+    return &s390_features[feat];
+}
+
+S390Feat s390_feat_by_type_and_bit(S390FeatType type, int bit)
+{
+    S390Feat feat;
+
+    for (feat = 0; feat < ARRAY_SIZE(s390_features); feat++) {
+        if (s390_features[feat].type == type &&
+            s390_features[feat].bit == bit) {
+            return feat;
+        }
+    }
+    return S390_FEAT_MAX;
+}
+
+void s390_fill_feat_block(const S390FeatBitmap features, S390FeatType type,
+                          uint8_t *data)
+{
+    S390Feat feat;
+    int bit_nr;
+
+    if (type == S390_FEAT_TYPE_STFL && test_bit(S390_FEAT_ZARCH, features)) {
+        /* z/Architecture is always active if around */
+        data[0] |= 0x20;
+    }
+
+    feat = find_first_bit(features, S390_FEAT_MAX);
+    while (feat < S390_FEAT_MAX) {
+        if (s390_features[feat].type == type) {
+            bit_nr = s390_features[feat].bit;
+            /* big endian on uint8_t array */
+            data[bit_nr / 8] |= 0x80 >> (bit_nr % 8);
+        }
+        feat = find_next_bit(features, S390_FEAT_MAX, feat + 1);
+    }
+}
+
+void s390_add_from_feat_block(S390FeatBitmap features, S390FeatType type,
+                              uint8_t *data)
+{
+    int nr_bits, le_bit;
+
+    switch (type) {
+    case S390_FEAT_TYPE_STFL:
+       nr_bits = 2048;
+       break;
+    case S390_FEAT_TYPE_PLO:
+       nr_bits = 256;
+       break;
+    default:
+       /* all cpu subfunctions have 128 bit */
+       nr_bits = 128;
+    };
+
+    le_bit = find_first_bit((unsigned long *) data, nr_bits);
+    while (le_bit < nr_bits) {
+        /* convert the bit number to a big endian bit nr */
+        S390Feat feat = s390_feat_by_type_and_bit(type, BE_BIT_NR(le_bit));
+        /* ignore unknown bits */
+        if (feat < S390_FEAT_MAX) {
+            set_bit(feat, features);
+        }
+        le_bit = find_next_bit((unsigned long *) data, nr_bits, le_bit + 1);
+    }
+}
+
+void s390_feat_bitmap_to_ascii(const S390FeatBitmap bitmap, void *opaque,
+                               void (*fn)(const char *name, void *opaque))
+{
+    S390Feat feat;
+
+    feat = find_first_bit(bitmap, S390_FEAT_MAX);
+    while (feat < S390_FEAT_MAX) {
+        (*fn)(s390_feat_def(feat)->name, opaque);
+        feat = find_next_bit(bitmap, S390_FEAT_MAX, feat + 1);
+    };
+}
diff --git a/target-s390x/cpu_features.h b/target-s390x/cpu_features.h
new file mode 100644
index 0000000..485446c
--- /dev/null
+++ b/target-s390x/cpu_features.h
@@ -0,0 +1,279 @@
+/*
+ * CPU features/facilities for s390
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * Author(s): Michael Mueller <mimu@linux.vnet.ibm.com>
+ *            David Hildenbrand <dahi@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#ifndef TARGET_S390X_CPU_FEATURES_H
+#define TARGET_S390X_CPU_FEATURES_H
+
+#include "qemu/bitmap.h"
+
+typedef enum {
+    S390_FEAT_N3 = 0,
+    S390_FEAT_ZARCH,
+    S390_FEAT_DAT_ENH_1,
+    S390_FEAT_IDTE_SEGMENT,
+    S390_FEAT_IDTE_REGION,
+    S390_FEAT_ASN_LX_REUSE,
+    S390_FEAT_STFLE,
+    S390_FEAT_EDAT_1,
+    S390_FEAT_SENSE_RUNNING_STATUS,
+    S390_FEAT_CONDITIONAL_SSKE,
+    S390_FEAT_CONFIGURATION_TOPOLOGY,
+    S390_FEAT_IPTE_RANGE,
+    S390_FEAT_NONQ_KEY_SETTING,
+    S390_FEAT_EXTENDED_TRANSLATION_2,
+    S390_FEAT_MSA,
+    S390_FEAT_LONG_DISPLACEMENT,
+    S390_FEAT_LONG_DISPLACEMENT_FAST,
+    S390_FEAT_HFP_MADDSUB,
+    S390_FEAT_EXTENDED_IMMEDIATE,
+    S390_FEAT_EXTENDED_TRANSLATION_3,
+    S390_FEAT_HFP_UNNORMALIZED_EXT,
+    S390_FEAT_ETF2_ENH,
+    S390_FEAT_STORE_CLOCK_FAST,
+    S390_FEAT_PARSING_ENH,
+    S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
+    S390_FEAT_TOD_CLOCK_STEERING,
+    S390_FEAT_ETF3_ENH,
+    S390_FEAT_EXTRACT_CPU_TIME,
+    S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
+    S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
+    S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
+    S390_FEAT_EXECUTE_EXT,
+    S390_FEAT_ENHANCED_MONITOR,
+    S390_FEAT_FLOATING_POINT_EXT,
+    S390_FEAT_SET_PROGRAM_PARAMETERS,
+    S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
+    S390_FEAT_DFP,
+    S390_FEAT_DFP_FAST,
+    S390_FEAT_PFPO,
+    S390_FEAT_GEN11_ENH,
+    S390_FEAT_CMPSC_ENH,
+    S390_FEAT_DFP_ZONED_CONVERSION,
+    S390_FEAT_GEN12_ENH,
+    S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
+    S390_FEAT_LOCAL_TLB_CLEARING,
+    S390_FEAT_INTERLOCKED_ACCESS_2,
+    S390_FEAT_GEN13_ENH,
+    S390_FEAT_MSA_EXT_5,
+    S390_FEAT_RUNTIME_INSTRUMENTATION,
+    S390_FEAT_TRANSACTIONAL_EXE,
+    S390_FEAT_STORE_HYPERVISOR_INFO,
+    S390_FEAT_ACCESS_EXCEPTION_FS_INDICATION,
+    S390_FEAT_MSA_EXT_3,
+    S390_FEAT_MSA_EXT_4,
+    S390_FEAT_EDAT_2,
+    S390_FEAT_DFP_PACKED_CONVERSION,
+    S390_FEAT_VECTOR,
+    S390_FEAT_STORE_CPU_COUNTER_MULTI,
+    S390_FEAT_SIE_GSLS,
+    S390_FEAT_ESOP,
+    S390_FEAT_SIE_64BSCAO,
+    S390_FEAT_SIE_CMMA,
+    S390_FEAT_SIE_PFMFI,
+    S390_FEAT_SIE_IBS,
+    S390_FEAT_SIE_F2,
+    S390_FEAT_SIE_SKEY,
+    S390_FEAT_SIE_GPERE,
+    S390_FEAT_SIE_SIIF,
+    S390_FEAT_SIE_SIGPIF,
+    S390_FEAT_SIE_IB,
+    S390_FEAT_SIE_CEI,
+    S390_FEAT_DAT_ENH_2,
+    S390_FEAT_CMM,
+    S390_FEAT_PLO_CL,
+    S390_FEAT_PLO_CLG,
+    S390_FEAT_PLO_CLGR,
+    S390_FEAT_PLO_CLX,
+    S390_FEAT_PLO_CS,
+    S390_FEAT_PLO_CSG,
+    S390_FEAT_PLO_CSGR,
+    S390_FEAT_PLO_CSX,
+    S390_FEAT_PLO_DCS,
+    S390_FEAT_PLO_DCSG,
+    S390_FEAT_PLO_DCSGR,
+    S390_FEAT_PLO_DCSX,
+    S390_FEAT_PLO_CSST,
+    S390_FEAT_PLO_CSSTG,
+    S390_FEAT_PLO_CSSTGR,
+    S390_FEAT_PLO_CSSTX,
+    S390_FEAT_PLO_CSDST,
+    S390_FEAT_PLO_CSDSTG,
+    S390_FEAT_PLO_CSDSTGR,
+    S390_FEAT_PLO_CSDSTX,
+    S390_FEAT_PLO_CSTST,
+    S390_FEAT_PLO_CSTSTG,
+    S390_FEAT_PLO_CSTSTGR,
+    S390_FEAT_PLO_CSTSTX,
+    S390_FEAT_PTFF_QTO,
+    S390_FEAT_PTFF_QSI,
+    S390_FEAT_PTFF_QPT,
+    S390_FEAT_PTFF_QUI,
+    S390_FEAT_PTFF_QTOU,
+    S390_FEAT_PTFF_STO,
+    S390_FEAT_PTFF_STOU,
+    S390_FEAT_KMAC_DEA,
+    S390_FEAT_KMAC_TDEA_128,
+    S390_FEAT_KMAC_TDEA_192,
+    S390_FEAT_KMAC_EDEA,
+    S390_FEAT_KMAC_ETDEA_128,
+    S390_FEAT_KMAC_ETDEA_192,
+    S390_FEAT_KMAC_AES_128,
+    S390_FEAT_KMAC_AES_192,
+    S390_FEAT_KMAC_AES_256,
+    S390_FEAT_KMAC_EAES_128,
+    S390_FEAT_KMAC_EAES_192,
+    S390_FEAT_KMAC_EAES_256,
+    S390_FEAT_KMC_DEA,
+    S390_FEAT_KMC_TDEA_128,
+    S390_FEAT_KMC_TDEA_192,
+    S390_FEAT_KMC_EDEA,
+    S390_FEAT_KMC_ETDEA_128,
+    S390_FEAT_KMC_ETDEA_192,
+    S390_FEAT_KMC_AES_128,
+    S390_FEAT_KMC_AES_192,
+    S390_FEAT_KMC_AES_256,
+    S390_FEAT_KMC_EAES_128,
+    S390_FEAT_KMC_EAES_192,
+    S390_FEAT_KMC_EAES_256,
+    S390_FEAT_KMC_PRNG,
+    S390_FEAT_KM_DEA,
+    S390_FEAT_KM_TDEA_128,
+    S390_FEAT_KM_TDEA_192,
+    S390_FEAT_KM_EDEA,
+    S390_FEAT_KM_ETDEA_128,
+    S390_FEAT_KM_ETDEA_192,
+    S390_FEAT_KM_AES_128,
+    S390_FEAT_KM_AES_192,
+    S390_FEAT_KM_AES_256,
+    S390_FEAT_KM_EAES_128,
+    S390_FEAT_KM_EAES_192,
+    S390_FEAT_KM_EAES_256,
+    S390_FEAT_KM_XTS_AES_128,
+    S390_FEAT_KM_XTS_AES_256,
+    S390_FEAT_KM_XTS_EAES_128,
+    S390_FEAT_KM_XTS_EAES_256,
+    S390_FEAT_KIMD_SHA_1,
+    S390_FEAT_KIMD_SHA_256,
+    S390_FEAT_KIMD_SHA_512,
+    S390_FEAT_KIMD_GHASH,
+    S390_FEAT_KLMD_SHA_1,
+    S390_FEAT_KLMD_SHA_256,
+    S390_FEAT_KLMD_SHA_512,
+    S390_FEAT_PCKMO_EDEA,
+    S390_FEAT_PCKMO_ETDEA_128,
+    S390_FEAT_PCKMO_ETDEA_256,
+    S390_FEAT_PCKMO_AES_128,
+    S390_FEAT_PCKMO_AES_192,
+    S390_FEAT_PCKMO_AES_256,
+    S390_FEAT_KMCTR_DEA,
+    S390_FEAT_KMCTR_TDEA_128,
+    S390_FEAT_KMCTR_TDEA_192,
+    S390_FEAT_KMCTR_EDEA,
+    S390_FEAT_KMCTR_ETDEA_128,
+    S390_FEAT_KMCTR_ETDEA_192,
+    S390_FEAT_KMCTR_AES_128,
+    S390_FEAT_KMCTR_AES_192,
+    S390_FEAT_KMCTR_AES_256,
+    S390_FEAT_KMCTR_EAES_128,
+    S390_FEAT_KMCTR_EAES_192,
+    S390_FEAT_KMCTR_EAES_256,
+    S390_FEAT_KMF_DEA,
+    S390_FEAT_KMF_TDEA_128,
+    S390_FEAT_KMF_TDEA_192,
+    S390_FEAT_KMF_EDEA,
+    S390_FEAT_KMF_ETDEA_128,
+    S390_FEAT_KMF_ETDEA_192,
+    S390_FEAT_KMF_AES_128,
+    S390_FEAT_KMF_AES_192,
+    S390_FEAT_KMF_AES_256,
+    S390_FEAT_KMF_EAES_128,
+    S390_FEAT_KMF_EAES_192,
+    S390_FEAT_KMF_EAES_256,
+    S390_FEAT_KMO_DEA,
+    S390_FEAT_KMO_TDEA_128,
+    S390_FEAT_KMO_TDEA_192,
+    S390_FEAT_KMO_EDEA,
+    S390_FEAT_KMO_ETDEA_128,
+    S390_FEAT_KMO_ETDEA_192,
+    S390_FEAT_KMO_AES_128,
+    S390_FEAT_KMO_AES_192,
+    S390_FEAT_KMO_AES_256,
+    S390_FEAT_KMO_EAES_128,
+    S390_FEAT_KMO_EAES_192,
+    S390_FEAT_KMO_EAES_256,
+    S390_FEAT_PCC_CMAC_DEA,
+    S390_FEAT_PCC_CMAC_TDEA_128,
+    S390_FEAT_PCC_CMAC_TDEA_192,
+    S390_FEAT_PCC_CMAC_ETDEA_128,
+    S390_FEAT_PCC_CMAC_ETDEA_192,
+    S390_FEAT_PCC_CMAC_TDEA,
+    S390_FEAT_PCC_CMAC_AES_128,
+    S390_FEAT_PCC_CMAC_AES_192,
+    S390_FEAT_PCC_CMAC_AES_256,
+    S390_FEAT_PCC_CMAC_EAES_128,
+    S390_FEAT_PCC_CMAC_EAES_192,
+    S390_FEAT_PCC_CMAC_EAES_256,
+    S390_FEAT_PCC_XTS_AES_128,
+    S390_FEAT_PCC_XTS_AES_256,
+    S390_FEAT_PCC_XTS_EAES_128,
+    S390_FEAT_PCC_XTS_EAES_256,
+    S390_FEAT_PPNO_SHA_512_DRNG,
+    S390_FEAT_MAX,
+} S390Feat;
+
+/* CPU features are announced via different ways */
+typedef enum {
+    S390_FEAT_TYPE_STFL,
+    S390_FEAT_TYPE_SCLP_CONF_CHAR,
+    S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
+    S390_FEAT_TYPE_SCLP_CPU,
+    S390_FEAT_TYPE_MISC,
+    S390_FEAT_TYPE_PLO,
+    S390_FEAT_TYPE_PTFF,
+    S390_FEAT_TYPE_KMAC,
+    S390_FEAT_TYPE_KMC,
+    S390_FEAT_TYPE_KM,
+    S390_FEAT_TYPE_KIMD,
+    S390_FEAT_TYPE_KLMD,
+    S390_FEAT_TYPE_PCKMO,
+    S390_FEAT_TYPE_KMCTR,
+    S390_FEAT_TYPE_KMF,
+    S390_FEAT_TYPE_KMO,
+    S390_FEAT_TYPE_PCC,
+    S390_FEAT_TYPE_PPNO,
+} S390FeatType;
+
+/* Definition of a CPU feature */
+typedef struct {
+    const char *name;       /* name exposed to the user */
+    const char *desc;       /* description exposed to the user */
+    S390FeatType type;      /* feature type (way of indication)*/
+    int bit;                /* bit within the feature type area (fixed) */
+} S390FeatDef;
+
+/* use ordinary bitmap operations to work with features */
+typedef unsigned long S390FeatBitmap[BITS_TO_LONGS(S390_FEAT_MAX)];
+
+const S390FeatDef *s390_feat_def(S390Feat feat);
+S390Feat s390_feat_by_type_and_bit(S390FeatType type, int bit);
+void s390_fill_feat_block(const S390FeatBitmap features, S390FeatType type,
+                          uint8_t *data);
+void s390_add_from_feat_block(S390FeatBitmap features, S390FeatType type,
+                          uint8_t *data);
+void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
+                               void (*fn)(const char *name, void *opaque));
+
+#define BE_BIT_NR(BIT) (BIT ^ (BITS_PER_LONG - 1))
+#define BE_BIT(BIT) (1ULL < BE_BIT_NR(BIT))
+
+#endif /* TARGET_S390X_CPU_FEATURES_H */
-- 
2.6.6

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

* [Qemu-devel] [RFC 04/28] s390x/cpumodel: generate CPU feature lists for CPU models
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (2 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 03/28] s390x/cpumodel: introduce CPU features David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 05/28] s390x/cpumodel: generate CPU feature group lists David Hildenbrand
                   ` (25 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

From: Michael Mueller <mimu@linux.vnet.ibm.com>

This patch introduces the helper "gen-features" which allows to generate
feature list definitions at compile time. Its flexibility is better and the
error-proneness is lower when compared to static programming time added
statements.

The helper includes "target-s390x/cpu_features.h" to be able to use named
facility bits instead of numbers. The generated defines will be used for
the definition of CPU models.

We generate feature lists for each HW generation and GA for EC models. BC
models are always based on a EC version and have no separate definitions.

Base features: Features we expect to be always available in sane setups.
Migration safe - will never change. Can be seen as "minimum features
required for a CPU model".

Default features: Features we expect to be stable and around in latest
setups (e.g. having KVM support) - not migration safe.

Max features: All supported features that are theoretically allowed for a
CPU model. Exceeding these features could otherwise produce problems with
IBC (instruction blocking controls) in KVM.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
[generate base, default and models. renaming and cleanup]
---
 Makefile.target             |   2 +-
 rules.mak                   |   1 +
 target-s390x/Makefile.objs  |  20 ++
 target-s390x/gen-features.c | 506 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 528 insertions(+), 1 deletion(-)
 create mode 100644 target-s390x/gen-features.c

diff --git a/Makefile.target b/Makefile.target
index 495b474..2ed5add 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -215,7 +215,7 @@ hmp-commands-info.h: $(SRC_PATH)/hmp-commands-info.hx $(SRC_PATH)/scripts/hxtool
 qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx $(SRC_PATH)/scripts/hxtool
 	$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"  GEN   $(TARGET_DIR)$@")
 
-clean:
+clean: clean-target
 	rm -f *.a *~ $(PROGS)
 	rm -f $(shell find . -name '*.[od]')
 	rm -f hmp-commands.h qmp-commands-old.h gdbstub-xml.c
diff --git a/rules.mak b/rules.mak
index 72c5955..ce0a2a5 100644
--- a/rules.mak
+++ b/rules.mak
@@ -14,6 +14,7 @@ MAKEFLAGS += -rR
 %.cpp:
 %.m:
 %.mak:
+clean-target:
 
 # Flags for C++ compilation
 QEMU_CXXFLAGS = -D__STDC_LIMIT_MACROS $(filter-out -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Wold-style-declaration -Wold-style-definition -Wredundant-decls, $(QEMU_CFLAGS))
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index 4266c87..745d501 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -3,3 +3,23 @@ obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
 obj-y += gdbstub.o cpu_models.o cpu_features.o
 obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o
 obj-$(CONFIG_KVM) += kvm.o
+
+# build and run feature list generator
+feat-src = $(SRC_PATH)/target-$(TARGET_BASE_ARCH)/
+feat-dst = $(BUILD_DIR)/$(TARGET_DIR)
+ifneq ($(MAKECMDGOALS),clean)
+GENERATED_HEADERS += $(feat-dst)gen-features.h
+endif
+
+$(feat-dst)gen-features.h: $(feat-dst)gen-features.h-timestamp
+	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
+$(feat-dst)gen-features.h-timestamp: $(feat-dst)gen-features
+	$(call quiet-command,$< >$@,"  GEN   $(TARGET_DIR)gen-features.h")
+
+$(feat-dst)gen-features: $(feat-src)gen-features.c config-target.h
+	$(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(CFLAGS) -o $@ $<,"  CC    $(TARGET_DIR)gen-features")
+
+clean-target:
+	rm -f gen-features.h-timestamp
+	rm -f gen-features.h
+	rm -f gen-features
diff --git a/target-s390x/gen-features.c b/target-s390x/gen-features.c
new file mode 100644
index 0000000..3a7c373
--- /dev/null
+++ b/target-s390x/gen-features.c
@@ -0,0 +1,506 @@
+/*
+ * S390 feature list generator
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * Author(s): Michael Mueller <mimu@linux.vnet.ibm.com>
+ *            David Hildenbrand <dahi@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "cpu_features.h"
+
+/***** BEGIN FEATURE DEFS *****/
+
+#define S390_FEAT_GROUP_PLO \
+    S390_FEAT_PLO_CL, \
+    S390_FEAT_PLO_CLG, \
+    S390_FEAT_PLO_CLGR, \
+    S390_FEAT_PLO_CLX, \
+    S390_FEAT_PLO_CS, \
+    S390_FEAT_PLO_CSG, \
+    S390_FEAT_PLO_CSGR, \
+    S390_FEAT_PLO_CSX, \
+    S390_FEAT_PLO_DCS, \
+    S390_FEAT_PLO_DCSG, \
+    S390_FEAT_PLO_DCSGR, \
+    S390_FEAT_PLO_DCSX, \
+    S390_FEAT_PLO_CSST, \
+    S390_FEAT_PLO_CSSTG, \
+    S390_FEAT_PLO_CSSTGR, \
+    S390_FEAT_PLO_CSSTX, \
+    S390_FEAT_PLO_CSDST, \
+    S390_FEAT_PLO_CSDSTG, \
+    S390_FEAT_PLO_CSDSTGR, \
+    S390_FEAT_PLO_CSDSTX, \
+    S390_FEAT_PLO_CSTST, \
+    S390_FEAT_PLO_CSTSTG, \
+    S390_FEAT_PLO_CSTSTGR, \
+    S390_FEAT_PLO_CSTSTX
+
+#define S390_FEAT_GROUP_TOD_CLOCK_STEERING \
+    S390_FEAT_TOD_CLOCK_STEERING, \
+    S390_FEAT_PTFF_QTO, \
+    S390_FEAT_PTFF_QSI, \
+    S390_FEAT_PTFF_QPT, \
+    S390_FEAT_PTFF_STO
+
+#define S390_FEAT_GROUP_GEN13_PTFF \
+    S390_FEAT_PTFF_QUI, \
+    S390_FEAT_PTFF_QTOU, \
+    S390_FEAT_PTFF_STOU
+
+#define S390_FEAT_GROUP_MSA \
+    S390_FEAT_MSA, \
+    S390_FEAT_KMAC_DEA, \
+    S390_FEAT_KMAC_TDEA_128, \
+    S390_FEAT_KMAC_TDEA_192, \
+    S390_FEAT_KMC_DEA, \
+    S390_FEAT_KMC_TDEA_128, \
+    S390_FEAT_KMC_TDEA_192, \
+    S390_FEAT_KM_DEA, \
+    S390_FEAT_KM_TDEA_128, \
+    S390_FEAT_KM_TDEA_192, \
+    S390_FEAT_KIMD_SHA_1, \
+    S390_FEAT_KLMD_SHA_1
+
+#define S390_FEAT_GROUP_MSA_EXT_1 \
+    S390_FEAT_KMC_AES_128, \
+    S390_FEAT_KM_AES_128, \
+    S390_FEAT_KIMD_SHA_256, \
+    S390_FEAT_KLMD_SHA_256
+
+#define S390_FEAT_GROUP_MSA_EXT_2 \
+    S390_FEAT_KMC_AES_192, \
+    S390_FEAT_KMC_AES_256, \
+    S390_FEAT_KMC_PRNG, \
+    S390_FEAT_KM_AES_192, \
+    S390_FEAT_KM_AES_256, \
+    S390_FEAT_KIMD_SHA_512, \
+    S390_FEAT_KLMD_SHA_512
+
+#define S390_FEAT_GROUP_MSA_EXT_3 \
+    S390_FEAT_MSA_EXT_3, \
+    S390_FEAT_KMAC_EDEA, \
+    S390_FEAT_KMAC_ETDEA_128, \
+    S390_FEAT_KMAC_ETDEA_192, \
+    S390_FEAT_KMC_EAES_128, \
+    S390_FEAT_KMC_EAES_192, \
+    S390_FEAT_KMC_EAES_256, \
+    S390_FEAT_KMC_EDEA, \
+    S390_FEAT_KMC_ETDEA_128, \
+    S390_FEAT_KMC_ETDEA_192, \
+    S390_FEAT_KM_EDEA, \
+    S390_FEAT_KM_ETDEA_128, \
+    S390_FEAT_KM_ETDEA_192, \
+    S390_FEAT_KM_EAES_128, \
+    S390_FEAT_KM_EAES_192, \
+    S390_FEAT_KM_EAES_256, \
+    S390_FEAT_PCKMO_EDEA, \
+    S390_FEAT_PCKMO_ETDEA_128, \
+    S390_FEAT_PCKMO_ETDEA_256, \
+    S390_FEAT_PCKMO_AES_128, \
+    S390_FEAT_PCKMO_AES_192, \
+    S390_FEAT_PCKMO_AES_256
+
+#define S390_FEAT_GROUP_MSA_EXT_4 \
+    S390_FEAT_MSA_EXT_4, \
+    S390_FEAT_KMAC_AES_128, \
+    S390_FEAT_KMAC_AES_192, \
+    S390_FEAT_KMAC_AES_256, \
+    S390_FEAT_KMAC_EAES_128, \
+    S390_FEAT_KMAC_EAES_192, \
+    S390_FEAT_KMAC_EAES_256, \
+    S390_FEAT_KM_XTS_AES_128, \
+    S390_FEAT_KM_XTS_AES_256, \
+    S390_FEAT_KM_XTS_EAES_128, \
+    S390_FEAT_KM_XTS_EAES_256, \
+    S390_FEAT_KIMD_GHASH, \
+    S390_FEAT_KMCTR_DEA, \
+    S390_FEAT_KMCTR_TDEA_128, \
+    S390_FEAT_KMCTR_TDEA_192, \
+    S390_FEAT_KMCTR_EDEA, \
+    S390_FEAT_KMCTR_ETDEA_128, \
+    S390_FEAT_KMCTR_ETDEA_192, \
+    S390_FEAT_KMCTR_AES_128, \
+    S390_FEAT_KMCTR_AES_192, \
+    S390_FEAT_KMCTR_AES_256, \
+    S390_FEAT_KMCTR_EAES_128, \
+    S390_FEAT_KMCTR_EAES_192, \
+    S390_FEAT_KMCTR_EAES_256, \
+    S390_FEAT_KMF_DEA, \
+    S390_FEAT_KMF_TDEA_128, \
+    S390_FEAT_KMF_TDEA_192, \
+    S390_FEAT_KMF_EDEA, \
+    S390_FEAT_KMF_ETDEA_128, \
+    S390_FEAT_KMF_ETDEA_192, \
+    S390_FEAT_KMF_AES_128, \
+    S390_FEAT_KMF_AES_192, \
+    S390_FEAT_KMF_AES_256, \
+    S390_FEAT_KMF_EAES_128, \
+    S390_FEAT_KMF_EAES_192, \
+    S390_FEAT_KMF_EAES_256, \
+    S390_FEAT_KMO_DEA, \
+    S390_FEAT_KMO_TDEA_128, \
+    S390_FEAT_KMO_TDEA_192, \
+    S390_FEAT_KMO_EDEA, \
+    S390_FEAT_KMO_ETDEA_128, \
+    S390_FEAT_KMO_ETDEA_192, \
+    S390_FEAT_KMO_AES_128, \
+    S390_FEAT_KMO_AES_192, \
+    S390_FEAT_KMO_AES_256, \
+    S390_FEAT_KMO_EAES_128, \
+    S390_FEAT_KMO_EAES_192, \
+    S390_FEAT_KMO_EAES_256, \
+    S390_FEAT_PCC_CMAC_DEA, \
+    S390_FEAT_PCC_CMAC_TDEA_128, \
+    S390_FEAT_PCC_CMAC_TDEA_192, \
+    S390_FEAT_PCC_CMAC_ETDEA_128, \
+    S390_FEAT_PCC_CMAC_ETDEA_192, \
+    S390_FEAT_PCC_CMAC_TDEA, \
+    S390_FEAT_PCC_CMAC_AES_128, \
+    S390_FEAT_PCC_CMAC_AES_192, \
+    S390_FEAT_PCC_CMAC_AES_256, \
+    S390_FEAT_PCC_CMAC_EAES_128, \
+    S390_FEAT_PCC_CMAC_EAES_192, \
+    S390_FEAT_PCC_CMAC_EAES_256, \
+    S390_FEAT_PCC_XTS_AES_128, \
+    S390_FEAT_PCC_XTS_AES_256, \
+    S390_FEAT_PCC_XTS_EAES_128, \
+    S390_FEAT_PCC_XTS_EAES_256
+
+#define S390_FEAT_GROUP_MSA_EXT_5 \
+    S390_FEAT_MSA_EXT_5, \
+    S390_FEAT_PPNO_SHA_512_DRNG
+
+/* base features in order of release */
+static uint16_t base_GEN7_GA1[] = {
+    S390_FEAT_GROUP_PLO,
+    S390_FEAT_N3,
+    S390_FEAT_ZARCH,
+};
+#define base_GEN7_GA2 EmptyFeat
+#define base_GEN7_GA3 EmptyFeat
+static uint16_t base_GEN8_GA1[] = {
+    S390_FEAT_DAT_ENH_1,
+    S390_FEAT_EXTENDED_TRANSLATION_2,
+    S390_FEAT_GROUP_MSA,
+    S390_FEAT_LONG_DISPLACEMENT,
+    S390_FEAT_LONG_DISPLACEMENT_FAST,
+    S390_FEAT_HFP_MADDSUB,
+};
+#define base_GEN8_GA2 EmptyFeat
+#define base_GEN8_GA3 EmptyFeat
+#define base_GEN8_GA4 EmptyFeat
+#define base_GEN8_GA5 EmptyFeat
+static uint16_t base_GEN9_GA1[] = {
+    S390_FEAT_IDTE_SEGMENT,
+    S390_FEAT_ASN_LX_REUSE,
+    S390_FEAT_STFLE,
+    S390_FEAT_SENSE_RUNNING_STATUS,
+    S390_FEAT_EXTENDED_IMMEDIATE,
+    S390_FEAT_EXTENDED_TRANSLATION_3,
+    S390_FEAT_HFP_UNNORMALIZED_EXT,
+    S390_FEAT_ETF2_ENH,
+    S390_FEAT_STORE_CLOCK_FAST,
+    S390_FEAT_GROUP_TOD_CLOCK_STEERING,
+    S390_FEAT_ETF3_ENH,
+    S390_FEAT_DAT_ENH_2,
+};
+#define base_GEN9_GA2 EmptyFeat
+#define base_GEN9_GA3 EmptyFeat
+static uint16_t base_GEN10_GA1[] = {
+    S390_FEAT_CONDITIONAL_SSKE,
+    S390_FEAT_PARSING_ENH,
+    S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
+    S390_FEAT_EXTRACT_CPU_TIME,
+    S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
+    S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
+    S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
+    S390_FEAT_EXECUTE_EXT,
+    S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
+    S390_FEAT_DFP,
+    S390_FEAT_DFP_FAST,
+    S390_FEAT_PFPO,
+};
+#define base_GEN10_GA2 EmptyFeat
+#define base_GEN10_GA3 EmptyFeat
+static uint16_t base_GEN11_GA1[] = {
+    S390_FEAT_NONQ_KEY_SETTING,
+    S390_FEAT_ENHANCED_MONITOR,
+    S390_FEAT_FLOATING_POINT_EXT,
+    S390_FEAT_SET_PROGRAM_PARAMETERS,
+    S390_FEAT_GEN11_ENH,
+    S390_FEAT_CMPSC_ENH,
+    S390_FEAT_INTERLOCKED_ACCESS_2,
+};
+#define base_GEN11_GA2 EmptyFeat
+static uint16_t base_GEN12_GA1[] = {
+    S390_FEAT_DFP_ZONED_CONVERSION,
+    S390_FEAT_GEN12_ENH,
+    S390_FEAT_LOCAL_TLB_CLEARING,
+};
+#define base_GEN12_GA2 EmptyFeat
+static uint16_t base_GEN13_GA1[] = {
+    S390_FEAT_GEN13_ENH,
+    S390_FEAT_DFP_PACKED_CONVERSION,
+    S390_FEAT_GROUP_GEN13_PTFF,
+};
+#define base_GEN13_GA2 EmptyFeat
+
+/* full features differing to the base in order of release */
+static uint16_t full_GEN7_GA1[] = {
+    S390_FEAT_SIE_F2,
+    S390_FEAT_SIE_SKEY,
+    S390_FEAT_SIE_GPERE,
+    S390_FEAT_SIE_IB,
+    S390_FEAT_SIE_CEI,
+};
+static uint16_t full_GEN7_GA2[] = {
+    S390_FEAT_EXTENDED_TRANSLATION_2,
+};
+static uint16_t full_GEN7_GA3[] = {
+    S390_FEAT_LONG_DISPLACEMENT,
+    S390_FEAT_SIE_SIIF,
+};
+static uint16_t full_GEN8_GA1[] = {
+    S390_FEAT_SIE_GSLS,
+    S390_FEAT_SIE_64BSCAO,
+};
+#define full_GEN8_GA2 EmptyFeat
+static uint16_t full_GEN8_GA3[] = {
+    S390_FEAT_ASN_LX_REUSE,
+    S390_FEAT_EXTENDED_TRANSLATION_3,
+};
+#define full_GEN8_GA4 EmptyFeat
+#define full_GEN8_GA5 EmptyFeat
+static uint16_t full_GEN9_GA1[] = {
+    S390_FEAT_GROUP_MSA_EXT_1,
+    S390_FEAT_CMM,
+    S390_FEAT_SIE_CMMA,
+};
+static uint16_t full_GEN9_GA2[] = {
+    S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
+    S390_FEAT_EXTRACT_CPU_TIME,
+    S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
+    S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
+    S390_FEAT_DFP,
+};
+static uint16_t full_GEN9_GA3[] = {
+    S390_FEAT_CONDITIONAL_SSKE,
+    S390_FEAT_PFPO,
+};
+static uint16_t full_GEN10_GA1[] = {
+    S390_FEAT_EDAT_1,
+    S390_FEAT_CONFIGURATION_TOPOLOGY,
+    S390_FEAT_GROUP_MSA_EXT_2,
+    S390_FEAT_ESOP,
+    S390_FEAT_SIE_PFMFI,
+    S390_FEAT_SIE_SIGPIF,
+};
+static uint16_t full_GEN10_GA2[] = {
+    S390_FEAT_SET_PROGRAM_PARAMETERS,
+    S390_FEAT_SIE_IBS,
+};
+static uint16_t full_GEN10_GA3[] = {
+    S390_FEAT_GROUP_MSA_EXT_3,
+};
+static uint16_t full_GEN11_GA1[] = {
+    S390_FEAT_IPTE_RANGE,
+    S390_FEAT_ACCESS_EXCEPTION_FS_INDICATION,
+    S390_FEAT_GROUP_MSA_EXT_4,
+};
+#define full_GEN11_GA2 EmptyFeat
+static uint16_t full_GEN12_GA1[] = {
+    S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
+    S390_FEAT_TRANSACTIONAL_EXE,
+    S390_FEAT_RUNTIME_INSTRUMENTATION,
+    S390_FEAT_EDAT_2,
+};
+static uint16_t full_GEN12_GA2[] = {
+    S390_FEAT_GROUP_MSA_EXT_5,
+};
+static uint16_t full_GEN13_GA1[] = {
+    S390_FEAT_VECTOR,
+    S390_FEAT_STORE_CPU_COUNTER_MULTI,
+};
+#define full_GEN13_GA2 EmptyFeat
+
+/* default features differing to the base in order of release */
+#define default_GEN7_GA1 EmptyFeat
+#define default_GEN7_GA2 EmptyFeat
+#define default_GEN7_GA3 EmptyFeat
+#define default_GEN8_GA1 EmptyFeat
+#define default_GEN8_GA2 EmptyFeat
+#define default_GEN8_GA3 EmptyFeat
+#define default_GEN8_GA4 EmptyFeat
+#define default_GEN8_GA5 EmptyFeat
+static uint16_t default_GEN9_GA1[] = {
+    S390_FEAT_GROUP_MSA_EXT_1,
+};
+#define default_GEN9_GA2 EmptyFeat
+#define default_GEN9_GA3 EmptyFeat
+static uint16_t default_GEN10_GA1[] = {
+    S390_FEAT_EDAT_1,
+    S390_FEAT_GROUP_MSA_EXT_2,
+};
+#define default_GEN10_GA2 EmptyFeat
+#define default_GEN10_GA3 EmptyFeat
+static uint16_t default_GEN11_GA1[] = {
+    S390_FEAT_GROUP_MSA_EXT_3,
+    S390_FEAT_IPTE_RANGE,
+    S390_FEAT_ACCESS_EXCEPTION_FS_INDICATION,
+    S390_FEAT_GROUP_MSA_EXT_4,
+};
+#define default_GEN11_GA2 EmptyFeat
+static uint16_t default_GEN12_GA1[] = {
+    S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
+    S390_FEAT_TRANSACTIONAL_EXE,
+    S390_FEAT_RUNTIME_INSTRUMENTATION,
+    S390_FEAT_EDAT_2,
+};
+#define default_GEN12_GA2 EmptyFeat
+static uint16_t default_GEN13_GA1[] = {
+    S390_FEAT_GROUP_MSA_EXT_5,
+    S390_FEAT_VECTOR,
+};
+#define default_GEN13_GA2 EmptyFeat
+
+/****** END FEATURE DEFS ******/
+
+#define _YEARS  "2016"
+#define _NAME_H "TARGET_S390X_GEN_FEATURES_H"
+
+#define CPU_FEAT_INITIALIZER(_name)                    \
+    {                                                  \
+        .name = "S390_FEAT_LIST_" #_name,              \
+        .base_bits =                                   \
+            { .data = base_##_name,                    \
+              .len = ARRAY_SIZE(base_##_name) },       \
+        .default_bits =                                \
+            { .data = default_##_name,                 \
+              .len = ARRAY_SIZE(default_##_name) },    \
+        .full_bits =                                   \
+            { .data = full_##_name,                    \
+              .len = ARRAY_SIZE(full_##_name) },       \
+    }
+
+typedef struct BitSpec {
+    uint16_t *data;
+    uint32_t len;
+} BitSpec;
+
+typedef struct {
+    const char *name;
+    BitSpec base_bits;
+    BitSpec default_bits;
+    BitSpec full_bits;
+} CpuFeatDefSpec;
+
+static uint16_t EmptyFeat[] = {};
+
+/*******************************
+ * processor GA series
+ *******************************/
+static CpuFeatDefSpec CpuFeatDef[] = {
+    CPU_FEAT_INITIALIZER(GEN7_GA1),
+    CPU_FEAT_INITIALIZER(GEN7_GA2),
+    CPU_FEAT_INITIALIZER(GEN7_GA3),
+    CPU_FEAT_INITIALIZER(GEN8_GA1),
+    CPU_FEAT_INITIALIZER(GEN8_GA2),
+    CPU_FEAT_INITIALIZER(GEN8_GA3),
+    CPU_FEAT_INITIALIZER(GEN8_GA4),
+    CPU_FEAT_INITIALIZER(GEN8_GA5),
+    CPU_FEAT_INITIALIZER(GEN9_GA1),
+    CPU_FEAT_INITIALIZER(GEN9_GA2),
+    CPU_FEAT_INITIALIZER(GEN9_GA3),
+    CPU_FEAT_INITIALIZER(GEN10_GA1),
+    CPU_FEAT_INITIALIZER(GEN10_GA2),
+    CPU_FEAT_INITIALIZER(GEN10_GA3),
+    CPU_FEAT_INITIALIZER(GEN11_GA1),
+    CPU_FEAT_INITIALIZER(GEN11_GA2),
+    CPU_FEAT_INITIALIZER(GEN12_GA1),
+    CPU_FEAT_INITIALIZER(GEN12_GA2),
+    CPU_FEAT_INITIALIZER(GEN13_GA1),
+    CPU_FEAT_INITIALIZER(GEN13_GA2),
+};
+
+static void set_bits(uint64_t list[], BitSpec bits)
+{
+    uint32_t i;
+
+    for (i = 0; i < bits.len; i++) {
+        list[bits.data[i] / 64] |= 1ULL << (bits.data[i] % 64);
+    }
+}
+
+static void print_feature_defs(void)
+{
+    uint64_t base_feat[S390_FEAT_MAX / 64 + 1] = {};
+    uint64_t default_feat[S390_FEAT_MAX / 64 + 1] = {};
+    uint64_t full_feat[S390_FEAT_MAX / 64 + 1] = {};
+    int i, j;
+
+    printf("\n/* CPU model feature list data */\n");
+
+    for (i = 0; i < ARRAY_SIZE(CpuFeatDef); i++) {
+        set_bits(base_feat, CpuFeatDef[i].base_bits);
+        /* add the base to the default features */
+        set_bits(default_feat, CpuFeatDef[i].base_bits);
+        set_bits(default_feat, CpuFeatDef[i].default_bits);
+        /* add the base to the full features */
+        set_bits(full_feat, CpuFeatDef[i].base_bits);
+        set_bits(full_feat, CpuFeatDef[i].full_bits);
+
+        printf("#define %s_BASE\t", CpuFeatDef[i].name);
+        for (j = 0; j < ARRAY_SIZE(base_feat); j++) {
+            printf("0x%016"PRIx64"UL", base_feat[j]);
+            if (j < ARRAY_SIZE(base_feat) - 1) {
+                printf(",");
+            } else {
+                printf("\n");
+            }
+        }
+        printf("#define %s_DEFAULT\t", CpuFeatDef[i].name);
+        for (j = 0; j < ARRAY_SIZE(default_feat); j++) {
+            printf("0x%016"PRIx64"UL", default_feat[j]);
+            if (j < ARRAY_SIZE(default_feat) - 1) {
+                printf(",");
+            } else {
+                printf("\n");
+            }
+        }
+        printf("#define %s_FULL\t\t", CpuFeatDef[i].name);
+        for (j = 0; j < ARRAY_SIZE(full_feat); j++) {
+            printf("0x%016"PRIx64"UL", full_feat[j]);
+            if (j < ARRAY_SIZE(full_feat) - 1) {
+                printf(",");
+            } else {
+                printf("\n");
+            }
+        }
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    printf("/*\n"
+           " * AUTOMATICALLY GENERATED, DO NOT MODIFY HERE, EDIT\n"
+           " * SOURCE FILE \"%s\" INSTEAD.\n"
+           " *\n"
+           " * Copyright %s IBM Corp.\n"
+           " *\n"
+           " * This work is licensed under the terms of the GNU GPL, "
+           "version 2 or (at\n * your option) any later version. See "
+           "the COPYING file in the top-level\n * directory.\n"
+           " */\n\n"
+           "#ifndef %s\n#define %s\n", __FILE__, _YEARS, _NAME_H, _NAME_H);
+    print_feature_defs();
+    printf("\n#endif\n");
+    return 0;
+}
-- 
2.6.6

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

* [Qemu-devel] [RFC 05/28] s390x/cpumodel: generate CPU feature group lists
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (3 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 04/28] s390x/cpumodel: generate CPU feature lists for CPU models David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 06/28] s390x/cpumodel: introduce CPU feature group definitions David Hildenbrand
                   ` (24 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Feature groups will be very helpful to reduce the amount of features
typically available in sane configurations. E.g. the MSA facilities
introduced loads of subfunctions, which could - in theory - go away
in the future, but we want to avoid reporting hundrets of features to
the user if usually all of them are in place.

Groups only contain features that were introduced in one shot, not just
random features. Therefore, groups can never change. This is an important
property regarding migration.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/gen-features.c | 80 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/target-s390x/gen-features.c b/target-s390x/gen-features.c
index 3a7c373..d4f4b29 100644
--- a/target-s390x/gen-features.c
+++ b/target-s390x/gen-features.c
@@ -178,6 +178,35 @@
     S390_FEAT_MSA_EXT_5, \
     S390_FEAT_PPNO_SHA_512_DRNG
 
+/* cpu feature groups */
+static uint16_t group_PLO[] = {
+    S390_FEAT_GROUP_PLO,
+};
+static uint16_t group_TOD_CLOCK_STEERING[] = {
+    S390_FEAT_GROUP_TOD_CLOCK_STEERING,
+};
+static uint16_t group_GEN13_PTFF[] = {
+    S390_FEAT_GROUP_GEN13_PTFF,
+};
+static uint16_t group_MSA[] = {
+    S390_FEAT_GROUP_MSA,
+};
+static uint16_t group_MSA_EXT_1[] = {
+    S390_FEAT_GROUP_MSA_EXT_1,
+};
+static uint16_t group_MSA_EXT_2[] = {
+    S390_FEAT_GROUP_MSA_EXT_2,
+};
+static uint16_t group_MSA_EXT_3[] = {
+    S390_FEAT_GROUP_MSA_EXT_3,
+};
+static uint16_t group_MSA_EXT_4[] = {
+    S390_FEAT_GROUP_MSA_EXT_4,
+};
+static uint16_t group_MSA_EXT_5[] = {
+    S390_FEAT_GROUP_MSA_EXT_5,
+};
+
 /* base features in order of release */
 static uint16_t base_GEN7_GA1[] = {
     S390_FEAT_GROUP_PLO,
@@ -430,6 +459,34 @@ static CpuFeatDefSpec CpuFeatDef[] = {
     CPU_FEAT_INITIALIZER(GEN13_GA2),
 };
 
+#define FEAT_GROUP_INITIALIZER(_name)                  \
+    {                                                  \
+        .name = "S390_FEAT_GROUP_LIST_" #_name,        \
+        .bits =                                        \
+            { .data = group_##_name,                   \
+              .len = ARRAY_SIZE(group_##_name) },      \
+    }
+
+typedef struct {
+    const char *name;
+    BitSpec bits;
+} FeatGroupDefSpec;
+
+/*******************************
+ * feature groups
+ *******************************/
+static FeatGroupDefSpec FeatGroupDef[] = {
+    FEAT_GROUP_INITIALIZER(PLO),
+    FEAT_GROUP_INITIALIZER(TOD_CLOCK_STEERING),
+    FEAT_GROUP_INITIALIZER(GEN13_PTFF),
+    FEAT_GROUP_INITIALIZER(MSA),
+    FEAT_GROUP_INITIALIZER(MSA_EXT_1),
+    FEAT_GROUP_INITIALIZER(MSA_EXT_2),
+    FEAT_GROUP_INITIALIZER(MSA_EXT_3),
+    FEAT_GROUP_INITIALIZER(MSA_EXT_4),
+    FEAT_GROUP_INITIALIZER(MSA_EXT_5),
+};
+
 static void set_bits(uint64_t list[], BitSpec bits)
 {
     uint32_t i;
@@ -487,6 +544,28 @@ static void print_feature_defs(void)
     }
 }
 
+static void print_feature_group_defs(void)
+{
+    int i, j;
+
+    printf("\n/* CPU feature group list data */\n");
+
+    for (i = 0; i < ARRAY_SIZE(FeatGroupDef); i++) {
+        uint64_t feat[S390_FEAT_MAX / 64 + 1] = {};
+
+        set_bits(feat, FeatGroupDef[i].bits);
+        printf("#define %s\t", FeatGroupDef[i].name);
+        for (j = 0; j < ARRAY_SIZE(feat); j++) {
+            printf("0x%016"PRIx64"UL", feat[j]);
+            if (j < ARRAY_SIZE(feat) - 1) {
+                printf(",");
+            } else {
+                printf("\n");
+            }
+        }
+    }
+}
+
 int main(int argc, char *argv[])
 {
     printf("/*\n"
@@ -501,6 +580,7 @@ int main(int argc, char *argv[])
            " */\n\n"
            "#ifndef %s\n#define %s\n", __FILE__, _YEARS, _NAME_H, _NAME_H);
     print_feature_defs();
+    print_feature_group_defs();
     printf("\n#endif\n");
     return 0;
 }
-- 
2.6.6

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

* [Qemu-devel] [RFC 06/28] s390x/cpumodel: introduce CPU feature group definitions
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (4 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 05/28] s390x/cpumodel: generate CPU feature group lists David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 20:14   ` Thomas Huth
  2016-06-21 13:02 ` [Qemu-devel] [RFC 07/28] s390x/cpumodel: register defined CPU models as subclasses David Hildenbrand
                   ` (23 subsequent siblings)
  29 siblings, 1 reply; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Let's use the generated groups to create feature group representations for
the user. These groups can later be used to enable/disable multiple
features in one shot and will be used to reduce the amount of reported
features to the user if all subfeatures are in place.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/cpu_features.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
 target-s390x/cpu_features.h | 23 +++++++++++++++++++++++
 2 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/target-s390x/cpu_features.c b/target-s390x/cpu_features.c
index c78a189..6ec2bfc 100644
--- a/target-s390x/cpu_features.c
+++ b/target-s390x/cpu_features.c
@@ -12,6 +12,7 @@
 
 #include "qemu/osdep.h"
 #include "cpu_features.h"
+#include "gen-features.h"
 
 #define FEAT_INIT(_name, _type, _bit, _desc) \
     {                                                \
@@ -321,14 +322,55 @@ void s390_add_from_feat_block(S390FeatBitmap features, S390FeatType type,
     }
 }
 
-void s390_feat_bitmap_to_ascii(const S390FeatBitmap bitmap, void *opaque,
+void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
                                void (*fn)(const char *name, void *opaque))
 {
+    S390FeatBitmap bitmap, tmp;
+    S390FeatGroup group;
     S390Feat feat;
 
+    bitmap_copy(bitmap, features, S390_FEAT_MAX);
+
+    /* process whole groups first */
+    for (group = 0; group < S390_FEAT_GROUP_MAX; group++) {
+        const S390FeatGroupDef *def = s390_feat_group_def(group);
+
+        bitmap_and(tmp, bitmap, def->feat, S390_FEAT_MAX);
+        if (bitmap_equal(tmp, def->feat, S390_FEAT_MAX)) {
+            bitmap_andnot(bitmap, bitmap, def->feat, S390_FEAT_MAX);
+            (*fn)(def->name, opaque);
+        }
+    }
+
+    /* report leftovers as separate features */
     feat = find_first_bit(bitmap, S390_FEAT_MAX);
     while (feat < S390_FEAT_MAX) {
         (*fn)(s390_feat_def(feat)->name, opaque);
         feat = find_next_bit(bitmap, S390_FEAT_MAX, feat + 1);
     };
 }
+
+#define FEAT_GROUP_INIT(_name, _group, _desc)        \
+    {                                                \
+        .name = _name,                               \
+        .desc = _desc,                               \
+        .feat = { S390_FEAT_GROUP_LIST_ ## _group }, \
+    }
+
+/* indexed by feature group number for easy lookup */
+static const S390FeatGroupDef s390_feature_groups[] = {
+    FEAT_GROUP_INIT("plo", PLO, "Perform-locked-operation facility"),
+    FEAT_GROUP_INIT("tods", TOD_CLOCK_STEERING, "Tod-clock-steering facility"),
+    FEAT_GROUP_INIT("gen13ptff", GEN13_PTFF, "PTFF enhancements introduced with z13"),
+    FEAT_GROUP_INIT("msa", MSA, "Message-security-assist facility"),
+    FEAT_GROUP_INIT("msa1", MSA_EXT_1, "Message-security-assist-extension 1 facility"),
+    FEAT_GROUP_INIT("msa2", MSA_EXT_2, "Message-security-assist-extension 2 facility"),
+    FEAT_GROUP_INIT("msa3", MSA_EXT_3, "Message-security-assist-extension 3 facility"),
+    FEAT_GROUP_INIT("msa4", MSA_EXT_4, "Message-security-assist-extension 4 facility"),
+    FEAT_GROUP_INIT("msa5", MSA_EXT_5, "Message-security-assist-extension 5 facility"),
+};
+
+const S390FeatGroupDef *s390_feat_group_def(S390FeatGroup group)
+{
+    return &s390_feature_groups[group];
+}
diff --git a/target-s390x/cpu_features.h b/target-s390x/cpu_features.h
index 485446c..e40a636 100644
--- a/target-s390x/cpu_features.h
+++ b/target-s390x/cpu_features.h
@@ -273,6 +273,29 @@ void s390_add_from_feat_block(S390FeatBitmap features, S390FeatType type,
 void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
                                void (*fn)(const char *name, void *opaque));
 
+/* static groups that will never change */
+typedef enum {
+    S390_FEAT_GROUP_PLO,
+    S390_FEAT_GROUP_TOD_CLOCK_STEERING,
+    S390_FEAT_GROUP_GEN13_PTFF_ENH,
+    S390_FEAT_GROUP_MSA,
+    S390_FEAT_GROUP_MSA_EXT_1,
+    S390_FEAT_GROUP_MSA_EXT_2,
+    S390_FEAT_GROUP_MSA_EXT_3,
+    S390_FEAT_GROUP_MSA_EXT_4,
+    S390_FEAT_GROUP_MSA_EXT_5,
+    S390_FEAT_GROUP_MAX,
+} S390FeatGroup;
+
+/* Definition of a CPU feature group */
+typedef struct {
+    const char *name;       /* name exposed to the user */
+    const char *desc;       /* description exposed to the user */
+    S390FeatBitmap feat;    /* features contained in the group */
+} S390FeatGroupDef;
+
+const S390FeatGroupDef *s390_feat_group_def(S390FeatGroup group);
+
 #define BE_BIT_NR(BIT) (BIT ^ (BITS_PER_LONG - 1))
 #define BE_BIT(BIT) (1ULL < BE_BIT_NR(BIT))
 
-- 
2.6.6

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

* [Qemu-devel] [RFC 07/28] s390x/cpumodel: register defined CPU models as subclasses
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (5 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 06/28] s390x/cpumodel: introduce CPU feature group definitions David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 08/28] s390x/cpumodel: store the CPU model in the CPU instance David Hildenbrand
                   ` (22 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

This patch adds the CPU model definitions that are known on s390x -
like z900, zBC12 or z13. For each definition, introduce two CPU models:

1. Base model (e.g. z13-base): Minimum feature set we expect to be around
   on all z13 systems. These models are migration save and will never
   change.
2. Flexible models (e.g. z13): Models that can change between QEMU versions
   and will be extended over time as we implement further features that
   are already part of such a model in real hardware of certain
   configurations.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/cpu-qom.h    |   2 +
 target-s390x/cpu_models.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++
 target-s390x/cpu_models.h |  36 +++++++++++++++
 3 files changed, 149 insertions(+)
 create mode 100644 target-s390x/cpu_models.h

diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index ae0be73..d619cbd 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -21,6 +21,7 @@
 #define QEMU_S390_CPU_QOM_H
 
 #include "qom/cpu.h"
+#include "cpu_models.h"
 
 #define TYPE_S390_CPU "s390-cpu"
 
@@ -45,6 +46,7 @@ typedef struct S390CPUClass {
     /*< private >*/
     CPUClass parent_class;
     /*< public >*/
+    const S390CPUDef *cpu_def;
     bool kvm_required;
     bool migration_safe;
     const char *desc;
diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index 18638a9..50b395a 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -12,11 +12,66 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
+#include "gen-features.h"
 #include "qapi/error.h"
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/arch_init.h"
 #endif
 
+#define CPUDEF_INIT(_type, _gen, _ec_ga, _mha_pow, _hmfai, _name, _desc) \
+    {                                                             \
+        .name = _name,                                            \
+        .type = _type,                                            \
+        .gen = _gen,                                              \
+        .ec_ga = _ec_ga,                                          \
+        .mha_pow = _mha_pow,                                      \
+        .hmfai = _hmfai,                                          \
+        .desc = _desc,                                            \
+        .base_feat = { S390_FEAT_LIST_GEN ## _gen ## _GA ## _ec_ga ## _BASE },  \
+        .default_feat = { S390_FEAT_LIST_GEN ## _gen ## _GA ## _ec_ga ## _DEFAULT },  \
+        .full_feat = { S390_FEAT_LIST_GEN ## _gen ## _GA ## _ec_ga ## _FULL },  \
+    }
+
+/*
+ * CPU definiton list in order of release. For now, base features of a
+ * following release are always a subset of base features of the previous
+ * release. Same is correct for the other feature sets.
+ * A BC release always follows the corresponding EC release.
+ */
+static const S390CPUDef s390_cpu_defs[] = {
+    CPUDEF_INIT(0x2064, 7, 1, 38, 0x00000000U, "z900", "IBM zSeries 900 GA1"),
+    CPUDEF_INIT(0x2064, 7, 2, 38, 0x00000000U, "z900.2", "IBM zSeries 900 GA2"),
+    CPUDEF_INIT(0x2064, 7, 3, 38, 0x00000000U, "z900.3", "IBM zSeries 900 GA3"),
+    CPUDEF_INIT(0x2066, 7, 3, 38, 0x00000000U, "z800", "IBM zSeries 800 GA1"),
+    CPUDEF_INIT(0x2084, 8, 1, 38, 0x00000000U, "z990", "IBM zSeries 990 GA1"),
+    CPUDEF_INIT(0x2084, 8, 2, 38, 0x00000000U, "z990.2", "IBM zSeries 990 GA2"),
+    CPUDEF_INIT(0x2084, 8, 3, 38, 0x00000000U, "z990.3", "IBM zSeries 990 GA3"),
+    CPUDEF_INIT(0x2086, 8, 3, 38, 0x00000000U, "z890", "IBM zSeries 880 GA1"),
+    CPUDEF_INIT(0x2084, 8, 4, 38, 0x00000000U, "z990.4", "IBM zSeries 990 GA4"),
+    CPUDEF_INIT(0x2086, 8, 4, 38, 0x00000000U, "z890.2", "IBM zSeries 880 GA2"),
+    CPUDEF_INIT(0x2084, 8, 5, 38, 0x00000000U, "z990.5", "IBM zSeries 990 GA5"),
+    CPUDEF_INIT(0x2086, 8, 5, 38, 0x00000000U, "z890.3", "IBM zSeries 880 GA3"),
+    CPUDEF_INIT(0x2094, 9, 1, 40, 0x00000000U, "z9EC", "IBM System z9 EC GA1"),
+    CPUDEF_INIT(0x2094, 9, 2, 40, 0x00000000U, "z9EC.2", "IBM System z9 EC GA2"),
+    CPUDEF_INIT(0x2096, 9, 2, 40, 0x00000000U, "z9BC", "IBM System z9 BC GA1"),
+    CPUDEF_INIT(0x2094, 9, 3, 40, 0x00000000U, "z9EC.3", "IBM System z9 EC GA3"),
+    CPUDEF_INIT(0x2096, 9, 3, 40, 0x00000000U, "z9BC.2", "IBM System z9 BC GA2"),
+    CPUDEF_INIT(0x2097, 10, 1, 43, 0x00000000U, "z10EC", "IBM System z10 EC GA1"),
+    CPUDEF_INIT(0x2097, 10, 2, 43, 0x00000000U, "z10EC.2", "IBM System z10 EC GA2"),
+    CPUDEF_INIT(0x2098, 10, 2, 43, 0x00000000U, "z10BC", "IBM System z10 BC GA1"),
+    CPUDEF_INIT(0x2097, 10, 3, 43, 0x00000000U, "z10EC.3", "IBM System z10 EC GA3"),
+    CPUDEF_INIT(0x2098, 10, 3, 43, 0x00000000U, "z10BC.2", "IBM System z10 BC GA2"),
+    CPUDEF_INIT(0x2817, 11, 1, 44, 0x08000000U, "z196", "IBM zEnterprise 196 GA1"),
+    CPUDEF_INIT(0x2817, 11, 2, 44, 0x08000000U, "z196.2", "IBM zEnterprise 196 GA2"),
+    CPUDEF_INIT(0x2818, 11, 2, 44, 0x08000000U, "z114", "IBM zEnterprise 114 GA1"),
+    CPUDEF_INIT(0x2827, 12, 1, 44, 0x08000000U, "zEC12", "IBM zEnterprise EC12 GA1"),
+    CPUDEF_INIT(0x2827, 12, 2, 44, 0x08000000U, "zEC12.2", "IBM zEnterprise EC12 GA2"),
+    CPUDEF_INIT(0x2828, 12, 2, 44, 0x08000000U, "zBC12", "IBM zEnterprise BC12 GA1"),
+    CPUDEF_INIT(0x2964, 13, 1, 47, 0x08000000U, "z13", "IBM z13 GA1"),
+    CPUDEF_INIT(0x2964, 13, 2, 47, 0x08000000U, "z13.2", "IBM z13 GA2"),
+    CPUDEF_INIT(0x2965, 13, 2, 47, 0x08000000U, "z13s", "IBM z13s GA1"),
+};
+
 struct S390PrintCpuListInfo {
     FILE *f;
     fprintf_function print;
@@ -84,6 +139,10 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
     }
 }
 
+static void s390_cpu_model_initfn(Object *obj)
+{
+}
+
 #ifdef CONFIG_KVM
 static void s390_host_cpu_model_initfn(Object *obj)
 {
@@ -126,6 +185,25 @@ static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data)
 }
 #endif
 
+static void s390_base_cpu_model_class_init(ObjectClass *oc, void *data)
+{
+    S390CPUClass *xcc = S390_CPU_CLASS(oc);
+
+    /* all base models are migration safe */
+    xcc->cpu_def = (const S390CPUDef *) data;
+    xcc->migration_safe = true;
+    xcc->desc = xcc->cpu_def->desc;
+}
+
+static void s390_cpu_model_class_init(ObjectClass *oc, void *data)
+{
+    S390CPUClass *xcc = S390_CPU_CLASS(oc);
+
+    /* model that can change between QEMU versions */
+    xcc->cpu_def = (const S390CPUDef *) data;
+    xcc->desc = xcc->cpu_def->desc;
+}
+
 static void s390_qemu_cpu_model_class_init(ObjectClass *oc, void *data)
 {
     S390CPUClass *xcc = S390_CPU_CLASS(oc);
@@ -143,6 +221,12 @@ static char *s390_cpu_type_name(const char *model_name)
     return g_strdup_printf(S390_CPU_TYPE_NAME("%s"), model_name);
 }
 
+/* Generate type name for a base cpu model. Caller has to free the string. */
+static char *s390_base_cpu_type_name(const char *model_name)
+{
+    return g_strdup_printf(S390_CPU_TYPE_NAME("%s-base"), model_name);
+}
+
 ObjectClass *s390_cpu_class_by_name(const char *name)
 {
     char *typename = s390_cpu_type_name(name);
@@ -173,6 +257,33 @@ static const TypeInfo host_s390_cpu_type_info = {
 
 static void register_types(void)
 {
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) {
+        char *base_name = s390_base_cpu_type_name(s390_cpu_defs[i].name);
+        TypeInfo ti_base = {
+            .name = base_name,
+            .parent = TYPE_S390_CPU,
+            .instance_init = s390_cpu_model_initfn,
+            .instance_finalize = s390_cpu_model_finalize,
+            .class_init = s390_base_cpu_model_class_init,
+            .class_data = (void *) &s390_cpu_defs[i],
+        };
+        char *name = s390_cpu_type_name(s390_cpu_defs[i].name);
+       TypeInfo ti = {
+            .name = name,
+            .parent = TYPE_S390_CPU,
+            .instance_init = s390_cpu_model_initfn,
+            .instance_finalize = s390_cpu_model_finalize,
+            .class_init = s390_cpu_model_class_init,
+            .class_data = (void *) &s390_cpu_defs[i],
+        };
+
+        type_register_static(&ti_base);
+        type_register_static(&ti);
+        g_free(base_name);
+        g_free(name);
+    }
     type_register_static(&qemu_s390_cpu_type_info);
 #ifdef CONFIG_KVM
     type_register_static(&host_s390_cpu_type_info);
diff --git a/target-s390x/cpu_models.h b/target-s390x/cpu_models.h
new file mode 100644
index 0000000..13f7217
--- /dev/null
+++ b/target-s390x/cpu_models.h
@@ -0,0 +1,36 @@
+/*
+ * CPU models for s390x
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#ifndef TARGET_S390X_CPU_MODELS_H
+#define TARGET_S390X_CPU_MODELS_H
+
+#include "cpu_features.h"
+#include "qom/cpu.h"
+
+/* static CPU definition */
+typedef struct S390CPUDef {
+    const char *name;       /* name exposed to the user */
+    const char *desc;       /* description exposed to the user */
+    uint8_t gen;            /* hw generation identification */
+    uint16_t type;          /* cpu type identification */
+    uint8_t ec_ga;          /* EC GA version (on which also the BC is based) */
+    uint8_t mha_pow;        /* Maximum Host Adress Power, mha = 2^pow-1 */
+    uint32_t hmfai;         /* hypervisor-managed facilities */
+    /* base/min features, must never be changed between QEMU versions */
+    S390FeatBitmap base_feat;
+    /* deafault features, QEMU version specific */
+    S390FeatBitmap default_feat;
+    /* max allowed features, QEMU version specific */
+    S390FeatBitmap full_feat;
+} S390CPUDef;
+
+#endif /* TARGET_S390X_CPU_MODELS_H */
-- 
2.6.6

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

* [Qemu-devel] [RFC 08/28] s390x/cpumodel: store the CPU model in the CPU instance
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (6 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 07/28] s390x/cpumodel: register defined CPU models as subclasses David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 09/28] s390x/cpumodel: expose features and feature groups as properties David Hildenbrand
                   ` (21 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

A CPU model consists of a CPU definition, to which delta changes are
applied - features added or removed (e.g. z13-base,vx=on). In addition,
certain properties (e.g. cpu id) can later on change during migration
but belong into the CPU model. This data will later be filled from the
host model in the KVM case.

Therefore, store the configured CPU model inside the CPU instance, so
we can later on perform delta changes using properties.

For the "qemu" model, we emulate in TCG a z900. "host" will be
uninitialized (cpu->model == NULL) unless we have CPU model support in KVM
later on. The other models are all initialized from their definitions.
Only the "host" model can have a cpu->model == NULL.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/cpu.h        |  1 +
 target-s390x/cpu_models.c | 26 ++++++++++++++++++++++++++
 target-s390x/cpu_models.h | 10 ++++++++++
 3 files changed, 37 insertions(+)

diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 832da89..ec60b3b 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -187,6 +187,7 @@ struct S390CPU {
 
     CPUS390XState env;
     int64_t id;
+    S390CPUModel *model;
     /* needed for live migration */
     void *irqstate;
     uint32_t irqstate_saved_size;
diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index 50b395a..d54b795 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -141,6 +141,21 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
 
 static void s390_cpu_model_initfn(Object *obj)
 {
+    S390CPU *cpu = S390_CPU(obj);
+    S390CPUClass *xcc = S390_CPU_GET_CLASS(cpu);
+
+    cpu->model = g_malloc0(sizeof(*cpu->model));
+    /* copy the model, so we can modify it */
+    cpu->model->def = xcc->cpu_def;
+    if (xcc->migration_safe) {
+        /* base model - features will mever change */
+        bitmap_copy(cpu->model->features, cpu->model->def->base_feat,
+                    S390_FEAT_MAX);
+    } else {
+        /* latest model - features can change */
+        bitmap_copy(cpu->model->features,
+                    cpu->model->def->default_feat, S390_FEAT_MAX);
+    }
 }
 
 #ifdef CONFIG_KVM
@@ -151,10 +166,21 @@ static void s390_host_cpu_model_initfn(Object *obj)
 
 static void s390_qemu_cpu_model_initfn(Object *obj)
 {
+    S390CPU *cpu = S390_CPU(obj);
+
+    cpu->model = g_malloc0(sizeof(*cpu->model));
+    /* TCG emulates a z900 */
+    cpu->model->def = &s390_cpu_defs[0];
+    bitmap_copy(cpu->model->features, cpu->model->def->default_feat,
+                S390_FEAT_MAX);
 }
 
 static void s390_cpu_model_finalize(Object *obj)
 {
+    S390CPU *cpu = S390_CPU(obj);
+
+    g_free(cpu->model);
+    cpu->model = NULL;
 }
 
 static bool get_migratable(Object *obj, Error **errp)
diff --git a/target-s390x/cpu_models.h b/target-s390x/cpu_models.h
index 13f7217..244256b 100644
--- a/target-s390x/cpu_models.h
+++ b/target-s390x/cpu_models.h
@@ -33,4 +33,14 @@ typedef struct S390CPUDef {
     S390FeatBitmap full_feat;
 } S390CPUDef;
 
+/* CPU model based on a CPU definition */
+typedef struct S390CPUModel {
+    const S390CPUDef *def;
+    S390FeatBitmap features;
+    /* values copied from the "host" model, can change during migration */
+    uint16_t lowest_ibc;    /* lowest IBC that the hardware supports */
+    uint32_t cpu_id;        /* CPU id */
+    uint8_t cpu_ver;        /* CPU version, usually "ff" for kvm */
+} S390CPUModel;
+
 #endif /* TARGET_S390X_CPU_MODELS_H */
-- 
2.6.6

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

* [Qemu-devel] [RFC 09/28] s390x/cpumodel: expose features and feature groups as properties
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (7 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 08/28] s390x/cpumodel: store the CPU model in the CPU instance David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 10/28] s390x/cpumodel: let the CPU model handle feature checks David Hildenbrand
                   ` (20 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Let's add all features and feature groups as properties to all CPU models.
If the "host" CPU model is unknown, we can neither query nor change
features. KVM will just continue to work like it did until now.

We will not allow to enable features that were not part of the original
CPU model, because that could collide with the IBC in KVM.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/cpu.c        |   1 +
 target-s390x/cpu.h        |   1 +
 target-s390x/cpu_models.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 151 insertions(+)

diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index d7d0b62..2f3c8e2 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -291,6 +291,7 @@ static void s390_cpu_initfn(Object *obj)
     cs->exception_index = EXCP_HLT;
     object_property_add(OBJECT(cpu), "id", "int64_t", s390x_cpu_get_id,
                         s390x_cpu_set_id, NULL, NULL, NULL);
+    s390_cpu_model_register_props(obj);
 #if !defined(CONFIG_USER_ONLY)
     qemu_get_timedate(&tm, 0);
     env->tod_offset = TOD_UNIX_EPOCH +
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index ec60b3b..47a1861 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -633,6 +633,7 @@ extern void subsystem_reset(void);
 
 void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 #define cpu_list s390_cpu_list
+void s390_cpu_model_register_props(Object *obj);
 void s390_cpu_model_class_register_props(ObjectClass *oc);
 void s390_realize_cpu_model(CPUState *cs, Error **errp);
 ObjectClass *s390_cpu_class_by_name(const char *name);
diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index d54b795..93e63cb 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -14,6 +14,7 @@
 #include "cpu.h"
 #include "gen-features.h"
 #include "qapi/error.h"
+#include "qapi/visitor.h"
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/arch_init.h"
 #endif
@@ -96,8 +97,24 @@ void s390_cpu_list(FILE *f, fprintf_function print)
         f = f,
         print = print,
     };
+    S390FeatGroup group;
+    S390Feat feat;
 
     object_class_foreach(print_cpu_model_list, TYPE_S390_CPU, false, &info);
+
+    (*print)(f, "\nRecognized feature flags:\n");
+    for (feat = 0; feat < S390_FEAT_MAX; feat++) {
+        const S390FeatDef *def = s390_feat_def(feat);
+
+        (*print)(f, "%-20s %-50s\n", def->name, def->desc);
+    }
+
+    (*print)(f, "\nRecognized feature groups:\n");
+    for (group = 0; group < S390_FEAT_GROUP_MAX; group++) {
+        const S390FeatGroupDef *def = s390_feat_group_def(group);
+
+        (*print)(f, "%-20s %-50s\n", def->name, def->desc);
+    }
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -139,6 +156,138 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
     }
 }
 
+static void get_feature(Object *obj, Visitor *v, const char *name,
+                        void *opaque, Error **errp)
+{
+    S390Feat feat = (S390Feat) opaque;
+    S390CPU *cpu = S390_CPU(obj);
+    bool value;
+
+    if (!cpu->model) {
+        error_setg(errp, "Details about the host CPU model are not available, "
+                         "features cannot be queried.");
+        return;
+    }
+
+    value = test_bit(feat, cpu->model->features);
+    visit_type_bool(v, name, &value, errp);
+}
+
+static void set_feature(Object *obj, Visitor *v, const char *name,
+                        void *opaque, Error **errp)
+{
+    S390Feat feat = (S390Feat) opaque;
+    DeviceState *dev = DEVICE(obj);
+    S390CPU *cpu = S390_CPU(obj);
+    bool value;
+
+    if (dev->realized) {
+        error_setg(errp, "Attempt to set property '%s' on '%s' after "
+                   "it was realized", name, object_get_typename(obj));
+        return;
+    } else if (!cpu->model) {
+        error_setg(errp, "Details about the host CPU model are not available, "
+                         "features cannot be changed.");
+        return;
+    }
+
+    visit_type_bool(v, name, &value, errp);
+    if (*errp) {
+        return;
+    }
+    if (value) {
+        if (!test_bit(feat, cpu->model->def->full_feat)) {
+            error_setg(errp, "Feature '%s' is not available for CPU model '%s',"
+                       " it was introduced with later models.",
+                       name, cpu->model->def->name);
+            return;
+        }
+        set_bit(feat, cpu->model->features);
+    } else {
+        clear_bit(feat, cpu->model->features);
+    }
+}
+
+static void get_feature_group(Object *obj, Visitor *v, const char *name,
+                              void *opaque, Error **errp)
+{
+    S390FeatGroup group = (S390FeatGroup) opaque;
+    const S390FeatGroupDef *def = s390_feat_group_def(group);
+    S390CPU *cpu = S390_CPU(obj);
+    S390FeatBitmap tmp;
+    bool value;
+
+    if (!cpu->model) {
+        error_setg(errp, "Details about the host CPU model are not available, "
+                         "features cannot be queried.");
+        return;
+    }
+
+    /* a group is enabled if all features are enabled */
+    bitmap_and(tmp, cpu->model->features, def->feat, S390_FEAT_MAX);
+    value = bitmap_equal(tmp, def->feat, S390_FEAT_MAX);
+    visit_type_bool(v, name, &value, errp);
+}
+
+static void set_feature_group(Object *obj, Visitor *v, const char *name,
+                              void *opaque, Error **errp)
+{
+    S390FeatGroup group = (S390FeatGroup) opaque;
+    const S390FeatGroupDef *def = s390_feat_group_def(group);
+    DeviceState *dev = DEVICE(obj);
+    S390CPU *cpu = S390_CPU(obj);
+    bool value;
+
+    if (dev->realized) {
+        error_setg(errp, "Attempt to set property '%s' on '%s' after "
+                   "it was realized", name, object_get_typename(obj));
+        return;
+    } else if (!cpu->model) {
+        error_setg(errp, "Details about the host CPU model are not available, "
+                         "features cannot be changed.");
+        return;
+    }
+
+    visit_type_bool(v, name, &value, errp);
+    if (*errp) {
+        return;
+    }
+    if (value) {
+        /* groups are added in one shot, so an intersect is sufficient */
+        if (!bitmap_intersects(def->feat, cpu->model->def->full_feat,
+                               S390_FEAT_MAX)) {
+            error_setg(errp, "Group '%s' is not available for CPU model '%s',"
+                       " it was introduced with later models.",
+                       name, cpu->model->def->name);
+            return;
+        }
+        bitmap_or(cpu->model->features, cpu->model->features, def->feat,
+                  S390_FEAT_MAX);
+    } else {
+        bitmap_andnot(cpu->model->features, cpu->model->features, def->feat,
+                      S390_FEAT_MAX);
+    }
+}
+
+void s390_cpu_model_register_props(Object *obj)
+{
+    S390FeatGroup group;
+    S390Feat feat;
+
+    for (feat = 0; feat < S390_FEAT_MAX; feat++) {
+        const S390FeatDef *def = s390_feat_def(feat);
+        object_property_add(obj, def->name, "bool", get_feature,
+                            set_feature, NULL, (void *) feat, NULL);
+        object_property_set_description(obj, def->name, def->desc , NULL);
+    }
+    for (group = 0; group < S390_FEAT_GROUP_MAX; group++) {
+        const S390FeatGroupDef *def = s390_feat_group_def(group);
+        object_property_add(obj, def->name, "bool", get_feature_group,
+                            set_feature_group, NULL, (void *) group, NULL);
+        object_property_set_description(obj, def->name, def->desc , NULL);
+    }
+}
+
 static void s390_cpu_model_initfn(Object *obj)
 {
     S390CPU *cpu = S390_CPU(obj);
-- 
2.6.6

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

* [Qemu-devel] [RFC 10/28] s390x/cpumodel: let the CPU model handle feature checks
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (8 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 09/28] s390x/cpumodel: expose features and feature groups as properties David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 11/28] s390x/cpumodel: check and apply the CPU model David Hildenbrand
                   ` (19 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

If we have certain features enabled, we have to migrate additional state
(e.g. vector registers or runtime-instrumentation registers). Let the
CPU model control that unless we have no "host" CPU model in the KVM
case. This will later on be the case for compatibility machines, so
migration from QEMU versions without the CPU model will still work.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/cpu_models.c | 24 ++++++++++++++++++++++++
 target-s390x/cpu_models.h |  2 ++
 target-s390x/machine.c    | 14 ++------------
 3 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index 93e63cb..7e3f544 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -73,6 +73,30 @@ static const S390CPUDef s390_cpu_defs[] = {
     CPUDEF_INIT(0x2965, 13, 2, 47, 0x08000000U, "z13s", "IBM z13s GA1"),
 };
 
+bool s390_has_feat(S390Feat feat)
+{
+    static S390CPU *cpu;
+
+    if (!cpu) {
+        cpu = S390_CPU(qemu_get_cpu(0));
+    }
+
+    if (!cpu || !cpu->model) {
+#ifdef CONFIG_KVM
+        if (kvm_enabled()) {
+            if (feat == S390_FEAT_VECTOR) {
+                return kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS);
+            }
+            if (feat == S390_FEAT_RUNTIME_INSTRUMENTATION) {
+                return kvm_s390_get_ri();
+            }
+        }
+#endif
+        return 0;
+    }
+    return test_bit(feat, cpu->model->features);
+}
+
 struct S390PrintCpuListInfo {
     FILE *f;
     fprintf_function print;
diff --git a/target-s390x/cpu_models.h b/target-s390x/cpu_models.h
index 244256b..fe988cc 100644
--- a/target-s390x/cpu_models.h
+++ b/target-s390x/cpu_models.h
@@ -43,4 +43,6 @@ typedef struct S390CPUModel {
     uint8_t cpu_ver;        /* CPU version, usually "ff" for kvm */
 } S390CPUModel;
 
+bool s390_has_feat(S390Feat feat);
+
 #endif /* TARGET_S390X_CPU_MODELS_H */
diff --git a/target-s390x/machine.c b/target-s390x/machine.c
index aa39e5d..edc3a47 100644
--- a/target-s390x/machine.c
+++ b/target-s390x/machine.c
@@ -78,12 +78,7 @@ static const VMStateDescription vmstate_fpu = {
 
 static bool vregs_needed(void *opaque)
 {
-#ifdef CONFIG_KVM
-    if (kvm_enabled()) {
-        return kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS);
-    }
-#endif
-    return 0;
+    return s390_has_feat(S390_FEAT_VECTOR);
 }
 
 static const VMStateDescription vmstate_vregs = {
@@ -147,12 +142,7 @@ static const VMStateDescription vmstate_vregs = {
 
 static bool riccb_needed(void *opaque)
 {
-#ifdef CONFIG_KVM
-    if (kvm_enabled()) {
-        return kvm_s390_get_ri();
-    }
-#endif
-    return 0;
+    return s390_has_feat(S390_FEAT_RUNTIME_INSTRUMENTATION);
 }
 
 const VMStateDescription vmstate_riccb = {
-- 
2.6.6

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

* [Qemu-devel] [RFC 11/28] s390x/cpumodel: check and apply the CPU model
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (9 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 10/28] s390x/cpumodel: let the CPU model handle feature checks David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 12/28] s390x/sclp: factor out preparation of cpu entries David Hildenbrand
                   ` (18 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

We have to test if a configured CPU model is runnable in the current
configuration, and if not report why that is the case. This is done by
comparing it to the maximum supported model (host for KVM or z900 for TCG).
Also, we want to do some base sanity checking for a configured CPU model.

We'll cache the maximum model and the applied model (for performance
reasons and because KVM can only be configured before any VCPU is created).

For unavailable "host" model, we have to make sure that we inform KVM,
so it can do some compatibility stuff (enable CMMA later on to be precise).

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/cpu_models.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 154 insertions(+)

diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index 7e3f544..e7bcea9 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -15,6 +15,7 @@
 #include "gen-features.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
+#include "qemu/error-report.h"
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/arch_init.h"
 #endif
@@ -170,14 +171,167 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
 }
 #endif
 
+static void check_consistency(const S390CPUModel *model)
+{
+    static int dep[][2] = {
+        { S390_FEAT_IPTE_RANGE, S390_FEAT_DAT_ENH_1 },
+        { S390_FEAT_IDTE_SEGMENT, S390_FEAT_DAT_ENH_1 },
+        { S390_FEAT_IDTE_REGION, S390_FEAT_DAT_ENH_1 },
+        { S390_FEAT_IDTE_REGION, S390_FEAT_IDTE_SEGMENT },
+        { S390_FEAT_LOCAL_TLB_CLEARING, S390_FEAT_DAT_ENH_1},
+        { S390_FEAT_LONG_DISPLACEMENT_FAST, S390_FEAT_LONG_DISPLACEMENT },
+        { S390_FEAT_DFP_FAST, S390_FEAT_DFP },
+        { S390_FEAT_TRANSACTIONAL_EXE, S390_FEAT_GEN12_ENH },
+        { S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE, S390_FEAT_TRANSACTIONAL_EXE },
+        { S390_FEAT_EDAT_2, S390_FEAT_EDAT_1},
+        { S390_FEAT_MSA_EXT_5, S390_FEAT_KIMD_SHA_512 },
+        { S390_FEAT_MSA_EXT_5, S390_FEAT_KLMD_SHA_512 },
+        { S390_FEAT_MSA_EXT_4, S390_FEAT_MSA_EXT_3 },
+        { S390_FEAT_SIE_CMMA, S390_FEAT_CMM },
+        { S390_FEAT_SIE_CMMA, S390_FEAT_SIE_GSLS },
+        { S390_FEAT_SIE_PFMFI, S390_FEAT_EDAT_1 },
+    };
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(dep); i++) {
+        if (test_bit(dep[i][0], model->features) &&
+            !test_bit(dep[i][1], model->features)) {
+            error_report("Warning: \'%s\' requires \'%s\'.",
+                         s390_feat_def(dep[i][0])->name,
+                         s390_feat_def(dep[i][1])->name);
+        }
+    }
+}
+
+static void error_prepend_missing_feat(const char *name, void *opaque)
+{
+    error_prepend((Error **) opaque, "%s ", name);
+}
+
+static void check_compatibility(const S390CPUModel *max_model,
+                                const S390CPUModel *model, Error **errp)
+{
+    S390FeatBitmap missing;
+
+    if (model->def->gen > max_model->def->gen) {
+        error_setg(errp, "Selected CPU generation is too new. Maximum "
+                   "supported model in the configuration: \'%s\'",
+                   max_model->def->name);
+        return;
+    } else if (model->def->gen == max_model->def->gen &&
+               model->def->ec_ga > max_model->def->ec_ga) {
+        error_setg(errp, "Selected CPU GA level is too new. Maximum "
+                   "supported model in the configuration: \'%s\'",
+                   max_model->def->name);
+        return;
+    }
+
+    /* detect the missing features to properly report them */
+    bitmap_andnot(missing, model->features, max_model->features, S390_FEAT_MAX);
+    if (bitmap_empty(missing, S390_FEAT_MAX)) {
+        return;
+    }
+
+    error_setg(errp, " ");
+    s390_feat_bitmap_to_ascii(missing, errp, error_prepend_missing_feat);
+    error_prepend(errp, "Some features requested in the CPU model are not "
+                  "available in the configuration: ");
+}
+
+static S390CPUModel *get_max_cpu_model(Error **errp)
+{
+#ifndef CONFIG_USER_ONLY
+    static S390CPUModel max_model;
+    static bool cached;
+
+    if (cached) {
+        return &max_model;
+    }
+
+    if (kvm_enabled()) {
+        error_setg(errp, "KVM does not support CPU models.");
+    } else {
+        /* TCG enulates a z900 */
+        max_model.def = &s390_cpu_defs[0];
+        bitmap_copy(max_model.features, max_model.def->default_feat,
+                    S390_FEAT_MAX);
+    }
+    if (!*errp) {
+        cached = true;
+        return &max_model;
+    }
+#endif
+    return NULL;
+}
+
+static inline void apply_cpu_model(const S390CPUModel *model, Error **errp)
+{
+#ifndef CONFIG_USER_ONLY
+    static S390CPUModel applied_model;
+    static bool applied;
+
+    /*
+     * We have the same model for all VCPUs. KVM can only be configured before
+     * any VCPUs are defined in KVM.
+     */
+    if (applied) {
+        if (model && memcmp(&applied_model, model, sizeof(S390CPUModel))) {
+            error_setg(errp, "Mixed CPU models are not supported on s390x.");
+        }
+        return;
+    }
+
+    if (kvm_enabled()) {
+        /* FIXME KVM */
+        error_setg(errp, "KVM doesn't support CPU models.");
+    } else if (model) {
+        /* FIXME TCG - use data for stdip/stfl */
+    }
+
+    if (!*errp) {
+        applied = true;
+        if (model) {
+            applied_model = *model;
+        }
+    }
+#endif
+}
+
 void s390_realize_cpu_model(CPUState *cs, Error **errp)
 {
     S390CPUClass *xcc = S390_CPU_GET_CLASS(cs);
+    S390CPU *cpu = S390_CPU(cs);
+    const S390CPUModel *max_model;
 
     if (xcc->kvm_required && !kvm_enabled()) {
         error_setg(errp, "CPU definition requires KVM");
         return;
     }
+
+    if (!cpu->model) {
+        /* no host model support -> perform compatibility stuff */
+        apply_cpu_model(NULL, errp);
+        return;
+    }
+
+    max_model = get_max_cpu_model(errp);
+    if (*errp) {
+        error_prepend(errp, "CPU models are not available: ");
+        return;
+    }
+
+    /* copy over properties that can vary */
+    cpu->model->lowest_ibc = max_model->lowest_ibc;
+    cpu->model->cpu_id = max_model->cpu_id;
+    cpu->model->cpu_ver = max_model->cpu_ver;
+
+    check_consistency(cpu->model);
+    check_compatibility(max_model, cpu->model, errp);
+    if (*errp) {
+        return;
+    }
+
+    apply_cpu_model(cpu->model, errp);
 }
 
 static void get_feature(Object *obj, Visitor *v, const char *name,
-- 
2.6.6

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

* [Qemu-devel] [RFC 12/28] s390x/sclp: factor out preparation of cpu entries
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (10 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 11/28] s390x/cpumodel: check and apply the CPU model David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 13/28] s390x/sclp: introduce sclp feature blocks David Hildenbrand
                   ` (17 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Let's factor out the common code of "read cpu info" and "read scp
info". This will make the introduction of new cpu entry fields easier.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 hw/s390x/sclp.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index fca37f5..15d7114 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -29,6 +29,16 @@ static inline SCLPDevice *get_sclp_device(void)
     return SCLP(object_resolve_path_type("", TYPE_SCLP, NULL));
 }
 
+static void prepare_cpu_entries(SCLPDevice *sclp, CPUEntry *entry, int count)
+{
+    int i;
+
+    for (i = 0; i < count; i++) {
+        entry[i].address = i;
+        entry[i].type = 0;
+    }
+}
+
 /* Provide information about the configuration, CPUs and storage */
 static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 {
@@ -37,7 +47,6 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
     sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
     CPUState *cpu;
     int cpu_count = 0;
-    int i = 0;
     int rnsize, rnmax;
     int slots = MIN(machine->ram_slots, s390_get_memslot_count(kvm_state));
 
@@ -50,10 +59,7 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
     read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
     read_info->highest_cpu = cpu_to_be16(max_cpus);
 
-    for (i = 0; i < cpu_count; i++) {
-        read_info->entries[i].address = i;
-        read_info->entries[i].type = 0;
-    }
+    prepare_cpu_entries(sclp, read_info->entries, cpu_count);
 
     read_info->facilities = cpu_to_be64(SCLP_HAS_CPU_INFO |
                                         SCLP_HAS_PCI_RECONFIG);
@@ -304,7 +310,6 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
     ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
     CPUState *cpu;
     int cpu_count = 0;
-    int i = 0;
 
     CPU_FOREACH(cpu) {
         cpu_count++;
@@ -318,10 +323,7 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
     cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured
         + cpu_info->nr_configured*sizeof(CPUEntry));
 
-    for (i = 0; i < cpu_count; i++) {
-        cpu_info->entries[i].address = i;
-        cpu_info->entries[i].type = 0;
-    }
+    prepare_cpu_entries(sclp, cpu_info->entries, cpu_count);
 
     sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
 }
-- 
2.6.6

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

* [Qemu-devel] [RFC 13/28] s390x/sclp: introduce sclp feature blocks
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (11 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 12/28] s390x/sclp: factor out preparation of cpu entries David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 14/28] s390x/sclp: indicate sclp features David Hildenbrand
                   ` (16 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

The sclp "read cpu info" and "read scp info" commands can include
features for the cpu info and configuration characteristics (extended),
decribing some advanced features available in the configuration.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 include/hw/s390x/sclp.h | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
index b0c71b5..743abd4 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -97,11 +97,14 @@ typedef struct SCCBHeader {
 } QEMU_PACKED SCCBHeader;
 
 #define SCCB_DATA_LEN (SCCB_SIZE - sizeof(SCCBHeader))
+#define SCCB_CPU_FEATURE_LEN 6
 
 /* CPU information */
 typedef struct CPUEntry {
     uint8_t address;
-    uint8_t reserved0[13];
+    uint8_t reserved0;
+    uint8_t features[SCCB_CPU_FEATURE_LEN];
+    uint8_t reserved2[6];
     uint8_t type;
     uint8_t reserved1;
 } QEMU_PACKED CPUEntry;
@@ -117,10 +120,13 @@ typedef struct ReadInfo {
     uint8_t  loadparm[8];               /* 24-31 */
     uint8_t  _reserved3[48 - 32];       /* 32-47 */
     uint64_t facilities;                /* 48-55 */
-    uint8_t  _reserved0[100 - 56];
+    uint8_t  _reserved0[80 - 56];       /* 56-79 */
+    uint8_t  conf_char[96 - 80];        /* 80-95 */
+    uint8_t  _reserved4[100 - 96];      /* 96-99 */
     uint32_t rnsize2;
     uint64_t rnmax2;
-    uint8_t  _reserved4[120-112];       /* 112-119 */
+    uint8_t  _reserved6[116 - 112];     /* 112-115 */
+    uint8_t  conf_char_ext[120 - 116];   /* 116-119 */
     uint16_t highest_cpu;
     uint8_t  _reserved5[128 - 122];     /* 122-127 */
     struct CPUEntry entries[0];
-- 
2.6.6

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

* [Qemu-devel] [RFC 14/28] s390x/sclp: indicate sclp features
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (12 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 13/28] s390x/sclp: introduce sclp feature blocks David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 15/28] s390x/sclp: propagate the ibc val(lowest and unblocked ibc) David Hildenbrand
                   ` (15 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

We have three different blocks in the SCLP read-SCP information response
that indicate sclp features. Let's prepare propagation.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 hw/s390x/sclp.c           |  9 +++++++++
 target-s390x/cpu_models.c | 14 ++++++++++++++
 target-s390x/cpu_models.h |  1 +
 3 files changed, 24 insertions(+)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 15d7114..3c126ee 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -31,11 +31,14 @@ static inline SCLPDevice *get_sclp_device(void)
 
 static void prepare_cpu_entries(SCLPDevice *sclp, CPUEntry *entry, int count)
 {
+    uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
     int i;
 
+    s390_get_feat_block(S390_FEAT_TYPE_SCLP_CPU, features);
     for (i = 0; i < count; i++) {
         entry[i].address = i;
         entry[i].type = 0;
+        memcpy(entry[i].features, features, sizeof(entry[i].features));
     }
 }
 
@@ -59,6 +62,12 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
     read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
     read_info->highest_cpu = cpu_to_be16(max_cpus);
 
+    /* Configuration Characteristic (Extension) */
+    s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR,
+                         read_info->conf_char);
+    s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
+                         read_info->conf_char_ext);
+
     prepare_cpu_entries(sclp, read_info->entries, cpu_count);
 
     read_info->facilities = cpu_to_be64(SCLP_HAS_CPU_INFO |
diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index e7bcea9..571ceaa 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -74,6 +74,20 @@ static const S390CPUDef s390_cpu_defs[] = {
     CPUDEF_INIT(0x2965, 13, 2, 47, 0x08000000U, "z13s", "IBM z13s GA1"),
 };
 
+void s390_get_feat_block(S390FeatType type, uint8_t *data)
+{
+    static S390CPU *cpu;
+
+    if (!cpu) {
+        cpu = S390_CPU(qemu_get_cpu(0));
+    }
+
+    if (!cpu || !cpu->model) {
+        return;
+    }
+    return s390_fill_feat_block(cpu->model->features, type, data);
+}
+
 bool s390_has_feat(S390Feat feat)
 {
     static S390CPU *cpu;
diff --git a/target-s390x/cpu_models.h b/target-s390x/cpu_models.h
index fe988cc..04c47c6 100644
--- a/target-s390x/cpu_models.h
+++ b/target-s390x/cpu_models.h
@@ -43,6 +43,7 @@ typedef struct S390CPUModel {
     uint8_t cpu_ver;        /* CPU version, usually "ff" for kvm */
 } S390CPUModel;
 
+void s390_get_feat_block(S390FeatType type, uint8_t *data);
 bool s390_has_feat(S390Feat feat);
 
 #endif /* TARGET_S390X_CPU_MODELS_H */
-- 
2.6.6

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

* [Qemu-devel] [RFC 15/28] s390x/sclp: propagate the ibc val(lowest and unblocked ibc)
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (13 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 14/28] s390x/sclp: indicate sclp features David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 16/28] s390x/sclp: propagate the mha via sclp David Hildenbrand
                   ` (14 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

If we have a lowest ibc, we can indicate the ibc to the guest.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 hw/s390x/sclp.c           |  2 ++
 include/hw/s390x/sclp.h   |  3 ++-
 target-s390x/cpu_models.c | 21 +++++++++++++++++++++
 target-s390x/cpu_models.h | 12 ++++++++++++
 4 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 3c126ee..52f8bb9 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -62,6 +62,8 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
     read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
     read_info->highest_cpu = cpu_to_be16(max_cpus);
 
+    read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
+
     /* Configuration Characteristic (Extension) */
     s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR,
                          read_info->conf_char);
diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
index 743abd4..4580134 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -120,7 +120,8 @@ typedef struct ReadInfo {
     uint8_t  loadparm[8];               /* 24-31 */
     uint8_t  _reserved3[48 - 32];       /* 32-47 */
     uint64_t facilities;                /* 48-55 */
-    uint8_t  _reserved0[80 - 56];       /* 56-79 */
+    uint8_t  _reserved0[76 - 56];       /* 56-75 */
+    uint32_t ibc_val;
     uint8_t  conf_char[96 - 80];        /* 80-95 */
     uint8_t  _reserved4[100 - 96];      /* 96-99 */
     uint32_t rnsize2;
diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index 571ceaa..d58b931 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -74,6 +74,27 @@ static const S390CPUDef s390_cpu_defs[] = {
     CPUDEF_INIT(0x2965, 13, 2, 47, 0x08000000U, "z13s", "IBM z13s GA1"),
 };
 
+uint32_t s390_get_ibc_val(void)
+{
+    uint16_t unblocked_ibc, lowest_ibc;
+    static S390CPU *cpu;
+
+    if (!cpu) {
+        cpu = S390_CPU(qemu_get_cpu(0));
+    }
+
+    if (!cpu || !cpu->model) {
+        return 0;
+    }
+    unblocked_ibc = s390_ibc_from_cpu_model(cpu->model);
+    lowest_ibc = cpu->model->lowest_ibc;
+    /* the lowest_ibc always has to be <= unblocked_ibc */
+    if (!lowest_ibc || lowest_ibc > unblocked_ibc) {
+        return 0;
+    }
+    return ((uint32_t) lowest_ibc << 16) | unblocked_ibc;
+}
+
 void s390_get_feat_block(S390FeatType type, uint8_t *data)
 {
     static S390CPU *cpu;
diff --git a/target-s390x/cpu_models.h b/target-s390x/cpu_models.h
index 04c47c6..bbb85ac 100644
--- a/target-s390x/cpu_models.h
+++ b/target-s390x/cpu_models.h
@@ -43,6 +43,18 @@ typedef struct S390CPUModel {
     uint8_t cpu_ver;        /* CPU version, usually "ff" for kvm */
 } S390CPUModel;
 
+#define S390_GEN_Z10 0xa
+
+uint32_t s390_get_ibc_val(void);
+static inline uint16_t s390_ibc_from_cpu_model(const S390CPUModel *model)
+{
+    uint16_t ibc = 0;
+
+    if (model->def->gen >= S390_GEN_Z10) {
+        ibc = ((model->def->gen - S390_GEN_Z10) << 4) + model->def->ec_ga;
+    }
+    return ibc;
+}
 void s390_get_feat_block(S390FeatType type, uint8_t *data);
 bool s390_has_feat(S390Feat feat);
 
-- 
2.6.6

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

* [Qemu-devel] [RFC 16/28] s390x/sclp: propagate the mha via sclp
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (14 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 15/28] s390x/sclp: propagate the ibc val(lowest and unblocked ibc) David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 17/28] s390x/sclp: propagate hmfai David Hildenbrand
                   ` (13 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

The mha is provided in the CPU model, so get any CPU and extract the value.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 hw/s390x/sclp.c           |  1 +
 include/hw/s390x/sclp.h   |  3 ++-
 target-s390x/cpu_models.c | 14 ++++++++++++++
 target-s390x/cpu_models.h |  1 +
 4 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 52f8bb9..5ffcf51 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -105,6 +105,7 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 
         read_info->facilities |= cpu_to_be64(SCLP_FC_ASSIGN_ATTACH_READ_STOR);
     }
+    read_info->mha_pow = s390_get_mha_pow();
 
     rnsize = 1 << (sclp->increment_size - 20);
     if (rnsize <= 128) {
diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
index 4580134..7a610cd 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -123,7 +123,8 @@ typedef struct ReadInfo {
     uint8_t  _reserved0[76 - 56];       /* 56-75 */
     uint32_t ibc_val;
     uint8_t  conf_char[96 - 80];        /* 80-95 */
-    uint8_t  _reserved4[100 - 96];      /* 96-99 */
+    uint8_t  _reserved4[99 - 96];       /* 96-98 */
+    uint8_t mha_pow;
     uint32_t rnsize2;
     uint64_t rnmax2;
     uint8_t  _reserved6[116 - 112];     /* 112-115 */
diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index d58b931..edfbb60 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -74,6 +74,20 @@ static const S390CPUDef s390_cpu_defs[] = {
     CPUDEF_INIT(0x2965, 13, 2, 47, 0x08000000U, "z13s", "IBM z13s GA1"),
 };
 
+uint8_t s390_get_mha_pow(void)
+{
+    static S390CPU *cpu;
+
+    if (!cpu) {
+        cpu = S390_CPU(qemu_get_cpu(0));
+    }
+
+    if (!cpu || !cpu->model) {
+        return 0;
+    }
+    return cpu->model->def->mha_pow;
+}
+
 uint32_t s390_get_ibc_val(void)
 {
     uint16_t unblocked_ibc, lowest_ibc;
diff --git a/target-s390x/cpu_models.h b/target-s390x/cpu_models.h
index bbb85ac..ee019b4 100644
--- a/target-s390x/cpu_models.h
+++ b/target-s390x/cpu_models.h
@@ -45,6 +45,7 @@ typedef struct S390CPUModel {
 
 #define S390_GEN_Z10 0xa
 
+uint8_t s390_get_mha_pow(void);
 uint32_t s390_get_ibc_val(void);
 static inline uint16_t s390_ibc_from_cpu_model(const S390CPUModel *model)
 {
-- 
2.6.6

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

* [Qemu-devel] [RFC 17/28] s390x/sclp: propagate hmfai
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (15 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 16/28] s390x/sclp: propagate the mha via sclp David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 18/28] update linux headers (CPU model) David Hildenbrand
                   ` (12 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

hmfai is provided on CPU models >= z196. Let's propagate it properly.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 hw/s390x/sclp.c           |  1 +
 include/hw/s390x/sclp.h   |  3 ++-
 target-s390x/cpu_models.c | 14 ++++++++++++++
 target-s390x/cpu_models.h |  1 +
 4 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 5ffcf51..883592c 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -106,6 +106,7 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
         read_info->facilities |= cpu_to_be64(SCLP_FC_ASSIGN_ATTACH_READ_STOR);
     }
     read_info->mha_pow = s390_get_mha_pow();
+    read_info->hmfai = cpu_to_be32(s390_get_hmfai());
 
     rnsize = 1 << (sclp->increment_size - 20);
     if (rnsize <= 128) {
diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
index 7a610cd..004cb13 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -130,7 +130,8 @@ typedef struct ReadInfo {
     uint8_t  _reserved6[116 - 112];     /* 112-115 */
     uint8_t  conf_char_ext[120 - 116];   /* 116-119 */
     uint16_t highest_cpu;
-    uint8_t  _reserved5[128 - 122];     /* 122-127 */
+    uint8_t  _reserved5[124 - 122];     /* 122-123 */
+    uint32_t hmfai;
     struct CPUEntry entries[0];
 } QEMU_PACKED ReadInfo;
 
diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index edfbb60..32d9a09 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -74,6 +74,20 @@ static const S390CPUDef s390_cpu_defs[] = {
     CPUDEF_INIT(0x2965, 13, 2, 47, 0x08000000U, "z13s", "IBM z13s GA1"),
 };
 
+uint32_t s390_get_hmfai(void)
+{
+    static S390CPU *cpu;
+
+    if (!cpu) {
+        cpu = S390_CPU(qemu_get_cpu(0));
+    }
+
+    if (!cpu || !cpu->model) {
+        return 0;
+    }
+    return cpu->model->def->hmfai;
+}
+
 uint8_t s390_get_mha_pow(void)
 {
     static S390CPU *cpu;
diff --git a/target-s390x/cpu_models.h b/target-s390x/cpu_models.h
index ee019b4..986f7cb 100644
--- a/target-s390x/cpu_models.h
+++ b/target-s390x/cpu_models.h
@@ -45,6 +45,7 @@ typedef struct S390CPUModel {
 
 #define S390_GEN_Z10 0xa
 
+uint32_t s390_get_hmfai(void);
 uint8_t s390_get_mha_pow(void);
 uint32_t s390_get_ibc_val(void);
 static inline uint16_t s390_ibc_from_cpu_model(const S390CPUModel *model)
-- 
2.6.6

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

* [Qemu-devel] [RFC 18/28] update linux headers (CPU model)
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (16 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 17/28] s390x/sclp: propagate hmfai David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 19/28] s390x/kvm: allow runtime-instrumentation for "none" machine David Hildenbrand
                   ` (11 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Update linux headers to include the new cpu model attributes

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 linux-headers/asm-s390/kvm.h | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
index 09ae5dc..dd4f22e 100644
--- a/linux-headers/asm-s390/kvm.h
+++ b/linux-headers/asm-s390/kvm.h
@@ -93,6 +93,46 @@ struct kvm_s390_vm_cpu_machine {
 	__u64 fac_list[256];
 };
 
+#define KVM_S390_VM_CPU_PROCESSOR_FEAT	2
+#define KVM_S390_VM_CPU_MACHINE_FEAT	3
+
+#define KVM_S390_VM_CPU_FEAT_NR_BITS	1024
+#define KVM_S390_VM_CPU_FEAT_ESOP	0
+#define KVM_S390_VM_CPU_FEAT_SIEF2	1
+#define KVM_S390_VM_CPU_FEAT_64BSCAO	2
+#define KVM_S390_VM_CPU_FEAT_SIIF	3
+#define KVM_S390_VM_CPU_FEAT_GPERE	4
+#define KVM_S390_VM_CPU_FEAT_GSLS	5
+#define KVM_S390_VM_CPU_FEAT_IB		6
+#define KVM_S390_VM_CPU_FEAT_CEI	7
+#define KVM_S390_VM_CPU_FEAT_IBS	8
+#define KVM_S390_VM_CPU_FEAT_SKEY	9
+#define KVM_S390_VM_CPU_FEAT_CMMA	10
+#define KVM_S390_VM_CPU_FEAT_PFMFI	11
+#define KVM_S390_VM_CPU_FEAT_SIGPIF	12
+struct kvm_s390_vm_cpu_feat {
+	__u64 feat[16];
+};
+
+#define KVM_S390_VM_CPU_PROCESSOR_SUBFUNC	4
+#define KVM_S390_VM_CPU_MACHINE_SUBFUNC		5
+struct kvm_s390_vm_cpu_subfunc {
+	__u8 plo[32];		/* always */
+	__u8 ptff[16];		/* with TOD-clock steering */
+	__u8 kmac[16];		/* with MSA */
+	__u8 kmc[16];		/* with MSA */
+	__u8 km[16];		/* with MSA */
+	__u8 kimd[16];		/* with MSA */
+	__u8 klmd[16];		/* with MSA */
+	__u8 pckmo[16];		/* with MSA3 */
+	__u8 kmctr[16];		/* with MSA4 */
+	__u8 kmf[16];		/* with MSA4 */
+	__u8 kmo[16];		/* with MSA4 */
+	__u8 pcc[16];		/* with MSA4 */
+	__u8 ppno[16];		/* with MSA5 */
+	__u8 reserved[1824];
+};
+
 /* kvm attributes for crypto */
 #define KVM_S390_VM_CRYPTO_ENABLE_AES_KW	0
 #define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW	1
-- 
2.6.6

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

* [Qemu-devel] [RFC 19/28] s390x/kvm: allow runtime-instrumentation for "none" machine
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (17 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 18/28] update linux headers (CPU model) David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 20/28] s390x/kvm: implement CPU model support David Hildenbrand
                   ` (10 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

To be able to query the correct host model for the "none" machine,
let's allow runtime-instrumentation for that machine.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 hw/s390x/s390-virtio-ccw.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 52f079a..704b5b5 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -248,6 +248,11 @@ bool ri_allowed(void)
 
             return s390mc->ri_allowed;
         }
+        /*
+         * Make sure the "none" machine can have ri, otherwise it won't * be
+         * unlocked in KVM and therefore the host CPU model might be wrong.
+         */
+        return true;
     }
     return 0;
 }
-- 
2.6.6

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

* [Qemu-devel] [RFC 20/28] s390x/kvm: implement CPU model support
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (18 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 19/28] s390x/kvm: allow runtime-instrumentation for "none" machine David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 21/28] s390x/kvm: disable host model for existing compat machines David Hildenbrand
                   ` (9 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Let's implement our two hooks so we can support CPU models.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/cpu_models.c |  75 +++++++++++-
 target-s390x/cpu_models.h |  50 ++++++++
 target-s390x/kvm.c        | 295 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 417 insertions(+), 3 deletions(-)

diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index 32d9a09..b8ae601 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -161,6 +161,61 @@ bool s390_has_feat(S390Feat feat)
     return test_bit(feat, cpu->model->features);
 }
 
+uint8_t s390_get_gen_for_cpu_type(uint16_t type)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) {
+        if (s390_cpu_defs[i].type == type) {
+            return s390_cpu_defs[i].gen;
+        }
+    }
+    return 0;
+}
+
+const S390CPUDef *s390_find_cpu_def(uint16_t type, uint8_t gen, uint8_t ec_ga,
+                                    S390FeatBitmap features)
+{
+    const S390CPUDef *last_compatible = NULL;
+    int i;
+
+    if (!gen) {
+        ec_ga = 0;
+    }
+    if (!gen && type) {
+        gen = s390_get_gen_for_cpu_type(type);
+    }
+
+    for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) {
+        const S390CPUDef *def = &s390_cpu_defs[i];
+        S390FeatBitmap missing;
+
+        /* don't even try newer generations if we know the generation */
+        if (gen) {
+            if (def->gen > gen) {
+                break;
+            } else if (def->gen == gen && ec_ga && def->ec_ga > ec_ga) {
+                break;
+            }
+        }
+
+        if (features) {
+            /* see if the model satisfies the minimum features */
+            bitmap_andnot(missing, def->base_feat, features, S390_FEAT_MAX);
+            if (!bitmap_empty(missing, S390_FEAT_MAX)) {
+                break;
+            }
+        }
+
+        /* stop the search if we found the exact model */
+        if (def->type == type && def->ec_ga == ec_ga) {
+            return def;
+        }
+        last_compatible = def;
+    }
+    return last_compatible;
+}
+
 struct S390PrintCpuListInfo {
     FILE *f;
     fprintf_function print;
@@ -312,7 +367,7 @@ static S390CPUModel *get_max_cpu_model(Error **errp)
     }
 
     if (kvm_enabled()) {
-        error_setg(errp, "KVM does not support CPU models.");
+        kvm_s390_get_host_cpu_model(&max_model, errp);
     } else {
         /* TCG enulates a z900 */
         max_model.def = &s390_cpu_defs[0];
@@ -345,8 +400,7 @@ static inline void apply_cpu_model(const S390CPUModel *model, Error **errp)
     }
 
     if (kvm_enabled()) {
-        /* FIXME KVM */
-        error_setg(errp, "KVM doesn't support CPU models.");
+        kvm_s390_apply_cpu_model(model, errp);
     } else if (model) {
         /* FIXME TCG - use data for stdip/stfl */
     }
@@ -551,6 +605,21 @@ static void s390_cpu_model_initfn(Object *obj)
 #ifdef CONFIG_KVM
 static void s390_host_cpu_model_initfn(Object *obj)
 {
+    S390CPU *cpu = S390_CPU(obj);
+    Error *err = NULL;
+
+    if (!kvm_enabled() || !kvm_s390_cpu_models_supported()) {
+        return;
+    }
+
+    cpu->model = g_malloc0(sizeof(*cpu->model));
+    kvm_s390_get_host_cpu_model(cpu->model, &err);
+    if (err) {
+        error_report_err(err);
+        g_free(cpu->model);
+        /* fallback to unsupported cpu models */
+        cpu->model = NULL;
+    }
 }
 #endif
 
diff --git a/target-s390x/cpu_models.h b/target-s390x/cpu_models.h
index 986f7cb..a1ee3d6 100644
--- a/target-s390x/cpu_models.h
+++ b/target-s390x/cpu_models.h
@@ -43,7 +43,25 @@ typedef struct S390CPUModel {
     uint8_t cpu_ver;        /* CPU version, usually "ff" for kvm */
 } S390CPUModel;
 
+/*
+ * CPU ID
+ *
+ * bits 0-7: Zeroes (ff for kvm)
+ * bits 8-31: CPU ID (serial number)
+ * bits 32-48: Machine type
+ * bits 48-63: Zeroes
+ */
+#define cpuid_type(x)     (((x) >> 16) & 0xffff)
+#define cpuid_id(x)       (((x) >> 32) & 0xffffff)
+#define cpuid_ver(x)      (((x) >> 56) & 0xff)
+
+#define lowest_ibc(x)     (((uint32_t)(x) >> 16) & 0xfff)
+#define unblocked_ibc(x)  ((uint32_t)(x) & 0xfff)
+#define has_ibc(x)        (lowest_ibc(x) != 0)
+
 #define S390_GEN_Z10 0xa
+#define ibc_gen(x)        (x == 0 ? 0 : ((x >> 4) + S390_GEN_Z10))
+#define ibc_ec_ga(x)      (x & 0xf)
 
 uint32_t s390_get_hmfai(void);
 uint8_t s390_get_mha_pow(void);
@@ -59,5 +77,37 @@ static inline uint16_t s390_ibc_from_cpu_model(const S390CPUModel *model)
 }
 void s390_get_feat_block(S390FeatType type, uint8_t *data);
 bool s390_has_feat(S390Feat feat);
+uint8_t s390_get_gen_for_cpu_type(uint16_t type);
+static inline bool s390_known_cpu_type(uint16_t type)
+{
+    return s390_get_gen_for_cpu_type(type) != 0;
+}
+static inline uint64_t s390_cpuid_from_cpu_model(const S390CPUModel *model)
+{
+    return ((uint64_t)model->cpu_ver << 56) |
+           ((uint64_t)model->cpu_id << 32) |
+           ((uint64_t)model->def->type << 16);
+}
+S390CPUDef const *s390_find_cpu_def(uint16_t type, uint8_t gen, uint8_t ec_ga,
+                                    S390FeatBitmap features);
+
+#ifdef CONFIG_KVM
+bool kvm_s390_cpu_models_supported(void);
+void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp);
+void kvm_s390_apply_cpu_model(const S390CPUModel *model,  Error **errp);
+#else
+static inline void kvm_s390_get_host_cpu_model(S390CPUModel *model,
+                                               Error **errp)
+{
+}
+static inline void kvm_s390_apply_cpu_model(const S390CPUModel *model,
+                                            Error **errp)
+{
+}
+static inline bool kvm_s390_cpu_models_supported(void)
+{
+    return false;
+}
+#endif
 
 #endif /* TARGET_S390X_CPU_MODELS_H */
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 45e94ca..6002cf9 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -2271,3 +2271,298 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
 {
     abort();
 }
+
+static inline int test_bit_inv(long nr, const unsigned long *addr)
+{
+    return test_bit(BE_BIT_NR(nr), addr);
+}
+
+static inline void set_bit_inv(long nr, unsigned long *addr)
+{
+    set_bit(BE_BIT_NR(nr), addr);
+}
+
+static int query_cpu_subfunc(S390FeatBitmap features)
+{
+    struct kvm_s390_vm_cpu_subfunc prop;
+    struct kvm_device_attr attr = {
+        .group = KVM_S390_VM_CPU_MODEL,
+        .attr = KVM_S390_VM_CPU_MACHINE_SUBFUNC,
+        .addr = (uint64_t) &prop,
+    };
+    int rc;
+
+    rc = kvm_vm_ioctl(kvm_state, KVM_GET_DEVICE_ATTR, &attr);
+    if (rc) {
+        return  rc;
+    }
+
+    /*
+     * We're going to add all subfunctions now, if the corresponding feature
+     * is available that unlocks the query functions.
+     */
+    s390_add_from_feat_block(features, S390_FEAT_TYPE_PLO, prop.plo);
+    if (test_bit(S390_FEAT_TOD_CLOCK_STEERING, features)) {
+        s390_add_from_feat_block(features, S390_FEAT_TYPE_PTFF, prop.ptff);
+    }
+    if (test_bit(S390_FEAT_MSA, features)) {
+        s390_add_from_feat_block(features, S390_FEAT_TYPE_KMAC, prop.kmac);
+        s390_add_from_feat_block(features, S390_FEAT_TYPE_KMC, prop.kmc);
+        s390_add_from_feat_block(features, S390_FEAT_TYPE_KM, prop.km);
+        s390_add_from_feat_block(features, S390_FEAT_TYPE_KIMD, prop.kimd);
+        s390_add_from_feat_block(features, S390_FEAT_TYPE_KLMD, prop.klmd);
+    }
+    if (test_bit(S390_FEAT_MSA_EXT_3, features)) {
+        s390_add_from_feat_block(features, S390_FEAT_TYPE_PCKMO, prop.pckmo);
+    }
+    if (test_bit(S390_FEAT_MSA_EXT_4, features)) {
+        s390_add_from_feat_block(features, S390_FEAT_TYPE_KMCTR, prop.kmctr);
+        s390_add_from_feat_block(features, S390_FEAT_TYPE_KMF, prop.kmf);
+        s390_add_from_feat_block(features, S390_FEAT_TYPE_KMO, prop.kmo);
+        s390_add_from_feat_block(features, S390_FEAT_TYPE_PCC, prop.pcc);
+    }
+    if (test_bit(S390_FEAT_MSA_EXT_5, features)) {
+        s390_add_from_feat_block(features, S390_FEAT_TYPE_PPNO, prop.ppno);
+    }
+    return 0;
+}
+
+static int configure_cpu_subfunc(const S390FeatBitmap features)
+{
+    struct kvm_s390_vm_cpu_subfunc prop = {};
+    struct kvm_device_attr attr = {
+        .group = KVM_S390_VM_CPU_MODEL,
+        .attr = KVM_S390_VM_CPU_PROCESSOR_SUBFUNC,
+        .addr = (uint64_t) &prop,
+    };
+
+    if (!kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
+                           KVM_S390_VM_CPU_PROCESSOR_SUBFUNC)) {
+        /* hardware support might be missing, IBC will handle most of this */
+        return 0;
+    }
+
+    s390_fill_feat_block(features, S390_FEAT_TYPE_PLO, prop.plo);
+    if (test_bit(S390_FEAT_TOD_CLOCK_STEERING, features)) {
+        s390_fill_feat_block(features, S390_FEAT_TYPE_PTFF, prop.ptff);
+        prop.ptff[0] |= 0x80; /* query is always available */
+    }
+    if (test_bit(S390_FEAT_MSA, features)) {
+        s390_fill_feat_block(features, S390_FEAT_TYPE_KMAC, prop.kmac);
+        prop.kmac[0] |= 0x80; /* query is always available */
+        s390_fill_feat_block(features, S390_FEAT_TYPE_KMC, prop.kmc);
+        prop.kmc[0] |= 0x80; /* query is always available */
+        s390_fill_feat_block(features, S390_FEAT_TYPE_KM, prop.km);
+        prop.km[0] |= 0x80; /* query is always available */
+        s390_fill_feat_block(features, S390_FEAT_TYPE_KIMD, prop.kimd);
+        prop.kimd[0] |= 0x80; /* query is always available */
+        s390_fill_feat_block(features, S390_FEAT_TYPE_KLMD, prop.klmd);
+        prop.klmd[0] |= 0x80; /* query is always available */
+    }
+    if (test_bit(S390_FEAT_MSA_EXT_3, features)) {
+        s390_fill_feat_block(features, S390_FEAT_TYPE_PCKMO, prop.pckmo);
+        prop.pckmo[0] |= 0x80; /* query is always available */
+    }
+    if (test_bit(S390_FEAT_MSA_EXT_4, features)) {
+        s390_fill_feat_block(features, S390_FEAT_TYPE_KMCTR, prop.kmctr);
+        prop.kmctr[0] |= 0x80; /* query is always available */
+        s390_fill_feat_block(features, S390_FEAT_TYPE_KMF, prop.kmf);
+        prop.kmf[0] |= 0x80; /* query is always available */
+        s390_fill_feat_block(features, S390_FEAT_TYPE_KMO, prop.kmo);
+        prop.kmo[0] |= 0x80; /* query is always available */
+        s390_fill_feat_block(features, S390_FEAT_TYPE_PCC, prop.pcc);
+        prop.pcc[0] |= 0x80; /* query is always available */
+    }
+    if (test_bit(S390_FEAT_MSA_EXT_5, features)) {
+        s390_fill_feat_block(features, S390_FEAT_TYPE_PPNO, prop.ppno);
+        prop.ppno[0] |= 0x80; /* query is always available */
+    }
+    return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
+}
+
+static int kvm_to_feat[][2] = {
+    { KVM_S390_VM_CPU_FEAT_ESOP, S390_FEAT_ESOP },
+    { KVM_S390_VM_CPU_FEAT_SIEF2, S390_FEAT_SIE_F2 },
+    { KVM_S390_VM_CPU_FEAT_64BSCAO , S390_FEAT_SIE_64BSCAO },
+    { KVM_S390_VM_CPU_FEAT_SIIF, S390_FEAT_SIE_SIIF },
+    { KVM_S390_VM_CPU_FEAT_GPERE, S390_FEAT_SIE_GPERE },
+    { KVM_S390_VM_CPU_FEAT_GSLS, S390_FEAT_SIE_GSLS },
+    { KVM_S390_VM_CPU_FEAT_IB, S390_FEAT_SIE_IB },
+    { KVM_S390_VM_CPU_FEAT_CEI, S390_FEAT_SIE_CEI },
+    { KVM_S390_VM_CPU_FEAT_IBS, S390_FEAT_SIE_IBS },
+    { KVM_S390_VM_CPU_FEAT_SKEY, S390_FEAT_SIE_SKEY },
+    { KVM_S390_VM_CPU_FEAT_CMMA, S390_FEAT_SIE_CMMA },
+    { KVM_S390_VM_CPU_FEAT_PFMFI, S390_FEAT_SIE_PFMFI},
+    { KVM_S390_VM_CPU_FEAT_SIGPIF, S390_FEAT_SIE_SIGPIF},
+};
+
+static int query_cpu_feat(S390FeatBitmap features)
+{
+    struct kvm_s390_vm_cpu_feat prop;
+    struct kvm_device_attr attr = {
+        .group = KVM_S390_VM_CPU_MODEL,
+        .attr = KVM_S390_VM_CPU_MACHINE_FEAT,
+        .addr = (uint64_t) &prop,
+    };
+    int rc;
+    int i;
+
+    rc = kvm_vm_ioctl(kvm_state, KVM_GET_DEVICE_ATTR, &attr);
+    if (rc) {
+        return  rc;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(kvm_to_feat); i++) {
+        if (test_bit_inv(kvm_to_feat[i][0], (unsigned long *)prop.feat)) {
+            set_bit(kvm_to_feat[i][1], features);
+        }
+    }
+    return 0;
+}
+
+static int configure_cpu_feat(const S390FeatBitmap features)
+{
+    struct kvm_s390_vm_cpu_feat prop = {};
+    struct kvm_device_attr attr = {
+        .group = KVM_S390_VM_CPU_MODEL,
+        .attr = KVM_S390_VM_CPU_PROCESSOR_FEAT,
+        .addr = (uint64_t) &prop,
+    };
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(kvm_to_feat); i++) {
+        if (test_bit(kvm_to_feat[i][1], features)) {
+            set_bit_inv(kvm_to_feat[i][0], (unsigned long *)prop.feat);
+        }
+    }
+    return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
+}
+
+bool kvm_s390_cpu_models_supported(void)
+{
+    return kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
+                             KVM_S390_VM_CPU_MACHINE) &&
+           kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
+                             KVM_S390_VM_CPU_PROCESSOR) &&
+           kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
+                             KVM_S390_VM_CPU_MACHINE_FEAT) &&
+           kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
+                             KVM_S390_VM_CPU_PROCESSOR_FEAT) &&
+           kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
+                             KVM_S390_VM_CPU_MACHINE_SUBFUNC);
+}
+
+void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp)
+{
+    struct kvm_s390_vm_cpu_machine prop = {};
+    struct kvm_device_attr attr = {
+        .group = KVM_S390_VM_CPU_MODEL,
+        .attr = KVM_S390_VM_CPU_MACHINE,
+        .addr = (uint64_t) &prop,
+    };
+    uint16_t unblocked_ibc = 0, cpu_type = 0;
+    int rc;
+
+    memset(model, 0, sizeof(*model));
+
+    if (!kvm_s390_cpu_models_supported()) {
+        error_setg(errp, "KVM doesn't support CPU models");
+        return;
+    }
+
+    /* query the basic cpu model properties */
+    rc = kvm_vm_ioctl(kvm_state, KVM_GET_DEVICE_ATTR, &attr);
+    if (rc) {
+        error_setg(errp, "KVM: Error querying host CPU model: %d", rc);
+        return;
+    }
+
+    cpu_type = cpuid_type(prop.cpuid);
+    if (has_ibc(prop.ibc)) {
+        model->lowest_ibc = lowest_ibc(prop.ibc);
+        unblocked_ibc = unblocked_ibc(prop.ibc);
+    }
+    model->cpu_id = cpuid_id(prop.cpuid);
+    model->cpu_ver = 0xff;
+
+    /* get supported cpu features indicated via STFL(E) */
+    s390_add_from_feat_block(model->features, S390_FEAT_TYPE_STFL,
+                             (uint8_t *) prop.fac_mask);
+    /* dat-enhancement facility 2 has no bit but was introduced with stfle */
+    if (test_bit(S390_FEAT_STFLE, model->features)) {
+        set_bit(S390_FEAT_DAT_ENH_2, model->features);
+    }
+    /* get supported cpu features indicated e.g. via SCLP */
+    rc = query_cpu_feat(model->features);
+    if (rc) {
+        error_setg(errp, "KVM: Error querying CPU features: %d", rc);
+        return;
+    }
+    /* get supported cpu subfunctions indicated via query / test bit */
+    rc = query_cpu_subfunc(model->features);
+    if (rc) {
+        error_setg(errp, "KVM: Error querying CPU subfunctions: %d", rc);
+        return;
+    }
+
+    if (s390_known_cpu_type(cpu_type)) {
+        /* we want the exact model, even if some features are missing */
+        model->def = s390_find_cpu_def(cpu_type, ibc_gen(unblocked_ibc),
+                                       ibc_ec_ga(unblocked_ibc), NULL);
+    } else {
+        /* model unknown, e.g. too new - search using features */
+        model->def = s390_find_cpu_def(0, ibc_gen(unblocked_ibc),
+                                       ibc_ec_ga(unblocked_ibc),
+                                       model->features);
+    }
+    if (!model->def) {
+        error_setg(errp, "KVM: host CPU model could not be identified");
+        return;
+    }
+    /* strip of features that are not part of the maximum model */
+    bitmap_and(model->features, model->features, model->def->full_feat,
+               S390_FEAT_MAX);
+}
+
+void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp)
+{
+    struct kvm_s390_vm_cpu_processor prop  = {
+        .fac_list = { 0 },
+    };
+    struct kvm_device_attr attr = {
+        .group = KVM_S390_VM_CPU_MODEL,
+        .attr = KVM_S390_VM_CPU_PROCESSOR,
+        .addr = (uint64_t) &prop,
+    };
+    int rc;
+
+    if (!model) {
+        return;
+    }
+    if (!kvm_s390_cpu_models_supported()) {
+        error_setg(errp, "KVM doesn't support CPU models");
+        return;
+    }
+    prop.cpuid = s390_cpuid_from_cpu_model(model);
+    prop.ibc = s390_ibc_from_cpu_model(model);
+    /* configure cpu features indicated via STFL(e) */
+    s390_fill_feat_block(model->features, S390_FEAT_TYPE_STFL,
+                         (uint8_t *) prop.fac_list);
+    rc = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
+    if (rc) {
+        error_setg(errp, "KVM: Error configuring the CPU model: %d", rc);
+        return;
+    }
+    /* configure cpu features indicated e.g. via SCLP */
+    rc = configure_cpu_feat(model->features);
+    if (rc) {
+        error_setg(errp, "KVM: Error configuring CPU features: %d", rc);
+        return;
+    }
+    /* configure cpu subfunctions indicated via query / test bit */
+    rc = configure_cpu_subfunc(model->features);
+    if (rc) {
+        error_setg(errp, "KVM: Error configuring CPU subfunctions: %d", rc);
+        return;
+    }
+}
-- 
2.6.6

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

* [Qemu-devel] [RFC 21/28] s390x/kvm: disable host model for existing compat machines
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (19 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 20/28] s390x/kvm: implement CPU model support David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 22/28] s390x/kvm: let the CPU model control CMM(A) David Hildenbrand
                   ` (8 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Compatibility machines that touch runtime-instrumentation should not
be used with the CPU model. Otherwise the host model will look different,
depending on the QEMU machine QEMU has been started with.

So let's simply disable the host model for existing compatibility machines
that all disable ri.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/kvm.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 6002cf9..a4f5762 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -2440,6 +2440,10 @@ static int configure_cpu_feat(const S390FeatBitmap features)
 
 bool kvm_s390_cpu_models_supported(void)
 {
+    if (!ri_allowed()) {
+        /* compatibility machines interfere with the cpu model */
+        return false;
+    }
     return kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
                              KVM_S390_VM_CPU_MACHINE) &&
            kvm_vm_check_attr(kvm_state, KVM_S390_VM_CPU_MODEL,
-- 
2.6.6

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

* [Qemu-devel] [RFC 22/28] s390x/kvm: let the CPU model control CMM(A)
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (20 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 21/28] s390x/kvm: disable host model for existing compat machines David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 23/28] qmp: add QMP interface "query-cpu-model-expansion" David Hildenbrand
                   ` (7 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Starting with recent kernels, if the cmma attributes are available, we
actually have hardware support. Enabling CMMA then means providing the
guest VCPU with CMM, therefore enabling its CMM facility.

Let's not blindly enable CMM anymore but let's control it using CPU models.
For disabled CPU models, CMMA will continue to always get enabled.

Also enable it in the applicable default models.

Please note that CMM doesn't work with hugetlbfs, therefore we will
warn the user and keep it disabled. Migrating from/to a hugetlbfs
configuration works, as it will be disabled on both sides.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/gen-features.c |  1 +
 target-s390x/kvm.c          | 47 ++++++++++++++++++++++++++++++++++-----------
 2 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/target-s390x/gen-features.c b/target-s390x/gen-features.c
index d4f4b29..52d46dc 100644
--- a/target-s390x/gen-features.c
+++ b/target-s390x/gen-features.c
@@ -371,6 +371,7 @@ static uint16_t full_GEN13_GA1[] = {
 #define default_GEN8_GA5 EmptyFeat
 static uint16_t default_GEN9_GA1[] = {
     S390_FEAT_GROUP_MSA_EXT_1,
+    S390_FEAT_CMM,
 };
 #define default_GEN9_GA2 EmptyFeat
 #define default_GEN9_GA3 EmptyFeat
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index a4f5762..dd2abec 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -174,6 +174,18 @@ int kvm_s390_set_mem_limit(KVMState *s, uint64_t new_limit, uint64_t *hw_limit)
     return kvm_vm_ioctl(s, KVM_SET_DEVICE_ATTR, &attr);
 }
 
+static bool kvm_s390_cmma_available(void)
+{
+    static bool initialized, value;
+
+    if (!initialized) {
+        initialized = true;
+        value = kvm_vm_check_mem_attr(kvm_state, KVM_S390_VM_MEM_ENABLE_CMMA) &&
+                kvm_vm_check_mem_attr(kvm_state, KVM_S390_VM_MEM_CLR_CMMA);
+    }
+    return value;
+}
+
 void kvm_s390_cmma_reset(void)
 {
     int rc;
@@ -182,11 +194,15 @@ void kvm_s390_cmma_reset(void)
         .attr = KVM_S390_VM_MEM_CLR_CMMA,
     };
 
+    if (!mem_path || !kvm_s390_cmma_available()) {
+        return;
+    }
+
     rc = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
     trace_kvm_clear_cmma(rc);
 }
 
-static void kvm_s390_enable_cmma(KVMState *s)
+static void kvm_s390_enable_cmma(void)
 {
     int rc;
     struct kvm_device_attr attr = {
@@ -194,12 +210,7 @@ static void kvm_s390_enable_cmma(KVMState *s)
         .attr = KVM_S390_VM_MEM_ENABLE_CMMA,
     };
 
-    if (!kvm_vm_check_mem_attr(s, KVM_S390_VM_MEM_ENABLE_CMMA) ||
-        !kvm_vm_check_mem_attr(s, KVM_S390_VM_MEM_CLR_CMMA)) {
-        return;
-    }
-
-    rc = kvm_vm_ioctl(s, KVM_SET_DEVICE_ATTR, &attr);
+    rc = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
     trace_kvm_enable_cmma(rc);
 }
 
@@ -259,10 +270,6 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
     cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
     cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);
 
-    if (!mem_path) {
-        kvm_s390_enable_cmma(s);
-    }
-
     if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
         || !kvm_check_extension(s, KVM_CAP_S390_COW)) {
         phys_mem_set_alloc(legacy_s390_alloc);
@@ -2509,6 +2516,11 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp)
         return;
     }
 
+    /* with cpu model support, CMM is only indicated if really available */
+    if (kvm_s390_cmma_available()) {
+        set_bit(S390_FEAT_CMM, model->features);
+    }
+
     if (s390_known_cpu_type(cpu_type)) {
         /* we want the exact model, even if some features are missing */
         model->def = s390_find_cpu_def(cpu_type, ibc_gen(unblocked_ibc),
@@ -2541,6 +2553,10 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp)
     int rc;
 
     if (!model) {
+        /* compatibility handling if cpu models are disabled */
+        if (kvm_s390_cmma_available() && !mem_path) {
+            kvm_s390_enable_cmma();
+        }
         return;
     }
     if (!kvm_s390_cpu_models_supported()) {
@@ -2569,4 +2585,13 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp)
         error_setg(errp, "KVM: Error configuring CPU subfunctions: %d", rc);
         return;
     }
+    /* enable CMM via CMMA - disable on hugetlbfs */
+    if (test_bit(S390_FEAT_CMM, model->features)) {
+        if (mem_path) {
+            error_report("Warning: CMM will not be enabled because it is not "
+                         "compatible to hugetlbfs.");
+        } else {
+            kvm_s390_enable_cmma();
+        }
+    }
 }
-- 
2.6.6

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

* [Qemu-devel] [RFC 23/28] qmp: add QMP interface "query-cpu-model-expansion"
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (21 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 22/28] s390x/kvm: let the CPU model control CMM(A) David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 24/28] qmp: add QMP interface "query-cpu-model-comparison" David Hildenbrand
                   ` (6 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Let's provide a standardized interface to expand CPU models, like the
host model.

To take care of all architectures, different detail levels for an expansion
are introduced. Certain architectures might not support all detail levels.

When the host CPU model is to be expanded, at least the accelerator
QEMU has been started with affects the result. Some architectures
might decide to take the QEMU machine also into account.

E.g. for s390x, the host CPU model will only depend on the accelerator.

The result  of "stable" will be a migration safe CPU model, that will
produce the same guest ABI on other QEMU versions. This interface is very
helpful when CPU models are to be updated between QEMU versions. The
updated model can then simply be expanded to a migration safe
representation.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 include/sysemu/arch_init.h             |  3 ++
 qapi-schema.json                       | 81 ++++++++++++++++++++++++++++++++++
 qmp-commands.hx                        |  6 +++
 qmp.c                                  |  7 +++
 stubs/Makefile.objs                    |  1 +
 stubs/arch-query-cpu-model-expansion.c | 12 +++++
 6 files changed, 110 insertions(+)
 create mode 100644 stubs/arch-query-cpu-model-expansion.c

diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index d690dfa..37b2e86 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -35,5 +35,8 @@ int kvm_available(void);
 int xen_available(void);
 
 CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp);
+CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
+                                                      CpuModelInfo *mode,
+                                                      Error **errp);
 
 #endif
diff --git a/qapi-schema.json b/qapi-schema.json
index 0964eec..5b72dc0 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3026,6 +3026,87 @@
 ##
 { 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] }
 
+##
+# @CpuModelInfo:
+#
+# Virtual CPU model.
+#
+# A CPU model consists of the name of a CPU definition, to which
+# delta changes are applied (e.g. features added/removed). Most magic values
+# that an architecture might require should be hidden behind the name.
+# However, if required, architectures can expose relevant properties.
+#
+# @name: the name of the CPU definition the model is based on
+# @props: #optional a dictionary of properties to be applied
+#
+# Since: 2.7.0
+##
+{ 'struct': 'CpuModelInfo',
+  'data': { 'name': 'str',
+            '*props': 'any' } }
+
+##
+# @CpuModelExpansionType
+#
+# An enumeration of CPU model expansion types.
+#
+# @stable: Expand to a stable CPU model, creating a migration-safe
+#          representation with only delta changes.
+#
+# @migratable: Expand all migratable properties, hiding unmigratable
+#              properties.
+#
+# @full: Expand all properties, including unmigratable ones.
+#
+# Since: 2.7.0
+##
+{ 'enum': 'CpuModelExpansionType',
+  'data': [ 'stable', 'migratable', 'full' ] }
+
+
+##
+# @CpuModelExpansionInfo
+#
+# The result of a cpu model expansion.
+#
+# @model: the expanded CpuModelInfo.
+#
+# Since: 2.7.0
+##
+{ 'struct': 'CpuModelExpansionInfo',
+  'data': { 'model': 'CpuModelInfo' } }
+
+
+##
+# @query-cpu-model-expansion:
+#
+# Expands the given CPU model to the requested detail level.
+# For "stable", a migration-safe representation is created, which will look
+# the same on all QEMU versions and only contains delta changes. "migratable"
+# and "full" will expose properties in a more detailed way. Not all types
+# might be supported for an architecture.
+#
+# Expanding CPU models is in general independant of the accelerator, except
+# for models like "host" that explicitly rely on an accelerator and can
+# vary in different configurations. On certain architectures, the result may
+# rely on the QEMU machine.
+#
+# This interface can therefore also be used to query the "host" capabilities
+# on supporting architectures.
+#
+# Returns: a CpuModelExpansionInfo. Returns an error if CPU models are not
+#          supported, if the model cannot be expanded, if the model contains
+#          an unknown cpu definition name, unknown properties or properties
+#          with a wrong type. Also returns an error if an expansion type is
+#          not supported.
+#
+# Since: 2.7.0
+##
+{ 'command': 'query-cpu-model-expansion',
+  'data': { 'type': 'CpuModelExpansionType',
+            'model': 'CpuModelInfo' },
+  'returns': 'CpuModelExpansionInfo' }
+
 # @AddfdInfo:
 #
 # Information about a file descriptor that was added to an fd set.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index b444c20..b279fc5 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3930,6 +3930,12 @@ EQMP
     },
 
     {
+        .name       = "query-cpu-model-expansion",
+        .args_type  = "model:q",
+        .mhandler.cmd_new = qmp_marshal_query_cpu_model_expansion,
+    },
+
+    {
         .name       = "query-target",
         .args_type  = "",
         .mhandler.cmd_new = qmp_marshal_query_target,
diff --git a/qmp.c b/qmp.c
index 7df6543..c54f0a0 100644
--- a/qmp.c
+++ b/qmp.c
@@ -607,6 +607,13 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
     return arch_query_cpu_definitions(errp);
 }
 
+CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
+                                                     CpuModelInfo *model,
+                                                     Error **errp)
+{
+    return arch_query_cpu_model_expansion(type, model, errp);
+}
+
 void qmp_add_client(const char *protocol, const char *fdname,
                     bool has_skipauth, bool skipauth, bool has_tls, bool tls,
                     Error **errp)
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 4b258a6..83915f5 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -1,4 +1,5 @@
 stub-obj-y += arch-query-cpu-def.o
+stub-obj-y += arch-query-cpu-model-expansion.o
 stub-obj-y += bdrv-next-monitor-owned.o
 stub-obj-y += blk-commit-all.o
 stub-obj-y += blockdev-close-all-bdrv-states.o
diff --git a/stubs/arch-query-cpu-model-expansion.c b/stubs/arch-query-cpu-model-expansion.c
new file mode 100644
index 0000000..ae7cf55
--- /dev/null
+++ b/stubs/arch-query-cpu-model-expansion.c
@@ -0,0 +1,12 @@
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "sysemu/arch_init.h"
+#include "qapi/qmp/qerror.h"
+
+CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
+                                                      CpuModelInfo *mode,
+                                                      Error **errp)
+{
+    error_setg(errp, QERR_UNSUPPORTED);
+    return NULL;
+}
-- 
2.6.6

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

* [Qemu-devel] [RFC 24/28] qmp: add QMP interface "query-cpu-model-comparison"
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (22 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 23/28] qmp: add QMP interface "query-cpu-model-expansion" David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 25/28] qmp: add QMP interface "query-cpu-model-baseline" David Hildenbrand
                   ` (5 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Let's provide a standardized interface to compare two CPU models.

query-cpu-model-compare takes two models and returns what it knows about
their compability.

If modelA is a subset of modelB or if both are identical, modelA will run
in the same configuration as modelB. If modelA is however a superset of
modelB or if both are incompatible, one can try to create a compatible one
by "baselining" both models (follow up patch).

The host CPU model has the same semantics as for "query-cpu-model-expansion".

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 include/sysemu/arch_init.h              |  3 ++
 qapi-schema.json                        | 59 +++++++++++++++++++++++++++++++++
 qmp-commands.hx                         |  6 ++++
 qmp.c                                   |  7 ++++
 stubs/Makefile.objs                     |  1 +
 stubs/arch-query-cpu-model-comparison.c | 12 +++++++
 6 files changed, 88 insertions(+)
 create mode 100644 stubs/arch-query-cpu-model-comparison.c

diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 37b2e86..96d47c0 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -38,5 +38,8 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp);
 CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
                                                       CpuModelInfo *mode,
                                                       Error **errp);
+CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *modela,
+                                                     CpuModelInfo *modelb,
+                                                     Error **errp);
 
 #endif
diff --git a/qapi-schema.json b/qapi-schema.json
index 5b72dc0..34df86f 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3107,6 +3107,65 @@
             'model': 'CpuModelInfo' },
   'returns': 'CpuModelExpansionInfo' }
 
+##
+# @CpuModelCompareResult:
+#
+# An enumeration of CPU model comparation results.
+#
+# @incompatible: both model definition are incompatible
+#
+# @identical: model A == model B
+#
+# @superset: model A > model B
+#
+# @subset: model A < model B
+#
+# Since: 2.7.0
+##
+{ 'enum': 'CpuModelCompareResult',
+  'data': [ 'incompatible', 'identical', 'superset', 'subset' ] }
+
+##
+# @CpuModelCompareInfo
+#
+# The result of a CPU model comparison.
+#
+# @result: The result of the compare operation.
+# @responsible-properties: List of properties that led to the comparison result
+#                          not being identical.
+#
+# @responsible-properties is a list of QOM property names that lead to
+# both CPUs not being detected as identical. For identical models, this
+# list is empty.
+# If the QOM property is read-only, that means there's no known
+# way to make the CPU models identical. If the special property name
+# "type" is included, the models are by definition not identical and
+# cannot be made identical.
+#
+# Since: 2.7.0
+##
+{ 'struct': 'CpuModelCompareInfo',
+  'data': {'result': 'CpuModelCompareResult',
+           'responsible-properties': ['str']
+          }
+}
+
+##
+# @query-cpu-model-comparison:
+#
+# Compares two CPU models.
+#
+# Returns: a CpuModelCompareInfo. Returns an error if CPU models are not
+#          supported, if a model cannot be used, if the model contains
+#          an unknown cpu definition name, unknown properties or properties
+#          with a wrong type.
+#
+# Since: 2.7.0
+##
+{ 'command': 'query-cpu-model-comparison',
+  'data': { 'modela': 'CpuModelInfo', 'modelb': 'CpuModelInfo' },
+  'returns': 'CpuModelCompareInfo' }
+
 # @AddfdInfo:
 #
 # Information about a file descriptor that was added to an fd set.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index b279fc5..4ee7937 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3936,6 +3936,12 @@ EQMP
     },
 
     {
+        .name       = "query-cpu-model-comparison",
+        .args_type  = "modela:q,modelb:q",
+        .mhandler.cmd_new = qmp_marshal_query_cpu_model_comparison,
+    },
+
+    {
         .name       = "query-target",
         .args_type  = "",
         .mhandler.cmd_new = qmp_marshal_query_target,
diff --git a/qmp.c b/qmp.c
index c54f0a0..afa8c77 100644
--- a/qmp.c
+++ b/qmp.c
@@ -614,6 +614,13 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
     return arch_query_cpu_model_expansion(type, model, errp);
 }
 
+CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *modela,
+                                                    CpuModelInfo *modelb,
+                                                    Error **errp)
+{
+    return arch_query_cpu_model_comparison(modela, modelb, errp);
+}
+
 void qmp_add_client(const char *protocol, const char *fdname,
                     bool has_skipauth, bool skipauth, bool has_tls, bool tls,
                     Error **errp)
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 83915f5..b831dbc 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -1,5 +1,6 @@
 stub-obj-y += arch-query-cpu-def.o
 stub-obj-y += arch-query-cpu-model-expansion.o
+stub-obj-y += arch-query-cpu-model-comparison.o
 stub-obj-y += bdrv-next-monitor-owned.o
 stub-obj-y += blk-commit-all.o
 stub-obj-y += blockdev-close-all-bdrv-states.o
diff --git a/stubs/arch-query-cpu-model-comparison.c b/stubs/arch-query-cpu-model-comparison.c
new file mode 100644
index 0000000..d5486ae
--- /dev/null
+++ b/stubs/arch-query-cpu-model-comparison.c
@@ -0,0 +1,12 @@
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "sysemu/arch_init.h"
+#include "qapi/qmp/qerror.h"
+
+CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *modela,
+                                                     CpuModelInfo *modelb,
+                                                     Error **errp)
+{
+    error_setg(errp, QERR_UNSUPPORTED);
+    return NULL;
+}
-- 
2.6.6

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

* [Qemu-devel] [RFC 25/28] qmp: add QMP interface "query-cpu-model-baseline"
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (23 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 24/28] qmp: add QMP interface "query-cpu-model-comparison" David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 26/28] s390x/cpumodel: implement QMP interface "query-cpu-model-expansion" David Hildenbrand
                   ` (4 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Let's provide a standardized interface to baseline two CPU models, to
create a third, compatible one.

For now, we allow two baseline modes. "stable" tries to create a
better tested model, e.g. by minimizing CPU definition changes.
"maximum" rather tries to get the maxmimum possible model,
e.g. by maximizing features.

The host CPU model has the same semantics as for "query-cpu-model-expansion".

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 include/sysemu/arch_init.h            |  4 ++++
 qapi-schema.json                      | 44 +++++++++++++++++++++++++++++++++++
 qmp-commands.hx                       |  6 +++++
 qmp.c                                 |  8 +++++++
 stubs/Makefile.objs                   |  1 +
 stubs/arch-query-cpu-model-baseline.c | 13 +++++++++++
 6 files changed, 76 insertions(+)
 create mode 100644 stubs/arch-query-cpu-model-baseline.c

diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 96d47c0..1b35e90 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -41,5 +41,9 @@ CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type
 CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *modela,
                                                      CpuModelInfo *modelb,
                                                      Error **errp);
+CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelBaselineType type,
+                                                    CpuModelInfo *modela,
+                                                    CpuModelInfo *modelb,
+                                                    Error **errp);
 
 #endif
diff --git a/qapi-schema.json b/qapi-schema.json
index 34df86f..3a3fccb 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3166,6 +3166,50 @@
   'data': { 'modela': 'CpuModelInfo', 'modelb': 'CpuModelInfo' },
   'returns': 'CpuModelCompareInfo' }
 
+##
+# @CpuModelBaselineType
+#
+# An enumeration of CPU model baseline types.
+#
+# @stable: Find a compatible, stable model (e.g. least feature changes).
+#
+# @maximum: Find a compatible, maximum model (e.g. maximizing features)
+#
+# Since: 2.7.0
+##
+{ 'enum': 'CpuModelBaselineType',
+  'data': [ 'stable', 'maximum' ] }
+
+##
+# @CpuModelBaselineInfo
+#
+# The result of a CPU model baseline.
+#
+# @model: the baselined CpuModelInfo.
+#
+# Since: 2.7.0
+##
+{ 'struct': 'CpuModelBaselineInfo',
+  'data': { 'model': 'CpuModelInfo' } }
+
+##
+# @query-cpu-model-baseline:
+#
+# Baseline two CPU models, creating a compatible third model.
+#
+# Returns: a CpuModelBaselineInfo. Returns an error if CPU models are not
+#          supported, if a model cannot be used, if the model contains
+#          an unknown cpu definition name, unknown properties or properties
+#          with a wrong type.
+#
+# Since: 2.7.0
+##
+{ 'command': 'query-cpu-model-baseline',
+  'data': { 'type' : 'CpuModelBaselineType',
+            'modela': 'CpuModelInfo',
+            'modelb': 'CpuModelInfo' },
+  'returns': 'CpuModelBaselineInfo' }
+
 # @AddfdInfo:
 #
 # Information about a file descriptor that was added to an fd set.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 4ee7937..42b3853 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3942,6 +3942,12 @@ EQMP
     },
 
     {
+        .name       = "query-cpu-model-baseline",
+        .args_type  = "type:s,modela:q,modelb:q",
+        .mhandler.cmd_new = qmp_marshal_query_cpu_model_baseline,
+    },
+
+    {
         .name       = "query-target",
         .args_type  = "",
         .mhandler.cmd_new = qmp_marshal_query_target,
diff --git a/qmp.c b/qmp.c
index afa8c77..6e5437f 100644
--- a/qmp.c
+++ b/qmp.c
@@ -621,6 +621,14 @@ CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *modela,
     return arch_query_cpu_model_comparison(modela, modelb, errp);
 }
 
+CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelBaselineType type,
+                                                   CpuModelInfo *modela,
+                                                   CpuModelInfo *modelb,
+                                                   Error **errp)
+{
+    return arch_query_cpu_model_baseline(type, modela, modelb, errp);
+}
+
 void qmp_add_client(const char *protocol, const char *fdname,
                     bool has_skipauth, bool skipauth, bool has_tls, bool tls,
                     Error **errp)
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index b831dbc..56bddd8 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -1,6 +1,7 @@
 stub-obj-y += arch-query-cpu-def.o
 stub-obj-y += arch-query-cpu-model-expansion.o
 stub-obj-y += arch-query-cpu-model-comparison.o
+stub-obj-y += arch-query-cpu-model-baseline.o
 stub-obj-y += bdrv-next-monitor-owned.o
 stub-obj-y += blk-commit-all.o
 stub-obj-y += blockdev-close-all-bdrv-states.o
diff --git a/stubs/arch-query-cpu-model-baseline.c b/stubs/arch-query-cpu-model-baseline.c
new file mode 100644
index 0000000..407d323
--- /dev/null
+++ b/stubs/arch-query-cpu-model-baseline.c
@@ -0,0 +1,13 @@
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "sysemu/arch_init.h"
+#include "qapi/qmp/qerror.h"
+
+CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelBaselineType type,
+                                                    CpuModelInfo *modela,
+                                                    CpuModelInfo *modelb,
+                                                    Error **errp)
+{
+    error_setg(errp, QERR_UNSUPPORTED);
+    return NULL;
+}
-- 
2.6.6

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

* [Qemu-devel] [RFC 26/28] s390x/cpumodel: implement QMP interface "query-cpu-model-expansion"
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (24 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 25/28] qmp: add QMP interface "query-cpu-model-baseline" David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 27/28] s390x/cpumodel: implement QMP interface "query-cpu-model-comparison" David Hildenbrand
                   ` (3 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

In order to expand CPU models, we create temporary cpus that handle the
feature/group parsing.

When converting the data structure back, we always fall back to the
base cpu model, which is by definition migration safe.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/cpu_models.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index b8ae601..988b9d7 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -16,6 +16,9 @@
 #include "qapi/error.h"
 #include "qapi/visitor.h"
 #include "qemu/error-report.h"
+#include "qapi/qmp/qerror.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/qmp/qbool.h"
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/arch_init.h"
 #endif
@@ -287,6 +290,135 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
 
     return list;
 }
+
+static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info,
+                                Error **errp)
+{
+    const QDict *qdict = NULL;
+    QmpInputVisitor *qiv;
+    const QDictEntry *e;
+    ObjectClass *oc;
+    S390CPU *cpu;
+    Object *obj;
+
+    if (info->props) {
+        qdict = qobject_to_qdict(info->props);
+        if (!qdict) {
+            error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
+            return;
+        }
+    }
+
+    oc = cpu_class_by_name(TYPE_S390_CPU, info->name);
+    if (!oc) {
+        error_setg(errp, "The CPU definition \'%s\' is unknown.", info->name);
+        return;
+    }
+    if (S390_CPU_CLASS(oc)->kvm_required && !kvm_enabled()) {
+        error_setg(errp, "The CPU definition '%s' requires KVM", info->name);
+        return;
+    }
+    obj = object_new(object_class_get_name(oc));
+    cpu = S390_CPU(obj);
+
+    if (!cpu->model) {
+        error_setg(errp, "Details about the host CPU model are not available, "
+                         "it cannot be used.");
+        object_unref(obj);
+        return;
+    }
+
+    if (qdict) {
+        qiv = qmp_input_visitor_new(info->props, true);
+        for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
+            object_property_set(obj, qmp_input_get_visitor(qiv), e->key, errp);
+            if (*errp) {
+                qmp_input_visitor_cleanup(qiv);
+                object_unref(obj);
+                return;
+            }
+        }
+        qmp_input_visitor_cleanup(qiv);
+    }
+
+    /* copy the model and throw the cpu away */
+    memcpy(model, cpu->model, sizeof(*model));
+    object_unref(obj);
+}
+
+static void qdict_add_disabled_feat(const char *name, void *opaque)
+{
+    qdict_put((QDict *) opaque, name, qbool_from_bool(false));
+}
+
+static void qdict_add_enabled_feat(const char *name, void *opaque)
+{
+    qdict_put((QDict *) opaque, name, qbool_from_bool(true));
+}
+
+/* convert S390CPUDef into migration safe CpuModelInfo */
+static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
+                                bool delta_changes)
+{
+    QDict *qdict = qdict_new();
+    S390FeatBitmap bitmap;
+
+    /* always fallback to the stable base model */
+    info->name = g_strdup_printf("%s-base", model->def->name);
+
+    if (delta_changes) {
+        /* features deleted from the base feature set */
+        bitmap_andnot(bitmap, model->def->base_feat, model->features,
+                      S390_FEAT_MAX);
+        if (!bitmap_empty(bitmap, S390_FEAT_MAX)) {
+            s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
+        }
+
+        /* features added to the base feature set */
+        bitmap_andnot(bitmap, model->features, model->def->base_feat,
+                      S390_FEAT_MAX);
+        if (!bitmap_empty(bitmap, S390_FEAT_MAX)) {
+            s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_enabled_feat);
+        }
+    } else {
+        /* expand all features */
+        s390_feat_bitmap_to_ascii(model->features, qdict, qdict_add_enabled_feat);
+        bitmap_complement(bitmap, model->features, S390_FEAT_MAX);
+        s390_feat_bitmap_to_ascii(model->features, qdict, qdict_add_disabled_feat);
+    }
+
+    if (!qdict_size(qdict)) {
+        QDECREF(qdict);
+    } else {
+        info->props = QOBJECT(qdict);
+        info->has_props = true;
+    }
+}
+
+CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
+                                                      CpuModelInfo *model,
+                                                      Error **errp)
+{
+    CpuModelExpansionInfo *expansion_info = NULL;
+    S390CPUModel s390_model;
+    bool delta_changes = false;
+
+    /* convert it to our internal representation */
+    cpu_model_from_info(&s390_model, model, errp);
+    if (*errp) {
+        return NULL;
+    }
+
+    if (type == CPU_MODEL_EXPANSION_TYPE_STABLE) {
+        delta_changes = true;
+    }
+
+    /* convert it back to a migration safe version */
+    expansion_info = g_malloc0(sizeof(*expansion_info));
+    expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
+    cpu_info_from_model(expansion_info->model, &s390_model, delta_changes);
+    return expansion_info;
+}
 #endif
 
 static void check_consistency(const S390CPUModel *model)
-- 
2.6.6

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

* [Qemu-devel] [RFC 27/28] s390x/cpumodel: implement QMP interface "query-cpu-model-comparison"
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (25 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 26/28] s390x/cpumodel: implement QMP interface "query-cpu-model-expansion" David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 13:02 ` [Qemu-devel] [RFC 28/28] s390x/cpumodel: implement QMP interface "query-cpu-model-baseline" David Hildenbrand
                   ` (2 subsequent siblings)
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Let's implement that interface by reusing our convertion code
implemented for expansion.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/cpu_models.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index 988b9d7..75d808b 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -419,6 +419,90 @@ CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type
     cpu_info_from_model(expansion_info->model, &s390_model, delta_changes);
     return expansion_info;
 }
+
+static void list_add_feat(const char *name, void *opaque)
+{
+    strList **last = (strList **) opaque;
+    strList *entry;
+
+    entry = g_malloc0(sizeof(*entry));
+    entry->value = g_strdup(name);
+    entry->next = *last;
+    *last = entry;
+}
+
+CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *infoa,
+                                                     CpuModelInfo *infob,
+                                                     Error **errp)
+{
+    CpuModelCompareResult feat_result, gen_result;
+    CpuModelCompareInfo *compare_info;
+    S390FeatBitmap missing, added;
+    S390CPUModel modela, modelb;
+
+    /* convert both models to our internal representation */
+    cpu_model_from_info(&modela, infoa, errp);
+    if (*errp) {
+        return NULL;
+    }
+    cpu_model_from_info(&modelb, infob, errp);
+    if (*errp) {
+        return NULL;
+    }
+    compare_info = g_malloc0(sizeof(*compare_info));
+
+    /* check the cpu generation and ga level */
+    if (modela.def->gen == modelb.def->gen) {
+        if (modela.def->ec_ga == modelb.def->ec_ga) {
+            /* ec and corresponding bc are identical */
+            gen_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL;
+        } else if (modela.def->ec_ga < modelb.def->ec_ga) {
+            gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
+        } else {
+            gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
+        }
+    } else if (modela.def->gen < modelb.def->gen) {
+        gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
+    } else {
+        gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
+    }
+    if (gen_result != CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
+        /* both models cannot be made identical */
+        list_add_feat("type", &compare_info->responsible_properties);
+    }
+
+    /* check the feature set */
+    if (bitmap_equal(modela.features, modelb.features, S390_FEAT_MAX)) {
+        feat_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL;
+    } else {
+        bitmap_andnot(missing, modela.features, modelb.features, S390_FEAT_MAX);
+        s390_feat_bitmap_to_ascii(missing,
+                                  &compare_info->responsible_properties,
+                                  list_add_feat);
+        bitmap_andnot(added, modelb.features, modela.features, S390_FEAT_MAX);
+        s390_feat_bitmap_to_ascii(added, &compare_info->responsible_properties,
+                                  list_add_feat);
+        if (bitmap_empty(missing, S390_FEAT_MAX)) {
+            feat_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
+        } else if (bitmap_empty(added, S390_FEAT_MAX)) {
+            feat_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
+        } else {
+            feat_result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE;
+        }
+    }
+
+    /* combine the results */
+    if (gen_result == feat_result) {
+        compare_info->result = gen_result;
+    } else if (feat_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
+        compare_info->result = gen_result;
+    } else if (gen_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
+        compare_info->result = feat_result;
+    } else {
+        compare_info->result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE;
+    }
+    return compare_info;
+}
 #endif
 
 static void check_consistency(const S390CPUModel *model)
-- 
2.6.6

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

* [Qemu-devel] [RFC 28/28] s390x/cpumodel: implement QMP interface "query-cpu-model-baseline"
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (26 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 27/28] s390x/cpumodel: implement QMP interface "query-cpu-model-comparison" David Hildenbrand
@ 2016-06-21 13:02 ` David Hildenbrand
  2016-06-21 16:44 ` [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features Eduardo Habkost
  2016-06-30  7:32 ` David Hildenbrand
  29 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 13:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, jdenemar, imammedo, cornelia.huck, borntraeger, fiuczy, mimu

Let's implement that interface by reusing our conversion code and
lookup code for cpu definitions.

Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
---
 target-s390x/cpu_models.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index 75d808b..56b945d 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -503,6 +503,67 @@ CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *infoa,
     }
     return compare_info;
 }
+
+CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelBaselineType type,
+                                                    CpuModelInfo *infoa,
+                                                    CpuModelInfo *infob,
+                                                    Error **errp)
+{
+    CpuModelBaselineInfo *baseline_info;
+    S390CPUModel modela, modelb, model;
+    uint16_t cpu_type;
+    uint8_t max_gen_ga;
+    uint8_t max_gen;
+
+    /* convert both models to our internal representation */
+    cpu_model_from_info(&modela, infoa, errp);
+    if (*errp) {
+        return NULL;
+    }
+
+    cpu_model_from_info(&modelb, infob, errp);
+    if (*errp) {
+        return NULL;
+    }
+
+    /* features both models support */
+    bitmap_and(model.features, modela.features, modelb.features, S390_FEAT_MAX);
+
+    /* detect the maximum model not regarding features */
+    if (modela.def->gen == modelb.def->gen) {
+        if (modela.def->type == modelb.def->type) {
+            cpu_type = modela.def->type;
+        } else {
+            cpu_type = 0;
+        }
+        max_gen = modela.def->gen;
+        max_gen_ga = MIN(modela.def->ec_ga, modelb.def->ec_ga);
+    } else if (modela.def->gen > modelb.def->gen) {
+        cpu_type = modelb.def->type;
+        max_gen = modelb.def->gen;
+        max_gen_ga = modelb.def->ec_ga;
+    } else {
+        cpu_type = modela.def->type;
+        max_gen = modela.def->gen;
+        max_gen_ga = modela.def->ec_ga;
+    }
+
+    model.def = s390_find_cpu_def(cpu_type, max_gen, max_gen_ga,
+                                  model.features);
+    /* make sure we don't exceed full features of that vcpu */
+    if (type == CPU_MODEL_BASELINE_TYPE_STABLE) {
+        bitmap_and(model.features, model.features, model.def->default_feat,
+                   S390_FEAT_MAX);
+    } else {
+        bitmap_and(model.features, model.features, model.def->full_feat,
+                   S390_FEAT_MAX);
+    }
+
+    baseline_info = g_malloc0(sizeof(*baseline_info));
+    baseline_info->model = g_malloc0(sizeof(*baseline_info->model));
+    cpu_info_from_model(baseline_info->model, &model, true);
+    return baseline_info;
+}
 #endif
 
 static void check_consistency(const S390CPUModel *model)
-- 
2.6.6

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (27 preceding siblings ...)
  2016-06-21 13:02 ` [Qemu-devel] [RFC 28/28] s390x/cpumodel: implement QMP interface "query-cpu-model-baseline" David Hildenbrand
@ 2016-06-21 16:44 ` Eduardo Habkost
  2016-06-21 17:01   ` David Hildenbrand
  2016-06-21 20:56   ` Jiri Denemark
  2016-06-30  7:32 ` David Hildenbrand
  29 siblings, 2 replies; 53+ messages in thread
From: Eduardo Habkost @ 2016-06-21 16:44 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: qemu-devel, jdenemar, imammedo, cornelia.huck, borntraeger,
	fiuczy, mimu, libvir-list

(CCing libvirt people)

On Tue, Jun 21, 2016 at 03:02:05PM +0200, David Hildenbrand wrote:
> This is our second attempt to implement CPU models for s390x. We realized
> that we also want to have features exposed via the CPU model. While doing
> that we realized that we want to have a better interface for libvirt.

Before getting into the details, I would like to clarify how the
following could be accomplished using the new commands:

Example:

1) User configures libvirt with:
   <cpu match='exact'>
       <model fallback='forbid'>Westmere</model>
       <feature policy='require' name='aes'/>
   </cpu>
2) libvirt will translate that to:
   "-cpu Westmere,+aes" or "-cpu Westmere,aes=on"
3) libvirt wants to know if "-cpu Westmere,aes=on" is usable in
   the current host, before trying to start the VM.

How exactly would this be done using the new commands?

> 
> Unfortunately, CPU models on s390x are special and we have to take care of:
> - A CPU like z13 looks differently in various environments (under different
>   LPAR versions, under different z/VM versions, under different KVM
>   versions, export regulation) - we have _a lot_ of feature variability.
> - We still have certain features that are not published but might be
>   implemented/introduced in the future. As they are a theoretical part
>   of a CPU already, we have to find a way to model these future changes.
> - We still have certain features that are already published, but not
>   implemented. Implementation might be added in the future in KVM.
> - We heavily rely on KVM to tell us which features it can actually
>   virtualize - user space queries like "STFL(e)" give no guarantees.
> - Certain "subfeatures" were introduced in one run. In practice, they are
>   always around, but in theory, subfeatures could be dropped in the future.
> - Just because two CPU models have the same features doesn't mean they
>   are equal - some internal numbers might be different. E.g. we won't allow
>   running a z13 under a zBC12 just by turning off features.
> - We cannot blindly enable all possible features for a CPU generation,
>   the IBC "Instruction Blocking Control" in KVM will try to block
>   instructions introduced with certain features. So a CPU generation always
>   has some maximum feature set that is guaranteed to work.
> 
> It all boils down to a specific released CPU to have.
> a) A fixed feature set that we expect it to be have on every hypervisor.
> b) A variable part that depends on the hypervisor and that could be
>    extended in the future (adding not yet implemented features) that we
>    always want to enable later on.
> c) A variable part that we want to enable only if requested - nested
>    virtualization ("vsie") and assists are one example.
> 
> But, the fixed feature set is not really what we want to use as a default.
> It is just like a really minimum, stable base.
> 
> So we have
> a) A "stable" CPU model for each released CPU that will never change and
>    maps to the minimum feature set we expect to be around on all
>    hypervisors. e.g. "z13-base" or "z10EC.2-base". These are migration
>    safe.
> b) A "default" CPU model for each released CPU, that can change between
>    QEMU versions and that will always include the features we expect to
>    be around in our currently supported environments and will contain only
>    features we expect to be stable. E.g. nested virtualization will not be
>    contained in these models. These models are not migration safe, e.g
>    "z13" or "z10EC.2". The feature set can differ between QEMU versions.
> c) An internal "maximum" CPU model for each generation that tells us which
>    features were supported as a maximum back when the hardware was
>    released. This will not be exposed
> 
> To not have to replicate all CPU model changes ("new default fetaures") in
> libvirt, to not duplicate the logic about compatibility and the like,
> our approach tries to keep all the QEMU logic in libvirt and provide
> standardized interfaces for libvirt to e.g. baseline, compare. This
> allows libvirt to not have to care about any model names or feature names,
> it can just pass the data from interface to interface and report it to
> the user.
> 
> Also, libvirt might want to know what the "host" model looks like and
> convert a CPU model to a migration safe variant. For this reason, a QMP
> command is added that can create a migration safe variant of a variable
> CPU model, indicating only the delta changes done to a stable model.
> 
> So we have:
> a) "query-cpu-model-expansion" - tell us what the "host" or a migration
>    unsafe model looks like. Either falling back to a stable model or
>    completely exposing all properties. We are interested in stable models.
> b) "query-cpu-model-comparison" - tell us how two CPU models compare,
>     indicating which properties were responsible for the decision.
> c) "query-cpu-model-baseline" - create a new model out of two models,
>     taking a requested level of stability into account.
> 
> As we are aware that e.g. x86 has their own idea of a CPU model and their
> existing implementation in place, but are also looking into to ways to e.g.
> expand the "host" CPU model to a detailed representation, we designed the
> "expansion" interface to also allow that.
> 
> Comments are very welcome, but please always keep the restrictions and
> specialties in mind when suggesting some major design changes.
> 
> The header update will be replaced by a kvm-next header update as soon as
> the VSIE patches are upstream. The major KVM interface changes are already
> part of kvm-next.
> 
> The current state is available on git://github.com/cohuck/qemu on branch
> "cpumodel-s390x".
> 
> David Hildenbrand (26):
>   s390x/cpumodel: "host" and "qemu" as CPU subclasses
>   s390x/cpumodel: expose CPU class properties
>   s390x/cpumodel: generate CPU feature group lists
>   s390x/cpumodel: introduce CPU feature group definitions
>   s390x/cpumodel: register defined CPU models as subclasses
>   s390x/cpumodel: store the CPU model in the CPU instance
>   s390x/cpumodel: expose features and feature groups as properties
>   s390x/cpumodel: let the CPU model handle feature checks
>   s390x/cpumodel: check and apply the CPU model
>   s390x/sclp: factor out preparation of cpu entries
>   s390x/sclp: introduce sclp feature blocks
>   s390x/sclp: indicate sclp features
>   s390x/sclp: propagate the ibc val(lowest and unblocked ibc)
>   s390x/sclp: propagate the mha via sclp
>   s390x/sclp: propagate hmfai
>   update linux headers (CPU model)
>   s390x/kvm: allow runtime-instrumentation for "none" machine
>   s390x/kvm: implement CPU model support
>   s390x/kvm: disable host model for existing compat machines
>   s390x/kvm: let the CPU model control CMM(A)
>   qmp: add QMP interface "query-cpu-model-expansion"
>   qmp: add QMP interface "query-cpu-model-comparison"
>   qmp: add QMP interface "query-cpu-model-baseline"
>   s390x/cpumodel: implement QMP interface "query-cpu-model-expansion"
>   s390x/cpumodel: implement QMP interface "query-cpu-model-comparison"
>   s390x/cpumodel: implement QMP interface "query-cpu-model-baseline"
> 
> Michael Mueller (2):
>   s390x/cpumodel: introduce CPU features
>   s390x/cpumodel: generate CPU feature lists for CPU models
> 
>  Makefile.target                         |    2 +-
>  hw/s390x/s390-virtio-ccw.c              |    5 +
>  hw/s390x/s390-virtio.c                  |    6 +-
>  hw/s390x/sclp.c                         |   35 +-
>  include/hw/s390x/sclp.h                 |   17 +-
>  include/sysemu/arch_init.h              |   10 +
>  linux-headers/asm-s390/kvm.h            |   40 ++
>  qapi-schema.json                        |  184 ++++++
>  qmp-commands.hx                         |   18 +
>  qmp.c                                   |   22 +
>  rules.mak                               |    1 +
>  stubs/Makefile.objs                     |    3 +
>  stubs/arch-query-cpu-model-baseline.c   |   13 +
>  stubs/arch-query-cpu-model-comparison.c |   12 +
>  stubs/arch-query-cpu-model-expansion.c  |   12 +
>  target-s390x/Makefile.objs              |   22 +-
>  target-s390x/cpu-qom.h                  |    5 +
>  target-s390x/cpu.c                      |   35 +-
>  target-s390x/cpu.h                      |    5 +
>  target-s390x/cpu_features.c             |  376 +++++++++++
>  target-s390x/cpu_features.h             |  302 +++++++++
>  target-s390x/cpu_models.c               | 1055 +++++++++++++++++++++++++++++++
>  target-s390x/cpu_models.h               |  113 ++++
>  target-s390x/gen-features.c             |  587 +++++++++++++++++
>  target-s390x/helper.c                   |   29 +-
>  target-s390x/kvm.c                      |  346 +++++++++-
>  target-s390x/machine.c                  |   14 +-
>  27 files changed, 3203 insertions(+), 66 deletions(-)
>  create mode 100644 stubs/arch-query-cpu-model-baseline.c
>  create mode 100644 stubs/arch-query-cpu-model-comparison.c
>  create mode 100644 stubs/arch-query-cpu-model-expansion.c
>  create mode 100644 target-s390x/cpu_features.c
>  create mode 100644 target-s390x/cpu_features.h
>  create mode 100644 target-s390x/cpu_models.c
>  create mode 100644 target-s390x/cpu_models.h
>  create mode 100644 target-s390x/gen-features.c
> 
> -- 
> 2.6.6
> 

-- 
Eduardo

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-21 16:44 ` [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features Eduardo Habkost
@ 2016-06-21 17:01   ` David Hildenbrand
  2016-06-21 20:33     ` Eduardo Habkost
  2016-06-21 20:56   ` Jiri Denemark
  1 sibling, 1 reply; 53+ messages in thread
From: David Hildenbrand @ 2016-06-21 17:01 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: qemu-devel, jdenemar, imammedo, cornelia.huck, borntraeger,
	fiuczy, mimu, libvir-list

> (CCing libvirt people)
> 
> On Tue, Jun 21, 2016 at 03:02:05PM +0200, David Hildenbrand wrote:
> > This is our second attempt to implement CPU models for s390x. We realized
> > that we also want to have features exposed via the CPU model. While doing
> > that we realized that we want to have a better interface for libvirt.  
> 
> Before getting into the details, I would like to clarify how the
> following could be accomplished using the new commands:
> 
> Example:
> 
> 1) User configures libvirt with:
>    <cpu match='exact'>
>        <model fallback='forbid'>Westmere</model>
>        <feature policy='require' name='aes'/>
>    </cpu>
> 2) libvirt will translate that to:
>    "-cpu Westmere,+aes" or "-cpu Westmere,aes=on"
> 3) libvirt wants to know if "-cpu Westmere,aes=on" is usable in
>    the current host, before trying to start the VM.
> 
> How exactly would this be done using the new commands?

Hi Eduardo,

thanks for having a look - highly appreciated that you actually map this
to libvirt requirements!

That would map to a compare operation between "host" and "Westmere,aes=on".

Host could at that point already be expanded by libvirt. Doesn't matter at that
point.

If the result is "identica"l or "superset", it is runnable. If the result is
"subset" or "incompatible", details about the responsible properties is
indicated. (I actually took that idea from your patch for indicating
runnability).

Thanks!

David

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

* Re: [Qemu-devel] [RFC 06/28] s390x/cpumodel: introduce CPU feature group definitions
  2016-06-21 13:02 ` [Qemu-devel] [RFC 06/28] s390x/cpumodel: introduce CPU feature group definitions David Hildenbrand
@ 2016-06-21 20:14   ` Thomas Huth
  2016-06-22  6:19     ` David Hildenbrand
  0 siblings, 1 reply; 53+ messages in thread
From: Thomas Huth @ 2016-06-21 20:14 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: ehabkost, borntraeger, fiuczy, cornelia.huck, imammedo, jdenemar, mimu

On 21.06.2016 15:02, David Hildenbrand wrote:
> Let's use the generated groups to create feature group representations for
> the user. These groups can later be used to enable/disable multiple
> features in one shot and will be used to reduce the amount of reported
> features to the user if all subfeatures are in place.
> 
> Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
> ---
>  target-s390x/cpu_features.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
>  target-s390x/cpu_features.h | 23 +++++++++++++++++++++++
>  2 files changed, 66 insertions(+), 1 deletion(-)
> 
> diff --git a/target-s390x/cpu_features.c b/target-s390x/cpu_features.c
> index c78a189..6ec2bfc 100644
> --- a/target-s390x/cpu_features.c
> +++ b/target-s390x/cpu_features.c
> @@ -12,6 +12,7 @@
>  
>  #include "qemu/osdep.h"
>  #include "cpu_features.h"
> +#include "gen-features.h"
>  
>  #define FEAT_INIT(_name, _type, _bit, _desc) \
>      {                                                \
> @@ -321,14 +322,55 @@ void s390_add_from_feat_block(S390FeatBitmap features, S390FeatType type,
>      }
>  }
>  
> -void s390_feat_bitmap_to_ascii(const S390FeatBitmap bitmap, void *opaque,
> +void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
>                                 void (*fn)(const char *name, void *opaque))
>  {
> +    S390FeatBitmap bitmap, tmp;
> +    S390FeatGroup group;
>      S390Feat feat;
>  
> +    bitmap_copy(bitmap, features, S390_FEAT_MAX);
> +
> +    /* process whole groups first */
> +    for (group = 0; group < S390_FEAT_GROUP_MAX; group++) {
> +        const S390FeatGroupDef *def = s390_feat_group_def(group);
> +
> +        bitmap_and(tmp, bitmap, def->feat, S390_FEAT_MAX);
> +        if (bitmap_equal(tmp, def->feat, S390_FEAT_MAX)) {
> +            bitmap_andnot(bitmap, bitmap, def->feat, S390_FEAT_MAX);
> +            (*fn)(def->name, opaque);

Maybe simply write
               fn(dev->name, opaque);
instead?

 Thomas

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-21 17:01   ` David Hildenbrand
@ 2016-06-21 20:33     ` Eduardo Habkost
  2016-06-21 21:09       ` Jiri Denemark
  0 siblings, 1 reply; 53+ messages in thread
From: Eduardo Habkost @ 2016-06-21 20:33 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: qemu-devel, jdenemar, imammedo, cornelia.huck, borntraeger,
	fiuczy, mimu, libvir-list

On Tue, Jun 21, 2016 at 07:01:44PM +0200, David Hildenbrand wrote:
> > (CCing libvirt people)
> > 
> > On Tue, Jun 21, 2016 at 03:02:05PM +0200, David Hildenbrand wrote:
> > > This is our second attempt to implement CPU models for s390x. We realized
> > > that we also want to have features exposed via the CPU model. While doing
> > > that we realized that we want to have a better interface for libvirt.  
> > 
> > Before getting into the details, I would like to clarify how the
> > following could be accomplished using the new commands:
> > 
> > Example:
> > 
> > 1) User configures libvirt with:
> >    <cpu match='exact'>
> >        <model fallback='forbid'>Westmere</model>
> >        <feature policy='require' name='aes'/>
> >    </cpu>
> > 2) libvirt will translate that to:
> >    "-cpu Westmere,+aes" or "-cpu Westmere,aes=on"
> > 3) libvirt wants to know if "-cpu Westmere,aes=on" is usable in
> >    the current host, before trying to start the VM.
> > 
> > How exactly would this be done using the new commands?
> 
> Hi Eduardo,
> 
> thanks for having a look - highly appreciated that you actually map this
> to libvirt requirements!
> 
> That would map to a compare operation between "host" and "Westmere,aes=on".
> 
> Host could at that point already be expanded by libvirt. Doesn't matter at that
> point.
> 
> If the result is "identica"l or "superset", it is runnable. If the result is
> "subset" or "incompatible", details about the responsible properties is
> indicated. (I actually took that idea from your patch for indicating
> runnability).

So, I have two worries about the proposal:


1) "query-cpu-model-expansion model=host" vs "query-host-cpu":

I still don't think we want to set in stone that "the result the
guest sees when using -cpu host" is always the same as "what the
host supports running".

For example: let's assume a given architecture have two features
(A and B) that are both supported by the host but can never be
enabled together. For actual "-cpu host" usage, QEMU would have
to choose between enabling A and B. For querying host
capabilities, we still want to let management software know that
either A or B are supported.

If we don't mind adding multiple new QMP commands in this series,
I don't see why not having a separate "query-host-cpu" command so
the semantics of each command are very clear. Then
query-cpu-definitions/query-cpu-model-expansion would be about
"what you really get when using -cpu <model>", and
"query-host-cpu" would be about "what this hosts supports
running".


2) Requiring a running QEMU instance to run
   query-cpu-model-comparison

With my previous query-host-cpu proposal, the task of comparing
the configuration requested by the user with host capabilities
can be done directly by libvirt. This way, no extra QEMU instance
needs to be run before starting a VM.

In my example above, if query-cpu-model-comparison were not
required, libvirt could run "query-cpu-expansion model=host" or
"query-host-cpu" once at boot, and just check if "Westmere" is
runnable and "aes" is present in the host data. With
query-cpu-model-comparison, QEMU needs to be run one more time
before starting a VM.

I don't know if requiring running a new QEMU instance just to
check if a CPU config is runnable would be acceptable for
libvirt. I will let the libvirt people answer that.

I still like the query-cpu-model-comparison proposal, because it
would allow us to extend the data returned by
query-cpu-model-expansion without requiring libvirt changes. It
may be the best log-term option, but probably only after we add a
mechanism to allow the VM to be configured after running a few
QMP commands, without re-running QEMU.

-- 
Eduardo

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-21 16:44 ` [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features Eduardo Habkost
  2016-06-21 17:01   ` David Hildenbrand
@ 2016-06-21 20:56   ` Jiri Denemark
  2016-06-22  6:43     ` David Hildenbrand
  2016-06-22 18:21     ` Eduardo Habkost
  1 sibling, 2 replies; 53+ messages in thread
From: Jiri Denemark @ 2016-06-21 20:56 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: David Hildenbrand, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list

On Tue, Jun 21, 2016 at 13:44:31 -0300, Eduardo Habkost wrote:
> (CCing libvirt people)
> 
> On Tue, Jun 21, 2016 at 03:02:05PM +0200, David Hildenbrand wrote:
> > This is our second attempt to implement CPU models for s390x. We realized
> > that we also want to have features exposed via the CPU model. While doing
> > that we realized that we want to have a better interface for libvirt.
> 
> Before getting into the details, I would like to clarify how the
> following could be accomplished using the new commands:
> 
> Example:
> 
> 1) User configures libvirt with:
>    <cpu match='exact'>
>        <model fallback='forbid'>Westmere</model>
>        <feature policy='require' name='aes'/>
>    </cpu>
> 2) libvirt will translate that to:
>    "-cpu Westmere,+aes" or "-cpu Westmere,aes=on"
> 3) libvirt wants to know if "-cpu Westmere,aes=on" is usable in
>    the current host, before trying to start the VM.

While this is what libvirt currently does, I don't think it's necessary
to keep doing that... see below.

> > a) "query-cpu-model-expansion" - tell us what the "host" or a migration
> >    unsafe model looks like. Either falling back to a stable model or
> >    completely exposing all properties. We are interested in stable models.
> > b) "query-cpu-model-comparison" - tell us how two CPU models compare,
> >     indicating which properties were responsible for the decision.
> > c) "query-cpu-model-baseline" - create a new model out of two models,
> >     taking a requested level of stability into account.

This looks like it copies current libvirt APIs, which I think is not a
very good idea. Both CPU compare and baseline APIs in libvirt will need
to be changed (or rather new APIs with similar functionality added) to
become useful. I think we should first focus on making guest CPU
configuration work the way it should work. For that I think we need some
higher level commands.

Let me sum up what libvirt is doing (or will be doing) with guest
CPUs... Libvirt supports three guest CPU configuration modes:

- host-passthrough -- this is easy, it's just asking for "-cpu host" and
  no fancy commands are required.

- host-model -- for this we need to know what CPU configuration we need
  to ask for to get as close to the host CPU as possible while being
  able to ask for the exact same CPU on a different host (after
  migration). And we need to be able to ask for this at probing time
  (when libvirtd starts rather than when starting a new domain) using
  "-machine none,accel=kvm:tcg", that is without actually creating any
  guest CPU. This is what Eduardo's query-host-cpu QMP command is useful
  for. In x86 world we could just query the guest CPU after running QEMU
  with "-cpu host", but that's unusable with "-machine none", which is
  why another way of getting this info is needed.

- custom -- the XML specifies an exact guest CPU configuration. We don't
  really need to know if that exact CPU is runnable on the current host
  in advance, we can just try to start the domain, check if the guest
  CPU matches what we asked for, and we may kill QEMU if the CPU does
  not meet the specification. Of course, higher level management wants
  to know a set of host where it can run a given domain for scheduling
  purposes, but since they logically want to avoid tons of different CPU
  configs, they would just stick the CPU models predefined by QEMU. Thus
  giving them a way of checking what CPU models can be run on a given
  host with a given QEMU (using the unavailable features stuff for
  query-cpu-definitions usable with "-machine none") should be enough
  and it's even better than having to ask for every single CPU model,
  which is what they need to do now.

There are configuration options which are somewhere between host-model
and custom, but they don't bring more requirements in addition to what
both of them needs.

This was basically all about starting a new domain. When the domain
successfully starts, we need to make sure the guest CPU does not change
during save/restore or migration to another host. To achieve this, we
need the same checking we need for custom mode, i.e., whether the guest
CPU we got is what we asked for. In addition to this, we need a way to
ask QEMU what the guest CPU looks like so that we can store it in the
domain XML and ask for it during migration.

I think all of this should be pretty much architecture agnostic. Of
course the actual data would be quite different fro each architecture,
but I believe the entry points could fit all. Or did I miss anything?

Jirka

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-21 20:33     ` Eduardo Habkost
@ 2016-06-21 21:09       ` Jiri Denemark
  2016-06-21 21:22         ` Eduardo Habkost
  2016-06-22  6:51         ` [Qemu-devel] " David Hildenbrand
  0 siblings, 2 replies; 53+ messages in thread
From: Jiri Denemark @ 2016-06-21 21:09 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: David Hildenbrand, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list

On Tue, Jun 21, 2016 at 17:33:09 -0300, Eduardo Habkost wrote:
> On Tue, Jun 21, 2016 at 07:01:44PM +0200, David Hildenbrand wrote:
> > > (CCing libvirt people)
> > > 
> > > On Tue, Jun 21, 2016 at 03:02:05PM +0200, David Hildenbrand wrote:
> > > > This is our second attempt to implement CPU models for s390x. We realized
> > > > that we also want to have features exposed via the CPU model. While doing
> > > > that we realized that we want to have a better interface for libvirt.  
> > > 
> > > Before getting into the details, I would like to clarify how the
> > > following could be accomplished using the new commands:
> > > 
> > > Example:
> > > 
> > > 1) User configures libvirt with:
> > >    <cpu match='exact'>
> > >        <model fallback='forbid'>Westmere</model>
> > >        <feature policy='require' name='aes'/>
> > >    </cpu>
> > > 2) libvirt will translate that to:
> > >    "-cpu Westmere,+aes" or "-cpu Westmere,aes=on"
> > > 3) libvirt wants to know if "-cpu Westmere,aes=on" is usable in
> > >    the current host, before trying to start the VM.
> > > 
> > > How exactly would this be done using the new commands?
> > 
> > Hi Eduardo,
> > 
> > thanks for having a look - highly appreciated that you actually map this
> > to libvirt requirements!
> > 
> > That would map to a compare operation between "host" and "Westmere,aes=on".
> > 
> > Host could at that point already be expanded by libvirt. Doesn't matter at that
> > point.
> > 
> > If the result is "identica"l or "superset", it is runnable. If the result is
> > "subset" or "incompatible", details about the responsible properties is
> > indicated. (I actually took that idea from your patch for indicating
> > runnability).
> 
> So, I have two worries about the proposal:
> 
> 
> 1) "query-cpu-model-expansion model=host" vs "query-host-cpu":
> 
> I still don't think we want to set in stone that "the result the
> guest sees when using -cpu host" is always the same as "what the
> host supports running".
> 
> For example: let's assume a given architecture have two features
> (A and B) that are both supported by the host but can never be
> enabled together. For actual "-cpu host" usage, QEMU would have
> to choose between enabling A and B. For querying host
> capabilities, we still want to let management software know that
> either A or B are supported.

What libvirt is really interested in is the guest CPU which would be
used with -cpu host. This is actually what I thought query-host-cpu was
all about. Perhaps because there's no difference for x86.

> 2) Requiring a running QEMU instance to run
>    query-cpu-model-comparison
> 
> With my previous query-host-cpu proposal, the task of comparing
> the configuration requested by the user with host capabilities
> can be done directly by libvirt. This way, no extra QEMU instance
> needs to be run before starting a VM.

I think we can just easily get around this by not comparing a guest CPU
to host (except for the explicit virConnectCompareCPU, which is not very
useful in its current form anyway).

Jirka

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-21 21:09       ` Jiri Denemark
@ 2016-06-21 21:22         ` Eduardo Habkost
  2016-06-22  7:11           ` [Qemu-devel] [libvirt] " Jiri Denemark
  2016-06-22  6:51         ` [Qemu-devel] " David Hildenbrand
  1 sibling, 1 reply; 53+ messages in thread
From: Eduardo Habkost @ 2016-06-21 21:22 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list

On Tue, Jun 21, 2016 at 11:09:49PM +0200, Jiri Denemark wrote:
[...]
> > 1) "query-cpu-model-expansion model=host" vs "query-host-cpu":
> > 
> > I still don't think we want to set in stone that "the result the
> > guest sees when using -cpu host" is always the same as "what the
> > host supports running".
> > 
> > For example: let's assume a given architecture have two features
> > (A and B) that are both supported by the host but can never be
> > enabled together. For actual "-cpu host" usage, QEMU would have
> > to choose between enabling A and B. For querying host
> > capabilities, we still want to let management software know that
> > either A or B are supported.
> 
> What libvirt is really interested in is the guest CPU which would be
> used with -cpu host. This is actually what I thought query-host-cpu was
> all about. Perhaps because there's no difference for x86.

In that case, I think it makes sense to just extend
query-cpu-definitions or use "query-cpu-model-expansion
model=host" instead of a query-host-cpu command.

Probably query-cpu-model-expansion is better than just extending
query-cpu-definitions, because it would allow the expansion of
extra CPU options, like "host,migratable=off".

-- 
Eduardo

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

* Re: [Qemu-devel] [RFC 06/28] s390x/cpumodel: introduce CPU feature group definitions
  2016-06-21 20:14   ` Thomas Huth
@ 2016-06-22  6:19     ` David Hildenbrand
  2016-06-22 18:00       ` Eduardo Habkost
  0 siblings, 1 reply; 53+ messages in thread
From: David Hildenbrand @ 2016-06-22  6:19 UTC (permalink / raw)
  To: Thomas Huth
  Cc: qemu-devel, ehabkost, borntraeger, fiuczy, cornelia.huck,
	imammedo, jdenemar, mimu

> On 21.06.2016 15:02, David Hildenbrand wrote:
> > Let's use the generated groups to create feature group representations for
> > the user. These groups can later be used to enable/disable multiple
> > features in one shot and will be used to reduce the amount of reported
> > features to the user if all subfeatures are in place.
> > 
> > Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
> > ---
> >  target-s390x/cpu_features.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
> >  target-s390x/cpu_features.h | 23 +++++++++++++++++++++++
> >  2 files changed, 66 insertions(+), 1 deletion(-)
> > 
> > diff --git a/target-s390x/cpu_features.c b/target-s390x/cpu_features.c
> > index c78a189..6ec2bfc 100644
> > --- a/target-s390x/cpu_features.c
> > +++ b/target-s390x/cpu_features.c
> > @@ -12,6 +12,7 @@
> >  
> >  #include "qemu/osdep.h"
> >  #include "cpu_features.h"
> > +#include "gen-features.h"
> >  
> >  #define FEAT_INIT(_name, _type, _bit, _desc) \
> >      {                                                \
> > @@ -321,14 +322,55 @@ void s390_add_from_feat_block(S390FeatBitmap features, S390FeatType type,
> >      }
> >  }
> >  
> > -void s390_feat_bitmap_to_ascii(const S390FeatBitmap bitmap, void *opaque,
> > +void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
> >                                 void (*fn)(const char *name, void *opaque))
> >  {
> > +    S390FeatBitmap bitmap, tmp;
> > +    S390FeatGroup group;
> >      S390Feat feat;
> >  
> > +    bitmap_copy(bitmap, features, S390_FEAT_MAX);
> > +
> > +    /* process whole groups first */
> > +    for (group = 0; group < S390_FEAT_GROUP_MAX; group++) {
> > +        const S390FeatGroupDef *def = s390_feat_group_def(group);
> > +
> > +        bitmap_and(tmp, bitmap, def->feat, S390_FEAT_MAX);
> > +        if (bitmap_equal(tmp, def->feat, S390_FEAT_MAX)) {
> > +            bitmap_andnot(bitmap, bitmap, def->feat, S390_FEAT_MAX);
> > +            (*fn)(def->name, opaque);  
> 
> Maybe simply write
>                fn(dev->name, opaque);
> instead?

Will that work? As fn is a pointer I am not a 100% sure. If so, I'll change it!

Thanks!

David

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-21 20:56   ` Jiri Denemark
@ 2016-06-22  6:43     ` David Hildenbrand
  2016-06-22 18:21     ` Eduardo Habkost
  1 sibling, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-22  6:43 UTC (permalink / raw)
  To: Jiri Denemark
  Cc: Eduardo Habkost, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list

> On Tue, Jun 21, 2016 at 13:44:31 -0300, Eduardo Habkost wrote:
> > (CCing libvirt people)
> > 
> > On Tue, Jun 21, 2016 at 03:02:05PM +0200, David Hildenbrand wrote:
> > > This is our second attempt to implement CPU models for s390x. We realized
> > > that we also want to have features exposed via the CPU model. While doing
> > > that we realized that we want to have a better interface for libvirt.
> > 
> > Before getting into the details, I would like to clarify how the
> > following could be accomplished using the new commands:
> > 
> > Example:
> > 
> > 1) User configures libvirt with:
> >    <cpu match='exact'>
> >        <model fallback='forbid'>Westmere</model>
> >        <feature policy='require' name='aes'/>
> >    </cpu>
> > 2) libvirt will translate that to:
> >    "-cpu Westmere,+aes" or "-cpu Westmere,aes=on"
> > 3) libvirt wants to know if "-cpu Westmere,aes=on" is usable in
> >    the current host, before trying to start the VM.
> 
> While this is what libvirt currently does, I don't think it's necessary
> to keep doing that... see below.
> 
> > > a) "query-cpu-model-expansion" - tell us what the "host" or a migration
> > >    unsafe model looks like. Either falling back to a stable model or
> > >    completely exposing all properties. We are interested in stable models.
> > > b) "query-cpu-model-comparison" - tell us how two CPU models compare,
> > >     indicating which properties were responsible for the decision.
> > > c) "query-cpu-model-baseline" - create a new model out of two models,
> > >     taking a requested level of stability into account.
> 
> This looks like it copies current libvirt APIs, which I think is not a
> very good idea. Both CPU compare and baseline APIs in libvirt will need
> to be changed (or rather new APIs with similar functionality added) to
> become useful. I think we should first focus on making guest CPU
> configuration work the way it should work. For that I think we need some
> higher level commands.

Hi Jiri,

thanks for your reply!

Please be aware that we (s390x) have no libvirt cpu model support in place. We
are coming up with a solution that solves our problems, but instead of tagging
all interfaces with "s390x" we want interfaces that everybody might use.

I understand that x86 has some very advanced libvirt CPU model magic in place.
You can still stick to what you have right now. It doesn't work for us.

So we provide 3 basic functions (baseline, compare, expand) that can easily by
added for s390x into the CPU model. So I don't see a problem introducing
these operations in libvirt - it just works without any magic and knowledge
about features and models in libvirt.

In the end it keeps the CPU model where it belongs (QEMU) and allows us to
just fit in fine into the libvirt CPU model world that was heavily inspired
by x86 (an I can tell you, that is a very challenging task).

But - of course - we have to do some additional queries on a QEMU instance. I
don't think that this is a problem (at least not for s390x).

> 
> Let me sum up what libvirt is doing (or will be doing) with guest
> CPUs... Libvirt supports three guest CPU configuration modes:

One important thing to mention here is that all of these was inspired by x86.
Some stuff doesn't even make sense on s390x ("mimic the real host"), as
it would even in practice never be possible. See my reply to Eduards patchset
I'll post later.

We want to focus on the real use cases and I think they are
- Making sure models ("Guest API") doesn't change during migration
- Allowing the user to use a certain CPU model
- Baselining/Comparing/Using the -cpu host model


> 
> - host-passthrough -- this is easy, it's just asking for "-cpu host" and
>   no fancy commands are required.

This should map to expanding the host model in our case.

> 
> - host-model -- for this we need to know what CPU configuration we need
>   to ask for to get as close to the host CPU as possible while being
>   able to ask for the exact same CPU on a different host (after
>   migration). And we need to be able to ask for this at probing time
>   (when libvirtd starts rather than when starting a new domain) using
>   "-machine none,accel=kvm:tcg", that is without actually creating any
>   guest CPU. This is what Eduardo's query-host-cpu QMP command is useful
>   for. In x86 world we could just query the guest CPU after running QEMU
>   with "-cpu host", but that's unusable with "-machine none", which is
>   why another way of getting this info is needed.

Again, we will be relying on "-cpu host" here, because the real host model
will never be possible to be fordwarded on s390x. And what's the use case
anyway? Does not make sense on s390x as far as I can tell.

We want to know what we are able to virtualize, not build up some strange
model that won't even be able to run.

> 
> - custom -- the XML specifies an exact guest CPU configuration. We don't
>   really need to know if that exact CPU is runnable on the current host
>   in advance, we can just try to start the domain, check if the guest
>   CPU matches what we asked for, and we may kill QEMU if the CPU does
>   not meet the specification. Of course, higher level management wants
>   to know a set of host where it can run a given domain for scheduling
>   purposes, but since they logically want to avoid tons of different CPU
>   configs, they would just stick the CPU models predefined by QEMU. Thus
>   giving them a way of checking what CPU models can be run on a given
>   host with a given QEMU (using the unavailable features stuff for
>   query-cpu-definitions usable with "-machine none") should be enough
>   and it's even better than having to ask for every single CPU model,
>   which is what they need to do now.

Which is simply necessary when having to care about a lot of feature
variability. Please keep the requirements in our cover letter in place.

It's not that simple when
a) having to update the "flexible" models over time (e.g. adding stuff to "z13")
b) nobody really using the "stable" models like "z13-base", but interested in
   "z13" +  feature changes

I agree that CPU models defined in QEMU are the place to go - which is why we
keep our default here.

And also keep in mind that I think your extension to query-cpu-definitions to
detect runability makes total sense, it is just not enough for us having to care
about changable "default" models.

Let's say we report a "z13" via that interface as runnable? It doesn't
mean a thing because that model could look different on e.g. another QEMU
version we're migrating to. To check the real deal, we have to expand that model
and then verify if it is runnable. In essence, runnability information
contained in query-cpu-definitions only makes sense for migration-safe models.

Of course, that could somehow be done using the "expansion" interface only
in combination with "query-cpu-definitions". But it doesn't solve the other
problems we're dealing with and just introduces some unnecessary complexity
(for us!).

> 
> There are configuration options which are somewhere between host-model
> and custom, but they don't bring more requirements in addition to what
> both of them needs.
> 
> This was basically all about starting a new domain. When the domain
> successfully starts, we need to make sure the guest CPU does not change
> during save/restore or migration to another host. To achieve this, we
> need the same checking we need for custom mode, i.e., whether the guest
> CPU we got is what we asked for. In addition to this, we need a way to
> ask QEMU what the guest CPU looks like so that we can store it in the
> domain XML and ask for it during migration.

Exactly, that's where our "expansion" interface comes into play.

If the user asks for a "z13", we will expand it to a
"z13-base,feata=on,featb=on" ...

So we can guarantee that we are always dealing with a migration safe variant.

> 
> I think all of this should be pretty much architecture agnostic. Of
> course the actual data would be quite different fro each architecture,
> but I believe the entry points could fit all. Or did I miss anything?
> 

These are also the use cases I looked into, with the addition of being able to
baseline and compare CPU models (including the "host" model).

Thanks again for having a look!

David

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-21 21:09       ` Jiri Denemark
  2016-06-21 21:22         ` Eduardo Habkost
@ 2016-06-22  6:51         ` David Hildenbrand
  2016-06-22  7:26           ` Jiri Denemark
  1 sibling, 1 reply; 53+ messages in thread
From: David Hildenbrand @ 2016-06-22  6:51 UTC (permalink / raw)
  To: Jiri Denemark
  Cc: Eduardo Habkost, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list

> On Tue, Jun 21, 2016 at 17:33:09 -0300, Eduardo Habkost wrote:
> > On Tue, Jun 21, 2016 at 07:01:44PM +0200, David Hildenbrand wrote:  
> > > > (CCing libvirt people)
> > > > 
> > > > On Tue, Jun 21, 2016 at 03:02:05PM +0200, David Hildenbrand wrote:  
> > > > > This is our second attempt to implement CPU models for s390x. We realized
> > > > > that we also want to have features exposed via the CPU model. While doing
> > > > > that we realized that we want to have a better interface for libvirt.    
> > > > 
> > > > Before getting into the details, I would like to clarify how the
> > > > following could be accomplished using the new commands:
> > > > 
> > > > Example:
> > > > 
> > > > 1) User configures libvirt with:
> > > >    <cpu match='exact'>
> > > >        <model fallback='forbid'>Westmere</model>
> > > >        <feature policy='require' name='aes'/>
> > > >    </cpu>
> > > > 2) libvirt will translate that to:
> > > >    "-cpu Westmere,+aes" or "-cpu Westmere,aes=on"
> > > > 3) libvirt wants to know if "-cpu Westmere,aes=on" is usable in
> > > >    the current host, before trying to start the VM.
> > > > 
> > > > How exactly would this be done using the new commands?  
> > > 
> > > Hi Eduardo,
> > > 
> > > thanks for having a look - highly appreciated that you actually map this
> > > to libvirt requirements!
> > > 
> > > That would map to a compare operation between "host" and "Westmere,aes=on".
> > > 
> > > Host could at that point already be expanded by libvirt. Doesn't matter at that
> > > point.
> > > 
> > > If the result is "identica"l or "superset", it is runnable. If the result is
> > > "subset" or "incompatible", details about the responsible properties is
> > > indicated. (I actually took that idea from your patch for indicating
> > > runnability).  
> > 
> > So, I have two worries about the proposal:
> > 
> > 
> > 1) "query-cpu-model-expansion model=host" vs "query-host-cpu":
> > 
> > I still don't think we want to set in stone that "the result the
> > guest sees when using -cpu host" is always the same as "what the
> > host supports running".
> > 
> > For example: let's assume a given architecture have two features
> > (A and B) that are both supported by the host but can never be
> > enabled together. For actual "-cpu host" usage, QEMU would have
> > to choose between enabling A and B. For querying host
> > capabilities, we still want to let management software know that
> > either A or B are supported.  
> 
> What libvirt is really interested in is the guest CPU which would be
> used with -cpu host. This is actually what I thought query-host-cpu was
> all about. Perhaps because there's no difference for x86.

That's also what I had in mind first. Let me explain why they are not the same
on s390x and why it is problematic (actually both types are not the same!):

1. Certain CPU features are only valid for LPAR guests, they can't be
virtualized for KVM guests (remember that we always have at least one level of
virtualization on s390x). So we will never be able to provide these features to
a KVM guest, therefore we will never be able to completely mimic the real host
model.

2. We have a whole lot of unpublished features. We would have to include them in
the "real host model", but we can't. For the "host" model, this is not a
problem, because we simply don't virtualize them. But the "real host model"
would then vary between say QEMZ versions, which looks really strage, because
in essance, QEMU/KVM looks like the wrong interface to query for a "real host
model".

3. We don't have the kernel interfaces in place to query the "real host model".
We can only query what we are able to virtualize. And that is indeed different
compared to what I said previously.

And as I can't see any use case for s390x, we most probably will never be able
to support the interface you are suggesting here. Which is fine, if it makes
sense for x86.

> 
> > 2) Requiring a running QEMU instance to run
> >    query-cpu-model-comparison
> > 
> > With my previous query-host-cpu proposal, the task of comparing
> > the configuration requested by the user with host capabilities
> > can be done directly by libvirt. This way, no extra QEMU instance
> > needs to be run before starting a VM.  
> 
> I think we can just easily get around this by not comparing a guest CPU
> to host (except for the explicit virConnectCompareCPU, which is not very
> useful in its current form anyway).

If there is some flexible way around that, great. But I think we (s390x) could
life without this additional query.


So your first concern is valid, and if you really need this information, you
should probably really create a new interface. Your second concern should not
be trivial for now. We don't want to optimize for total speed at that point.

David

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

* Re: [Qemu-devel] [libvirt] [RFC 00/28] s390x CPU models: exposing features
  2016-06-21 21:22         ` Eduardo Habkost
@ 2016-06-22  7:11           ` Jiri Denemark
  2016-06-22  7:14             ` David Hildenbrand
  0 siblings, 1 reply; 53+ messages in thread
From: Jiri Denemark @ 2016-06-22  7:11 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: David Hildenbrand, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list

On Tue, Jun 21, 2016 at 18:22:30 -0300, Eduardo Habkost wrote:
> On Tue, Jun 21, 2016 at 11:09:49PM +0200, Jiri Denemark wrote:
> [...]
> > > 1) "query-cpu-model-expansion model=host" vs "query-host-cpu":
> > > 
> > > I still don't think we want to set in stone that "the result the
> > > guest sees when using -cpu host" is always the same as "what the
> > > host supports running".
> > > 
> > > For example: let's assume a given architecture have two features
> > > (A and B) that are both supported by the host but can never be
> > > enabled together. For actual "-cpu host" usage, QEMU would have
> > > to choose between enabling A and B. For querying host
> > > capabilities, we still want to let management software know that
> > > either A or B are supported.
> > 
> > What libvirt is really interested in is the guest CPU which would be
> > used with -cpu host. This is actually what I thought query-host-cpu was
> > all about. Perhaps because there's no difference for x86.
> 
> In that case, I think it makes sense to just extend
> query-cpu-definitions or use "query-cpu-model-expansion
> model=host" instead of a query-host-cpu command.
> 
> Probably query-cpu-model-expansion is better than just extending
> query-cpu-definitions, because it would allow the expansion of
> extra CPU options, like "host,migratable=off".

Yeah, this would be even better.

Jirka

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

* Re: [Qemu-devel] [libvirt] [RFC 00/28] s390x CPU models: exposing features
  2016-06-22  7:11           ` [Qemu-devel] [libvirt] " Jiri Denemark
@ 2016-06-22  7:14             ` David Hildenbrand
  0 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-22  7:14 UTC (permalink / raw)
  To: Jiri Denemark
  Cc: Eduardo Habkost, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list

> On Tue, Jun 21, 2016 at 18:22:30 -0300, Eduardo Habkost wrote:
> > On Tue, Jun 21, 2016 at 11:09:49PM +0200, Jiri Denemark wrote:
> > [...]  
> > > > 1) "query-cpu-model-expansion model=host" vs "query-host-cpu":
> > > > 
> > > > I still don't think we want to set in stone that "the result the
> > > > guest sees when using -cpu host" is always the same as "what the
> > > > host supports running".
> > > > 
> > > > For example: let's assume a given architecture have two features
> > > > (A and B) that are both supported by the host but can never be
> > > > enabled together. For actual "-cpu host" usage, QEMU would have
> > > > to choose between enabling A and B. For querying host
> > > > capabilities, we still want to let management software know that
> > > > either A or B are supported.  
> > > 
> > > What libvirt is really interested in is the guest CPU which would be
> > > used with -cpu host. This is actually what I thought query-host-cpu was
> > > all about. Perhaps because there's no difference for x86.  
> > 
> > In that case, I think it makes sense to just extend
> > query-cpu-definitions or use "query-cpu-model-expansion
> > model=host" instead of a query-host-cpu command.
> > 
> > Probably query-cpu-model-expansion is better than just extending
> > query-cpu-definitions, because it would allow the expansion of
> > extra CPU options, like "host,migratable=off".  
> 
> Yeah, this would be even better.
> 
> Jirka
> 

Please be aware that we don't have anything like that on s390x, but
I prepared for that requirement by being able to tell
query-cpu-model-expansion how to expand (full, migratable, stable).
Actually full and migratable looks the same on s390x.

The plan for us is to rely on "stable" most of the time, full and migratable
might be what you're looking for.

David

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-22  6:51         ` [Qemu-devel] " David Hildenbrand
@ 2016-06-22  7:26           ` Jiri Denemark
  2016-06-22  7:34             ` David Hildenbrand
  0 siblings, 1 reply; 53+ messages in thread
From: Jiri Denemark @ 2016-06-22  7:26 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: Eduardo Habkost, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list

On Wed, Jun 22, 2016 at 08:51:40 +0200, David Hildenbrand wrote:
> > On Tue, Jun 21, 2016 at 17:33:09 -0300, Eduardo Habkost wrote:
> > > On Tue, Jun 21, 2016 at 07:01:44PM +0200, David Hildenbrand wrote:  
> > > I still don't think we want to set in stone that "the result the
> > > guest sees when using -cpu host" is always the same as "what the
> > > host supports running".
> > > 
> > > For example: let's assume a given architecture have two features
> > > (A and B) that are both supported by the host but can never be
> > > enabled together. For actual "-cpu host" usage, QEMU would have
> > > to choose between enabling A and B. For querying host
> > > capabilities, we still want to let management software know that
> > > either A or B are supported.  
> > 
> > What libvirt is really interested in is the guest CPU which would be
> > used with -cpu host. This is actually what I thought query-host-cpu was
> > all about. Perhaps because there's no difference for x86.
> 
> That's also what I had in mind first. Let me explain why they are not the same
> on s390x and why it is problematic (actually both types are not the same!):
> 
> 1. Certain CPU features are only valid for LPAR guests, they can't be
> virtualized for KVM guests (remember that we always have at least one level of
> virtualization on s390x). So we will never be able to provide these features to
> a KVM guest, therefore we will never be able to completely mimic the real host
> model.
> 
> 2. We have a whole lot of unpublished features. We would have to include them in
> the "real host model", but we can't. For the "host" model, this is not a
> problem, because we simply don't virtualize them. But the "real host model"
> would then vary between say QEMZ versions, which looks really strage, because
> in essance, QEMU/KVM looks like the wrong interface to query for a "real host
> model".
> 
> 3. We don't have the kernel interfaces in place to query the "real host model".
> We can only query what we are able to virtualize. And that is indeed different
> compared to what I said previously.
> 
> And as I can't see any use case for s390x, we most probably will never be able
> to support the interface you are suggesting here. Which is fine, if it makes
> sense for x86.

Well, as I said I always thought about query-host-cpu as a way to get
the CPU configuration QEMU would provide with -cpu host. Thanks to this
discussion I realized its semantics is different and thus what I really
need is actually the command you suggested, i.e.,
query-cpu-model-expansion.

> > > 2) Requiring a running QEMU instance to run
> > >    query-cpu-model-comparison
> > > 
> > > With my previous query-host-cpu proposal, the task of comparing
> > > the configuration requested by the user with host capabilities
> > > can be done directly by libvirt. This way, no extra QEMU instance
> > > needs to be run before starting a VM.  
> > 
> > I think we can just easily get around this by not comparing a guest CPU
> > to host (except for the explicit virConnectCompareCPU, which is not very
> > useful in its current form anyway).
> 
> If there is some flexible way around that, great. But I think we (s390x) could
> life without this additional query.

So if I understand correctly, you say you don't need the API to compare
guest CPU to host CPU, right? If so, that's exactly what I said too.

Jirka

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-22  7:26           ` Jiri Denemark
@ 2016-06-22  7:34             ` David Hildenbrand
  2016-06-22  7:53               ` Jiri Denemark
  0 siblings, 1 reply; 53+ messages in thread
From: David Hildenbrand @ 2016-06-22  7:34 UTC (permalink / raw)
  To: Jiri Denemark
  Cc: Eduardo Habkost, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list


> > > > 2) Requiring a running QEMU instance to run
> > > >    query-cpu-model-comparison
> > > > 
> > > > With my previous query-host-cpu proposal, the task of comparing
> > > > the configuration requested by the user with host capabilities
> > > > can be done directly by libvirt. This way, no extra QEMU instance
> > > > needs to be run before starting a VM.    
> > > 
> > > I think we can just easily get around this by not comparing a guest CPU
> > > to host (except for the explicit virConnectCompareCPU, which is not very
> > > useful in its current form anyway).  
> > 
> > If there is some flexible way around that, great. But I think we (s390x) could
> > life without this additional query.  
> 
> So if I understand correctly, you say you don't need the API to compare
> guest CPU to host CPU, right? If so, that's exactly what I said too.
> 

I think the coffee didn't do its work already :) . I wanted to write that we can
_with_ this additional query. Meaning the involved overhead would be ok - in my
opinion for s390x.

What we could do to avoid one compare operation would be:

a) Expand the host model
b) Expand the target model (because on s390x we could have migration unsafe
model)
c) Work with the runnability information returned via query-cpu-definitions

But as we have to do b) either way on s390x, we can directly do a compare
operation. (which makes implementation a lot simpler, because libvirt then
doesn't have to deal with any feature/model names).

David

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-22  7:34             ` David Hildenbrand
@ 2016-06-22  7:53               ` Jiri Denemark
  2016-06-22  7:54                 ` David Hildenbrand
  0 siblings, 1 reply; 53+ messages in thread
From: Jiri Denemark @ 2016-06-22  7:53 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: Eduardo Habkost, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list

On Wed, Jun 22, 2016 at 09:34:49 +0200, David Hildenbrand wrote:
> I think the coffee didn't do its work already :) . I wanted to write that we can
> _with_ this additional query. Meaning the involved overhead would be ok - in my
> opinion for s390x.
> 
> What we could do to avoid one compare operation would be:
> 
> a) Expand the host model
> b) Expand the target model (because on s390x we could have migration unsafe
> model)
> c) Work with the runnability information returned via query-cpu-definitions
> 
> But as we have to do b) either way on s390x, we can directly do a compare
> operation. (which makes implementation a lot simpler, because libvirt then
> doesn't have to deal with any feature/model names).

But why do you even need to do any comparison? Isn't it possible to let
QEMU do it when a domain starts? The thing is we should avoid doing
completely different things on each architecture.

Jirka

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-22  7:53               ` Jiri Denemark
@ 2016-06-22  7:54                 ` David Hildenbrand
  2016-06-22  8:05                   ` Jiri Denemark
  0 siblings, 1 reply; 53+ messages in thread
From: David Hildenbrand @ 2016-06-22  7:54 UTC (permalink / raw)
  To: Jiri Denemark
  Cc: Eduardo Habkost, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list

> On Wed, Jun 22, 2016 at 09:34:49 +0200, David Hildenbrand wrote:
> > I think the coffee didn't do its work already :) . I wanted to write that we can
> > _with_ this additional query. Meaning the involved overhead would be ok - in my
> > opinion for s390x.
> > 
> > What we could do to avoid one compare operation would be:
> > 
> > a) Expand the host model
> > b) Expand the target model (because on s390x we could have migration unsafe
> > model)
> > c) Work with the runnability information returned via query-cpu-definitions
> > 
> > But as we have to do b) either way on s390x, we can directly do a compare
> > operation. (which makes implementation a lot simpler, because libvirt then
> > doesn't have to deal with any feature/model names).  
> 
> But why do you even need to do any comparison? Isn't it possible to let
> QEMU do it when a domain starts? The thing is we should avoid doing
> completely different things on each architecture.
> 

Sure, QEMU will of course double check when starting the guest! So trying to
start and failing is of course an option! So no check is needed if that is
acceptable.

David

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-22  7:54                 ` David Hildenbrand
@ 2016-06-22  8:05                   ` Jiri Denemark
  2016-06-23  6:41                     ` David Hildenbrand
  0 siblings, 1 reply; 53+ messages in thread
From: Jiri Denemark @ 2016-06-22  8:05 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: Eduardo Habkost, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list

On Wed, Jun 22, 2016 at 09:54:51 +0200, David Hildenbrand wrote:
> > On Wed, Jun 22, 2016 at 09:34:49 +0200, David Hildenbrand wrote:
> > > I think the coffee didn't do its work already :) . I wanted to write that we can
> > > _with_ this additional query. Meaning the involved overhead would be ok - in my
> > > opinion for s390x.
> > > 
> > > What we could do to avoid one compare operation would be:
> > > 
> > > a) Expand the host model
> > > b) Expand the target model (because on s390x we could have migration unsafe
> > > model)
> > > c) Work with the runnability information returned via query-cpu-definitions
> > > 
> > > But as we have to do b) either way on s390x, we can directly do a compare
> > > operation. (which makes implementation a lot simpler, because libvirt then
> > > doesn't have to deal with any feature/model names).  
> > 
> > But why do you even need to do any comparison? Isn't it possible to let
> > QEMU do it when a domain starts? The thing is we should avoid doing
> > completely different things on each architecture.
> > 
> 
> Sure, QEMU will of course double check when starting the guest! So trying to
> start and failing is of course an option! So no check is needed if that is
> acceptable.

Yeah, I think it's the safest and easiest option now.

Jirka

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

* Re: [Qemu-devel] [RFC 06/28] s390x/cpumodel: introduce CPU feature group definitions
  2016-06-22  6:19     ` David Hildenbrand
@ 2016-06-22 18:00       ` Eduardo Habkost
  0 siblings, 0 replies; 53+ messages in thread
From: Eduardo Habkost @ 2016-06-22 18:00 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: Thomas Huth, qemu-devel, borntraeger, fiuczy, cornelia.huck,
	imammedo, jdenemar, mimu

On Wed, Jun 22, 2016 at 08:19:44AM +0200, David Hildenbrand wrote:
> > On 22.06.2016 15:02, David Hildenbrand wrote:
> > > Let's use the generated groups to create feature group representations for
> > > the user. These groups can later be used to enable/disable multiple
> > > features in one shot and will be used to reduce the amount of reported
> > > features to the user if all subfeatures are in place.
> > > 
> > > Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
> > > ---
> > >  target-s390x/cpu_features.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
> > >  target-s390x/cpu_features.h | 23 +++++++++++++++++++++++
> > >  2 files changed, 66 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/target-s390x/cpu_features.c b/target-s390x/cpu_features.c
> > > index c78a189..6ec2bfc 100644
> > > --- a/target-s390x/cpu_features.c
> > > +++ b/target-s390x/cpu_features.c
> > > @@ -12,6 +12,7 @@
> > >  
> > >  #include "qemu/osdep.h"
> > >  #include "cpu_features.h"
> > > +#include "gen-features.h"
> > >  
> > >  #define FEAT_INIT(_name, _type, _bit, _desc) \
> > >      {                                                \
> > > @@ -321,14 +322,55 @@ void s390_add_from_feat_block(S390FeatBitmap features, S390FeatType type,
> > >      }
> > >  }
> > >  
> > > -void s390_feat_bitmap_to_ascii(const S390FeatBitmap bitmap, void *opaque,
> > > +void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
> > >                                 void (*fn)(const char *name, void *opaque))
> > >  {
> > > +    S390FeatBitmap bitmap, tmp;
> > > +    S390FeatGroup group;
> > >      S390Feat feat;
> > >  
> > > +    bitmap_copy(bitmap, features, S390_FEAT_MAX);
> > > +
> > > +    /* process whole groups first */
> > > +    for (group = 0; group < S390_FEAT_GROUP_MAX; group++) {
> > > +        const S390FeatGroupDef *def = s390_feat_group_def(group);
> > > +
> > > +        bitmap_and(tmp, bitmap, def->feat, S390_FEAT_MAX);
> > > +        if (bitmap_equal(tmp, def->feat, S390_FEAT_MAX)) {
> > > +            bitmap_andnot(bitmap, bitmap, def->feat, S390_FEAT_MAX);
> > > +            (*fn)(def->name, opaque);  
> > 
> > Maybe simply write
> >                fn(dev->name, opaque);
> > instead?
> 
> Will that work? As fn is a pointer I am not a 100% sure. If so, I'll change it!

Both are 100% equivalent. Actually, the expression denoting the
function to be called has to be a function pointer, but (*fn)
happens to be magically converted back to a function pointer
because the spec says so.

-- 
Eduardo

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-21 20:56   ` Jiri Denemark
  2016-06-22  6:43     ` David Hildenbrand
@ 2016-06-22 18:21     ` Eduardo Habkost
  2016-06-23  6:33       ` David Hildenbrand
  1 sibling, 1 reply; 53+ messages in thread
From: Eduardo Habkost @ 2016-06-22 18:21 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list

On Tue, Jun 21, 2016 at 10:56:28PM +0200, Jiri Denemark wrote:
[...]
> Let me sum up what libvirt is doing (or will be doing) with guest
> CPUs... Libvirt supports three guest CPU configuration modes:
> 
> - host-passthrough -- this is easy, it's just asking for "-cpu host" and
>   no fancy commands are required.
> 
> - host-model -- for this we need to know what CPU configuration we need
>   to ask for to get as close to the host CPU as possible while being
>   able to ask for the exact same CPU on a different host (after
>   migration). And we need to be able to ask for this at probing time
>   (when libvirtd starts rather than when starting a new domain) using
>   "-machine none,accel=kvm:tcg", that is without actually creating any
>   guest CPU. This is what Eduardo's query-host-cpu QMP command is useful
>   for. In x86 world we could just query the guest CPU after running QEMU
>   with "-cpu host", but that's unusable with "-machine none", which is
>   why another way of getting this info is needed.

Question: KVM supports x2apic (and enables it by default) on any
host CPU, because it is all emulated by KVM. Should "host-model"
include x2apic on all hosts, or only when the host CPU has it?
("-cpu host" does include it).

Including x2apic sounds more useful, but it doesn't match the
"get as close to the host CPU as possible" part of your
description.

-- 
Eduardo

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-22 18:21     ` Eduardo Habkost
@ 2016-06-23  6:33       ` David Hildenbrand
  0 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-23  6:33 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: qemu-devel, imammedo, cornelia.huck, borntraeger, fiuczy, mimu,
	libvir-list


> Question: KVM supports x2apic (and enables it by default) on any
> host CPU, because it is all emulated by KVM. Should "host-model"
> include x2apic on all hosts, or only when the host CPU has it?
> ("-cpu host" does include it).
> 
> Including x2apic sounds more useful, but it doesn't match the
> "get as close to the host CPU as possible" part of your
> description.
> 

From a s390x point of view, our "host" model is about indicating the maximum
possible configuration we are able to virtualize, not strictly limiting it only
to the real host features.

We also have a feature called "sthyi", emulated by KVM, which might not be
around for the real "host". We will include that in "host", because otherwise
things seem to get really complicated with no obvious benefit (to me :) ).

Not sure how you want to handle that.

David

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-22  8:05                   ` Jiri Denemark
@ 2016-06-23  6:41                     ` David Hildenbrand
  0 siblings, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-23  6:41 UTC (permalink / raw)
  To: Jiri Denemark
  Cc: Eduardo Habkost, qemu-devel, imammedo, cornelia.huck,
	borntraeger, fiuczy, mimu, libvir-list

> On Wed, Jun 22, 2016 at 09:54:51 +0200, David Hildenbrand wrote:
> > > On Wed, Jun 22, 2016 at 09:34:49 +0200, David Hildenbrand wrote:  
> > > > I think the coffee didn't do its work already :) . I wanted to write that we can
> > > > _with_ this additional query. Meaning the involved overhead would be ok - in my
> > > > opinion for s390x.
> > > > 
> > > > What we could do to avoid one compare operation would be:
> > > > 
> > > > a) Expand the host model
> > > > b) Expand the target model (because on s390x we could have migration unsafe
> > > > model)
> > > > c) Work with the runnability information returned via query-cpu-definitions
> > > > 
> > > > But as we have to do b) either way on s390x, we can directly do a compare
> > > > operation. (which makes implementation a lot simpler, because libvirt then
> > > > doesn't have to deal with any feature/model names).    
> > > 
> > > But why do you even need to do any comparison? Isn't it possible to let
> > > QEMU do it when a domain starts? The thing is we should avoid doing
> > > completely different things on each architecture.
> > >   
> > 
> > Sure, QEMU will of course double check when starting the guest! So trying to
> > start and failing is of course an option! So no check is needed if that is
> > acceptable.  
> 
> Yeah, I think it's the safest and easiest option now.
> 
> Jirka
> 

Alright then, this RFC already handles that properly, so that seems to be
solved. The question now is if you guys see a fundamental problem in the way we
want to handle CPU models.

Especially
a) Having flexible, not migration safe CPU models that can be expanded to
migration safe models (using the expansion interface).

b) Letting QEMU carry out the task of comparing and baselining to be used
for e.g. for "virsh cpu-baseline" or "virsh cpu-compare".

c) Indicating the host model as the expansion of "-cpu host", e.g. for "virsh
capabilities" (which says "host" for now for us).

Also, it will be good to know if the "expansion" interface with parameters
"full" or "migratable" is really helpful to you or if I should drop that and
you will come up with an own "query-host-cpu".

We are also planning to implement the "query-cpu-definitions" runnability
information in the future, because as you said, it might be a good way to
quickly indicate runnable CPU models. But we are most likely not going to use it
for e.g. comparing or baselining or detection of runnability of a more complex
cpu model (having a lot of feature changes).

Thanks!

David

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
                   ` (28 preceding siblings ...)
  2016-06-21 16:44 ` [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features Eduardo Habkost
@ 2016-06-30  7:32 ` David Hildenbrand
  2016-06-30 15:07   ` Eduardo Habkost
  2016-07-11 10:50   ` David Hildenbrand
  29 siblings, 2 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-06-30  7:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, borntraeger, fiuczy, cornelia.huck, imammedo, jdenemar,
	mimu, libvir-list


Are there any further comments, especially on patches 23-25, introducing new
QOM interfaces?

Also, if anybody is planning to look into this, please speak up :)

Otherwise it might make sense to put this onto the next KVM call agenda.

David

> This is our second attempt to implement CPU models for s390x. We realized
> that we also want to have features exposed via the CPU model. While doing
> that we realized that we want to have a better interface for libvirt.
> 
> Unfortunately, CPU models on s390x are special and we have to take care of:
> - A CPU like z13 looks differently in various environments (under different
>   LPAR versions, under different z/VM versions, under different KVM
>   versions, export regulation) - we have _a lot_ of feature variability.
> - We still have certain features that are not published but might be
>   implemented/introduced in the future. As they are a theoretical part
>   of a CPU already, we have to find a way to model these future changes.
> - We still have certain features that are already published, but not
>   implemented. Implementation might be added in the future in KVM.
> - We heavily rely on KVM to tell us which features it can actually
>   virtualize - user space queries like "STFL(e)" give no guarantees.
> - Certain "subfeatures" were introduced in one run. In practice, they are
>   always around, but in theory, subfeatures could be dropped in the future.
> - Just because two CPU models have the same features doesn't mean they
>   are equal - some internal numbers might be different. E.g. we won't allow
>   running a z13 under a zBC12 just by turning off features.
> - We cannot blindly enable all possible features for a CPU generation,
>   the IBC "Instruction Blocking Control" in KVM will try to block
>   instructions introduced with certain features. So a CPU generation always
>   has some maximum feature set that is guaranteed to work.
> 
> It all boils down to a specific released CPU to have.
> a) A fixed feature set that we expect it to be have on every hypervisor.
> b) A variable part that depends on the hypervisor and that could be
>    extended in the future (adding not yet implemented features) that we
>    always want to enable later on.
> c) A variable part that we want to enable only if requested - nested
>    virtualization ("vsie") and assists are one example.
> 
> But, the fixed feature set is not really what we want to use as a default.
> It is just like a really minimum, stable base.
> 
> So we have
> a) A "stable" CPU model for each released CPU that will never change and
>    maps to the minimum feature set we expect to be around on all
>    hypervisors. e.g. "z13-base" or "z10EC.2-base". These are migration
>    safe.
> b) A "default" CPU model for each released CPU, that can change between
>    QEMU versions and that will always include the features we expect to
>    be around in our currently supported environments and will contain only
>    features we expect to be stable. E.g. nested virtualization will not be
>    contained in these models. These models are not migration safe, e.g
>    "z13" or "z10EC.2". The feature set can differ between QEMU versions.
> c) An internal "maximum" CPU model for each generation that tells us which
>    features were supported as a maximum back when the hardware was
>    released. This will not be exposed
> 
> To not have to replicate all CPU model changes ("new default fetaures") in
> libvirt, to not duplicate the logic about compatibility and the like,
> our approach tries to keep all the QEMU logic in libvirt and provide
> standardized interfaces for libvirt to e.g. baseline, compare. This
> allows libvirt to not have to care about any model names or feature names,
> it can just pass the data from interface to interface and report it to
> the user.
> 
> Also, libvirt might want to know what the "host" model looks like and
> convert a CPU model to a migration safe variant. For this reason, a QMP
> command is added that can create a migration safe variant of a variable
> CPU model, indicating only the delta changes done to a stable model.
> 
> So we have:
> a) "query-cpu-model-expansion" - tell us what the "host" or a migration
>    unsafe model looks like. Either falling back to a stable model or
>    completely exposing all properties. We are interested in stable models.
> b) "query-cpu-model-comparison" - tell us how two CPU models compare,
>     indicating which properties were responsible for the decision.
> c) "query-cpu-model-baseline" - create a new model out of two models,
>     taking a requested level of stability into account.
> 
> As we are aware that e.g. x86 has their own idea of a CPU model and their
> existing implementation in place, but are also looking into to ways to e.g.
> expand the "host" CPU model to a detailed representation, we designed the
> "expansion" interface to also allow that.
> 
> Comments are very welcome, but please always keep the restrictions and
> specialties in mind when suggesting some major design changes.
> 
> The header update will be replaced by a kvm-next header update as soon as
> the VSIE patches are upstream. The major KVM interface changes are already
> part of kvm-next.
> 
> The current state is available on git://github.com/cohuck/qemu on branch
> "cpumodel-s390x".
> 
> David Hildenbrand (26):
>   s390x/cpumodel: "host" and "qemu" as CPU subclasses
>   s390x/cpumodel: expose CPU class properties
>   s390x/cpumodel: generate CPU feature group lists
>   s390x/cpumodel: introduce CPU feature group definitions
>   s390x/cpumodel: register defined CPU models as subclasses
>   s390x/cpumodel: store the CPU model in the CPU instance
>   s390x/cpumodel: expose features and feature groups as properties
>   s390x/cpumodel: let the CPU model handle feature checks
>   s390x/cpumodel: check and apply the CPU model
>   s390x/sclp: factor out preparation of cpu entries
>   s390x/sclp: introduce sclp feature blocks
>   s390x/sclp: indicate sclp features
>   s390x/sclp: propagate the ibc val(lowest and unblocked ibc)
>   s390x/sclp: propagate the mha via sclp
>   s390x/sclp: propagate hmfai
>   update linux headers (CPU model)
>   s390x/kvm: allow runtime-instrumentation for "none" machine
>   s390x/kvm: implement CPU model support
>   s390x/kvm: disable host model for existing compat machines
>   s390x/kvm: let the CPU model control CMM(A)
>   qmp: add QMP interface "query-cpu-model-expansion"
>   qmp: add QMP interface "query-cpu-model-comparison"
>   qmp: add QMP interface "query-cpu-model-baseline"
>   s390x/cpumodel: implement QMP interface "query-cpu-model-expansion"
>   s390x/cpumodel: implement QMP interface "query-cpu-model-comparison"
>   s390x/cpumodel: implement QMP interface "query-cpu-model-baseline"
> 
> Michael Mueller (2):
>   s390x/cpumodel: introduce CPU features
>   s390x/cpumodel: generate CPU feature lists for CPU models
> 
>  Makefile.target                         |    2 +-
>  hw/s390x/s390-virtio-ccw.c              |    5 +
>  hw/s390x/s390-virtio.c                  |    6 +-
>  hw/s390x/sclp.c                         |   35 +-
>  include/hw/s390x/sclp.h                 |   17 +-
>  include/sysemu/arch_init.h              |   10 +
>  linux-headers/asm-s390/kvm.h            |   40 ++
>  qapi-schema.json                        |  184 ++++++
>  qmp-commands.hx                         |   18 +
>  qmp.c                                   |   22 +
>  rules.mak                               |    1 +
>  stubs/Makefile.objs                     |    3 +
>  stubs/arch-query-cpu-model-baseline.c   |   13 +
>  stubs/arch-query-cpu-model-comparison.c |   12 +
>  stubs/arch-query-cpu-model-expansion.c  |   12 +
>  target-s390x/Makefile.objs              |   22 +-
>  target-s390x/cpu-qom.h                  |    5 +
>  target-s390x/cpu.c                      |   35 +-
>  target-s390x/cpu.h                      |    5 +
>  target-s390x/cpu_features.c             |  376 +++++++++++
>  target-s390x/cpu_features.h             |  302 +++++++++
>  target-s390x/cpu_models.c               | 1055 +++++++++++++++++++++++++++++++
>  target-s390x/cpu_models.h               |  113 ++++
>  target-s390x/gen-features.c             |  587 +++++++++++++++++
>  target-s390x/helper.c                   |   29 +-
>  target-s390x/kvm.c                      |  346 +++++++++-
>  target-s390x/machine.c                  |   14 +-
>  27 files changed, 3203 insertions(+), 66 deletions(-)
>  create mode 100644 stubs/arch-query-cpu-model-baseline.c
>  create mode 100644 stubs/arch-query-cpu-model-comparison.c
>  create mode 100644 stubs/arch-query-cpu-model-expansion.c
>  create mode 100644 target-s390x/cpu_features.c
>  create mode 100644 target-s390x/cpu_features.h
>  create mode 100644 target-s390x/cpu_models.c
>  create mode 100644 target-s390x/cpu_models.h
>  create mode 100644 target-s390x/gen-features.c
> 

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-30  7:32 ` David Hildenbrand
@ 2016-06-30 15:07   ` Eduardo Habkost
  2016-07-11 10:50   ` David Hildenbrand
  1 sibling, 0 replies; 53+ messages in thread
From: Eduardo Habkost @ 2016-06-30 15:07 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: qemu-devel, borntraeger, fiuczy, cornelia.huck, imammedo,
	jdenemar, mimu, libvir-list

On Thu, Jun 30, 2016 at 09:32:04AM +0200, David Hildenbrand wrote:
> 
> Are there any further comments, especially on patches 23-25, introducing new
> QOM interfaces?
> 
> Also, if anybody is planning to look into this, please speak up :)

I am still planning to look at this (I didn't look at the
interfaces and code yet), especially the
query-cpu-model-expansion command.

-- 
Eduardo

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

* Re: [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features
  2016-06-30  7:32 ` David Hildenbrand
  2016-06-30 15:07   ` Eduardo Habkost
@ 2016-07-11 10:50   ` David Hildenbrand
  1 sibling, 0 replies; 53+ messages in thread
From: David Hildenbrand @ 2016-07-11 10:50 UTC (permalink / raw)
  To: qemu-devel
  Cc: ehabkost, libvir-list, borntraeger, fiuczy, cornelia.huck,
	imammedo, jdenemar, mimu

> Are there any further comments, especially on patches 23-25, introducing new
> QOM interfaces?

Ping, can somebody please have a look, especially on patches 23-25?
We really want to know if we can proceed with this CPU model approach.

David

> 
> Also, if anybody is planning to look into this, please speak up :)
> 
> Otherwise it might make sense to put this onto the next KVM call agenda.
> 
> David

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

end of thread, other threads:[~2016-07-11 10:50 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-21 13:02 [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 01/28] s390x/cpumodel: "host" and "qemu" as CPU subclasses David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 02/28] s390x/cpumodel: expose CPU class properties David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 03/28] s390x/cpumodel: introduce CPU features David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 04/28] s390x/cpumodel: generate CPU feature lists for CPU models David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 05/28] s390x/cpumodel: generate CPU feature group lists David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 06/28] s390x/cpumodel: introduce CPU feature group definitions David Hildenbrand
2016-06-21 20:14   ` Thomas Huth
2016-06-22  6:19     ` David Hildenbrand
2016-06-22 18:00       ` Eduardo Habkost
2016-06-21 13:02 ` [Qemu-devel] [RFC 07/28] s390x/cpumodel: register defined CPU models as subclasses David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 08/28] s390x/cpumodel: store the CPU model in the CPU instance David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 09/28] s390x/cpumodel: expose features and feature groups as properties David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 10/28] s390x/cpumodel: let the CPU model handle feature checks David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 11/28] s390x/cpumodel: check and apply the CPU model David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 12/28] s390x/sclp: factor out preparation of cpu entries David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 13/28] s390x/sclp: introduce sclp feature blocks David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 14/28] s390x/sclp: indicate sclp features David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 15/28] s390x/sclp: propagate the ibc val(lowest and unblocked ibc) David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 16/28] s390x/sclp: propagate the mha via sclp David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 17/28] s390x/sclp: propagate hmfai David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 18/28] update linux headers (CPU model) David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 19/28] s390x/kvm: allow runtime-instrumentation for "none" machine David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 20/28] s390x/kvm: implement CPU model support David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 21/28] s390x/kvm: disable host model for existing compat machines David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 22/28] s390x/kvm: let the CPU model control CMM(A) David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 23/28] qmp: add QMP interface "query-cpu-model-expansion" David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 24/28] qmp: add QMP interface "query-cpu-model-comparison" David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 25/28] qmp: add QMP interface "query-cpu-model-baseline" David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 26/28] s390x/cpumodel: implement QMP interface "query-cpu-model-expansion" David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 27/28] s390x/cpumodel: implement QMP interface "query-cpu-model-comparison" David Hildenbrand
2016-06-21 13:02 ` [Qemu-devel] [RFC 28/28] s390x/cpumodel: implement QMP interface "query-cpu-model-baseline" David Hildenbrand
2016-06-21 16:44 ` [Qemu-devel] [RFC 00/28] s390x CPU models: exposing features Eduardo Habkost
2016-06-21 17:01   ` David Hildenbrand
2016-06-21 20:33     ` Eduardo Habkost
2016-06-21 21:09       ` Jiri Denemark
2016-06-21 21:22         ` Eduardo Habkost
2016-06-22  7:11           ` [Qemu-devel] [libvirt] " Jiri Denemark
2016-06-22  7:14             ` David Hildenbrand
2016-06-22  6:51         ` [Qemu-devel] " David Hildenbrand
2016-06-22  7:26           ` Jiri Denemark
2016-06-22  7:34             ` David Hildenbrand
2016-06-22  7:53               ` Jiri Denemark
2016-06-22  7:54                 ` David Hildenbrand
2016-06-22  8:05                   ` Jiri Denemark
2016-06-23  6:41                     ` David Hildenbrand
2016-06-21 20:56   ` Jiri Denemark
2016-06-22  6:43     ` David Hildenbrand
2016-06-22 18:21     ` Eduardo Habkost
2016-06-23  6:33       ` David Hildenbrand
2016-06-30  7:32 ` David Hildenbrand
2016-06-30 15:07   ` Eduardo Habkost
2016-07-11 10:50   ` David Hildenbrand

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.