LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH v3 00/16] s390x cpu model implementation
@ 2015-03-02 12:43 Michael Mueller
  2015-03-02 12:43 ` [PATCH v3 01/16] Introduce probe mode for machine type none Michael Mueller
                   ` (16 more replies)
  0 siblings, 17 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:43 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

This patch set in combination with its kernel kvm patch set proposes an
implementation of S390 cpu models. The origin of this item is to provide
a means for management interfaces like libvirt to draw decisions if life
guest migration to a target hypervisor is reasonable.

A migration constraint is that a target hypervisor is capable to run a
guest with the same S390 cpu model as the source hypervisor does. To
verify this condition, the administration interface employes the existing
QMP command "query-cpu-definitions" which returns a list of all currently
supported S390 cpu models of a given host system. Together with the newly
defined QMP command "query-cpu-model", which returns the current active
S390 cpu model of a guest, a conclusion can be drawn if a migration is
possible.

A S390 cpu model is defined as a triple of machine type, cpu facility set
and IBC value. Each historic, current and future triple receives a name
composed of the machine type and its general availability counter. This name
forms the cpu model name (e.g.: "2817-ga2".)

With means of the Instruction Blocking Control feature (IBC), the instruction
set available to a given guest is limitable.

Details:
- The QMP command query-cpu-model returns the active cpu model and the
  accellerator it is using:

  {"name":"2066-ga1","accelerator":"kvm"}

Or just the empty model in case an accelerator does not implement cpu
models yet:

  {}

- A management instance like libvirt may probe by means of the QMP command
  query-cpu-definitions which models are defined and usable for all
  supporting accelerators. To implement this the cpu definition info type gets
  an optional field named 'accelerators' which holds a list defining
  which cpu model is 'runnable' and in addition which one the 'default'
  cpu model is (i.e. the model to be used in the 'host' case).

  [{"name":"2964-ga1",
    "accelerators":[{"name":"kvm","runnable":false,"default":false}]}

Or just 'host' in case an accelerator does not implement cpu models yet:

  [{"name":"host"}]

- For accel=kvm the cpu model initialization takes place in kvm_arch_init()

What's currently a little bit unclear to me is how to best initialize the
various accelerators for machine 'none'. I played around with different
options and finally came up with the following sugguestion:

Introduce a QEMU "probe mode" that gets entered in case the current machine
is "none" and no specific accelerator is requested on the cmd line. When
in that mode, loop trough a list of acellerators in configure_accelerator
and invoke all their init methods once. The last accelerator to init shall
be tcg.

In cpu model context that allows to initialize the S390 CPU classes for
each single accelertor which supports it. Whence the callback for
qemu-cpu-definitions allows to populate its answer string according to the
above sketched extended CpuDefinitionInfo type for multiplaccelerators. 

v2-v3:
- using GTK-Doc style format now for function descriptions
- typo fixed (2/16)
- gen-facilties now used to generate cpu model specific facility lists
  and the qemu side facility mask during build time (5/16)
- gen-facilities added to make magic (5/16)
- element of struct S390CPUMachineProps now statically in cpu class (6/16)
- element of struct S390CPUProcessorProps now statically in cpu class (6/16)
- facility list also static now (6/16)
- typo fixed (7/16)
- zBC12-ga1 model now active on zEC12-ga2 host (11/16)
- operations on facility lists use QEMU bitmap API now (11/16)
- routine s390_cpu_model_init() introduced, called during cpu object
  realization to prepare the current accelarator (12/16) if a cpu
  model was selected
- missing comment added in description of CpuModelInfo type (13/16)
- accelerator field now mandatory for "query-cpu-model" (13/16)
- sorted list related comment to "query-cpu-definitions" dropped in
  commit message (13/16)
- comment for AccelCpuInfo type updated (13/16)
- routine s390_facility_test() factored out (15/16)

v1-v2:
- QEMU-side facility list mask introduced: this allows to enable guest
  facilities that are handled by instruction interception handlers
  implemented on qemu side. Similar to the facilities enabled by means
  of the KVM side facility list mask which are handled by kvm/kernel.
- Concept of soft facilities has been dropped 
- Result type of QMP command query-cpu-definitions extended to hold
  additional information beside the cpu model name including which
  cpu model is runnable in current accelerator and machine context. 

Michael Mueller (16):
  Introduce probe mode for machine type none
  Introduce option --probe to switch into probe mode
  Introduce stub routine cpu_desc_avail
  target-s390x: Introduce cpu facilities
  target-s390x: Generate facility defines per cpu model
  target-s390x: Introduce cpu models
  target-s390x: Define cpu model specific facility lists
  target-s390x: Add cpu model alias definition routines
  target-s390x: Update linux-headers/asm-s390/kvm.h
  target-s390x: Add KVM VM attribute interface for cpu models
  target-s390x: Add cpu class initialization routines
  target-s390x: Prepare accelerator during cpu object realization
  target-s390x: New QMP command query-cpu-model
  target-s390x: Extend QMP command query-cpu-definitions
  target-s390x: Introduce facility test routine
  target-s390x: Enable cpu model usage

 Makefile.target               |   2 +-
 accel.c                       |  36 ++-
 hw/s390x/s390-virtio.c        |  12 +-
 include/hw/boards.h           |   1 +
 include/qemu-common.h         |   2 +
 include/sysemu/accel.h        |   2 +-
 include/sysemu/arch_init.h    |   1 +
 include/sysemu/kvm.h          |  10 +
 kvm-all.c                     |   3 +
 linux-headers/asm-s390/kvm.h  |  20 ++
 qapi-schema.json              |  57 +++-
 qemu-options.hx               |   8 +
 qmp-commands.hx               |   6 +
 qmp.c                         |   5 +
 rules.mak                     |   3 +
 stubs/Makefile.objs           |   2 +
 stubs/arch-query-cpu-mod.c    |   9 +
 stubs/cpu-desc-avail.c        |   6 +
 target-s390x/Makefile.objs    |  19 ++
 target-s390x/cpu-facilities.h |  76 +++++
 target-s390x/cpu-models.c     | 730 ++++++++++++++++++++++++++++++++++++++++++
 target-s390x/cpu-models.h     | 162 ++++++++++
 target-s390x/cpu-qom.h        |  25 ++
 target-s390x/cpu.c            | 149 ++++++++-
 target-s390x/gen-facilities.c | 401 +++++++++++++++++++++++
 target-s390x/helper.c         |   9 +-
 target-s390x/kvm.c            | 104 ++++++
 trace-events                  |   3 +
 vl.c                          |   9 +-
 29 files changed, 1845 insertions(+), 27 deletions(-)
 create mode 100644 stubs/arch-query-cpu-mod.c
 create mode 100644 stubs/cpu-desc-avail.c
 create mode 100644 target-s390x/cpu-facilities.h
 create mode 100644 target-s390x/cpu-models.c
 create mode 100644 target-s390x/cpu-models.h
 create mode 100644 target-s390x/gen-facilities.c

-- 
1.8.3.1


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

* [PATCH v3 01/16] Introduce probe mode for machine type none
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
@ 2015-03-02 12:43 ` Michael Mueller
  2015-03-02 13:57   ` Andreas Färber
  2015-03-02 19:17   ` Eduardo Habkost
  2015-03-02 12:43 ` [PATCH v3 02/16] Introduce option --probe to switch into probe mode Michael Mueller
                   ` (15 subsequent siblings)
  16 siblings, 2 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:43 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

QEMU now switches into "probe mode" when the selected machine is "none" and no
specific accelerator(s) has been requested (i.e.: "-machine none").

In probe mode a by "<ARCH>_CONFIG" defines predefined list of accelerators run
their init() methods.

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 accel.c              | 31 +++++++++++++++++++++++++------
 include/hw/boards.h  |  1 +
 include/sysemu/kvm.h | 10 ++++++++++
 kvm-all.c            |  3 +++
 4 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/accel.c b/accel.c
index 74e41da..260b009 100644
--- a/accel.c
+++ b/accel.c
@@ -36,6 +36,9 @@
 
 int tcg_tb_size;
 static bool tcg_allowed = true;
+static const char *probe_mode_accels =
+    "kvm:"
+    "tcg";
 
 static int tcg_init(MachineState *ms)
 {
@@ -59,13 +62,15 @@ static AccelClass *accel_find(const char *opt_name)
     return ac;
 }
 
-static int accel_init_machine(AccelClass *acc, MachineState *ms)
+static int accel_init_machine(AccelClass *acc, MachineState *ms,
+                              bool probe_mode)
 {
     ObjectClass *oc = OBJECT_CLASS(acc);
     const char *cname = object_class_get_name(oc);
     AccelState *accel = ACCEL(object_new(cname));
     int ret;
     ms->accelerator = accel;
+    ms->probe_mode = probe_mode;
     *(acc->allowed) = true;
     ret = acc->init_machine(ms);
     if (ret < 0) {
@@ -78,20 +83,30 @@ static int accel_init_machine(AccelClass *acc, MachineState *ms)
 
 int configure_accelerator(MachineState *ms)
 {
-    const char *p;
+    const char *p, *name;
     char buf[10];
     int ret;
     bool accel_initialised = false;
     bool init_failed = false;
     AccelClass *acc = NULL;
+    ObjectClass *oc;
+    bool probe_mode = false;
 
     p = qemu_opt_get(qemu_get_machine_opts(), "accel");
     if (p == NULL) {
-        /* Use the default "accelerator", tcg */
-        p = "tcg";
+        oc = (ObjectClass *) MACHINE_GET_CLASS(current_machine);
+        name = object_class_get_name(oc);
+        probe_mode = !strcmp(name, "none" TYPE_MACHINE_SUFFIX);
+        if (probe_mode) {
+            /* Use these accelerators in probe mode, tcg should be last */
+            p = probe_mode_accels;
+        } else {
+            /* Use the default "accelerator", tcg */
+            p = "tcg";
+        }
     }
 
-    while (!accel_initialised && *p != '\0') {
+    while ((probe_mode || !accel_initialised) && *p != '\0') {
         if (*p == ':') {
             p++;
         }
@@ -106,7 +121,7 @@ int configure_accelerator(MachineState *ms)
                    acc->name);
             continue;
         }
-        ret = accel_init_machine(acc, ms);
+        ret = accel_init_machine(acc, ms, probe_mode);
         if (ret < 0) {
             init_failed = true;
             fprintf(stderr, "failed to initialize %s: %s\n",
@@ -128,6 +143,10 @@ int configure_accelerator(MachineState *ms)
         fprintf(stderr, "Back to %s accelerator.\n", acc->name);
     }
 
+    if (probe_mode) {
+        accel_initialised = false;
+    }
+
     return !accel_initialised;
 }
 
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 3ddc449..3253fa5 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -135,6 +135,7 @@ struct MachineState {
     bool usb;
     char *firmware;
     bool iommu;
+    bool probe_mode;
 
     ram_addr_t ram_size;
     ram_addr_t maxram_size;
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 30cb84d..fbc18c8 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -50,6 +50,7 @@ extern bool kvm_msi_via_irqfd_allowed;
 extern bool kvm_gsi_routing_allowed;
 extern bool kvm_gsi_direct_mapping;
 extern bool kvm_readonly_mem_allowed;
+extern bool kvm_probe_mode;
 
 #if defined CONFIG_KVM || !defined NEED_CPU_H
 #define kvm_enabled()           (kvm_allowed)
@@ -143,6 +144,15 @@ extern bool kvm_readonly_mem_allowed;
  */
 #define kvm_readonly_mem_enabled() (kvm_readonly_mem_allowed)
 
+/**
+ * kvm_probe_mode_enabled:
+ *
+ * Returns: true if KVM is initialized for a machine type that
+ * has its probe_mode attribute set (ie QEMU was started in probe
+ * mode)
+ */
+#define kvm_probe_mode_enabled() (kvm_probe_mode)
+
 #else
 #define kvm_enabled()           (0)
 #define kvm_irqchip_in_kernel() (false)
diff --git a/kvm-all.c b/kvm-all.c
index 05a79c2..f9e4434 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -126,6 +126,7 @@ bool kvm_gsi_routing_allowed;
 bool kvm_gsi_direct_mapping;
 bool kvm_allowed;
 bool kvm_readonly_mem_allowed;
+bool kvm_probe_mode;
 
 static const KVMCapabilityInfo kvm_required_capabilites[] = {
     KVM_CAP_INFO(USER_MEMORY),
@@ -1471,6 +1472,8 @@ static int kvm_init(MachineState *ms)
         goto err;
     }
 
+    kvm_probe_mode = ms->probe_mode;
+
     s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
 
     /* If unspecified, use the default value */
-- 
1.8.3.1


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

* [PATCH v3 02/16] Introduce option --probe to switch into probe mode
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
  2015-03-02 12:43 ` [PATCH v3 01/16] Introduce probe mode for machine type none Michael Mueller
@ 2015-03-02 12:43 ` Michael Mueller
  2015-03-02 12:43 ` [PATCH v3 03/16] Introduce stub routine cpu_desc_avail Michael Mueller
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:43 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

The option --probe allows to switch into probe mode also for machines
different from none. If one or more accelerators are specified these
accelerators are used to provide probable properties. If no accelerator
is given a list of accelerators that support probing is used.

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 accel.c                | 13 ++++++++-----
 include/sysemu/accel.h |  2 +-
 qemu-options.hx        |  8 ++++++++
 vl.c                   |  7 ++++++-
 4 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/accel.c b/accel.c
index 260b009..4ed6df8 100644
--- a/accel.c
+++ b/accel.c
@@ -81,7 +81,7 @@ static int accel_init_machine(AccelClass *acc, MachineState *ms,
     return ret;
 }
 
-int configure_accelerator(MachineState *ms)
+int configure_accelerator(MachineState *ms, int probe)
 {
     const char *p, *name;
     char buf[10];
@@ -90,13 +90,16 @@ int configure_accelerator(MachineState *ms)
     bool init_failed = false;
     AccelClass *acc = NULL;
     ObjectClass *oc;
-    bool probe_mode = false;
+    bool probe_mode;
 
+    probe_mode = probe != 0;
     p = qemu_opt_get(qemu_get_machine_opts(), "accel");
     if (p == NULL) {
-        oc = (ObjectClass *) MACHINE_GET_CLASS(current_machine);
-        name = object_class_get_name(oc);
-        probe_mode = !strcmp(name, "none" TYPE_MACHINE_SUFFIX);
+        if (!probe_mode) {
+            oc = (ObjectClass *) MACHINE_GET_CLASS(current_machine);
+            name = object_class_get_name(oc);
+            probe_mode = !strcmp(name, "none" TYPE_MACHINE_SUFFIX);
+        }
         if (probe_mode) {
             /* Use these accelerators in probe mode, tcg should be last */
             p = probe_mode_accels;
diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h
index 997720f..3adb6ba 100644
--- a/include/sysemu/accel.h
+++ b/include/sysemu/accel.h
@@ -57,6 +57,6 @@ typedef struct AccelClass {
 
 extern int tcg_tb_size;
 
-int configure_accelerator(MachineState *ms);
+int configure_accelerator(MachineState *ms, int probe);
 
 #endif
diff --git a/qemu-options.hx b/qemu-options.hx
index 85ca3ad..22e7544 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2847,6 +2847,14 @@ STEXI
 Do not start CPU at startup (you must type 'c' in the monitor).
 ETEXI
 
+DEF("probe", 0, QEMU_OPTION_probe, \
+    "-probe          startup in probe mode, option -S is selected as well\n", QEMU_ARCH_ALL)
+STEXI
+@item -probe
+@findex -probe
+Startup in probe mode.
+ETEXI
+
 DEF("realtime", HAS_ARG, QEMU_OPTION_realtime,
     "-realtime [mlock=on|off]\n"
     "                run qemu with realtime features\n"
diff --git a/vl.c b/vl.c
index e1ffd0a..ba1730c 100644
--- a/vl.c
+++ b/vl.c
@@ -138,6 +138,7 @@ bool enable_mlock = false;
 int nb_nics;
 NICInfo nd_table[MAX_NICS];
 int autostart;
+int probe;
 static int rtc_utc = 1;
 static int rtc_date_offset = -1; /* -1 means no change */
 QEMUClockType rtc_clock;
@@ -3144,6 +3145,10 @@ int main(int argc, char **argv, char **envp)
             case QEMU_OPTION_S:
                 autostart = 0;
                 break;
+            case QEMU_OPTION_probe:
+                probe = 1;
+                autostart = 0;
+                break;
             case QEMU_OPTION_k:
                 keyboard_layout = optarg;
                 break;
@@ -4023,7 +4028,7 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
-    configure_accelerator(current_machine);
+    configure_accelerator(current_machine, probe);
 
     if (qtest_chrdev) {
         Error *local_err = NULL;
-- 
1.8.3.1


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

* [PATCH v3 03/16] Introduce stub routine cpu_desc_avail
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
  2015-03-02 12:43 ` [PATCH v3 01/16] Introduce probe mode for machine type none Michael Mueller
  2015-03-02 12:43 ` [PATCH v3 02/16] Introduce option --probe to switch into probe mode Michael Mueller
@ 2015-03-02 12:43 ` Michael Mueller
  2015-03-02 12:43 ` [PATCH v3 04/16] target-s390x: Introduce cpu facilities Michael Mueller
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:43 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

This patch introduces the function cpu_desc_avail() which returns by
default true if not architecture specific implemented. Its intention
is to indicate if the cpu model description is available for display
by list_cpus(). This change allows cpu model descriptions to become
dynamically created by evaluating the runtime context instead of
putting static cpu model information at display.

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
---
 include/qemu-common.h  | 2 ++
 stubs/Makefile.objs    | 1 +
 stubs/cpu-desc-avail.c | 6 ++++++
 vl.c                   | 2 +-
 4 files changed, 10 insertions(+), 1 deletion(-)
 create mode 100644 stubs/cpu-desc-avail.c

diff --git a/include/qemu-common.h b/include/qemu-common.h
index 644b46d..45040f9 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -481,4 +481,6 @@ int parse_debug_env(const char *name, int max, int initial);
 
 const char *qemu_ether_ntoa(const MACAddr *mac);
 
+bool cpu_desc_avail(void);
+
 #endif
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 5e347d0..fd7a489 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -40,3 +40,4 @@ stub-obj-$(CONFIG_WIN32) += fd-register.o
 stub-obj-y += cpus.o
 stub-obj-y += kvm.o
 stub-obj-y += qmp_pc_dimm_device_list.o
+stub-obj-y += cpu-desc-avail.o
diff --git a/stubs/cpu-desc-avail.c b/stubs/cpu-desc-avail.c
new file mode 100644
index 0000000..0cd594e
--- /dev/null
+++ b/stubs/cpu-desc-avail.c
@@ -0,0 +1,6 @@
+#include "qemu-common.h"
+
+bool cpu_desc_avail(void)
+{
+    return true;
+}
diff --git a/vl.c b/vl.c
index ba1730c..d337a74 100644
--- a/vl.c
+++ b/vl.c
@@ -3815,7 +3815,7 @@ int main(int argc, char **argv, char **envp)
      */
     cpudef_init();
 
-    if (cpu_model && is_help_option(cpu_model)) {
+    if (cpu_model && cpu_desc_avail() && is_help_option(cpu_model)) {
         list_cpus(stdout, &fprintf, cpu_model);
         exit(0);
     }
-- 
1.8.3.1


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

* [PATCH v3 04/16] target-s390x: Introduce cpu facilities
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (2 preceding siblings ...)
  2015-03-02 12:43 ` [PATCH v3 03/16] Introduce stub routine cpu_desc_avail Michael Mueller
@ 2015-03-02 12:43 ` Michael Mueller
  2015-03-02 12:43 ` [PATCH v3 05/16] target-s390x: Generate facility defines per cpu model Michael Mueller
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:43 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

The patch introduces S390 CPU facility bit numbers and names
as well as the architectural facility size limit in bytes.

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 target-s390x/cpu-facilities.h | 76 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 target-s390x/cpu-facilities.h

diff --git a/target-s390x/cpu-facilities.h b/target-s390x/cpu-facilities.h
new file mode 100644
index 0000000..1f1716a
--- /dev/null
+++ b/target-s390x/cpu-facilities.h
@@ -0,0 +1,76 @@
+/*
+ * CPU facilities for s390
+ *
+ * Copyright 2015 IBM Corp.
+ *
+ * Author(s): Michael Mueller <mimu@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_FACILITIES_H
+#define TARGET_S390X_CPU_FACILITIES_H
+
+/* architectural size of facilities is 2KB */
+#define FAC_LIST_ARCH_S390_SIZE_UINT8 (1<<11)
+
+/* CPU facility bits */
+typedef enum {
+    FAC_N3                              = 0,
+    FAC_ZARCH                           = 1,
+    FAC_ZARCH_ACTIVE                    = 2,
+    FAC_DAT_ENH                         = 3,
+    FAC_ASN_LX_REUSE                    = 6,
+    FAC_STFLE                           = 7,
+    FAC_ENHANCED_DAT_1                  = 8,
+    FAC_SENSE_RUNNING_STATUS            = 9,
+    FAC_CONDITIONAL_SSKE                = 10,
+    FAC_CONFIGURATION_TOPOLOGY          = 11,
+    FAC_IPTE_RANGE                      = 13,
+    FAC_NONQ_KEY_SETTING                = 14,
+    FAC_EXTENDED_TRANSLATION_2          = 16,
+    FAC_MESSAGE_SECURITY_ASSIST         = 17,
+    FAC_LONG_DISPLACEMENT               = 18,
+    FAC_LONG_DISPLACEMENT_FAST          = 19,
+    FAC_HFP_MADDSUB                     = 20,
+    FAC_EXTENDED_IMMEDIATE              = 21,
+    FAC_EXTENDED_TRANSLATION_3          = 22,
+    FAC_HFP_UNNORMALIZED_EXT            = 23,
+    FAC_ETF2_ENH                        = 24,
+    FAC_STORE_CLOCK_FAST                = 25,
+    FAC_PARSING_ENH                     = 26,
+    FAC_MOVE_WITH_OPTIONAL_SPEC         = 27,
+    FAC_TOD_CLOCK_STEERING              = 28,
+    FAC_ETF3_ENH                        = 30,
+    FAC_EXTRACT_CPU_TIME                = 31,
+    FAC_COMPARE_AND_SWAP_AND_STORE      = 32,
+    FAC_COMPARE_AND_SWAP_AND_STORE_2    = 33,
+    FAC_GENERAL_INSTRUCTIONS_EXT        = 34,
+    FAC_EXECUTE_EXT                     = 35,
+    FAC_ENHANCED_MONITOR                = 36,
+    FAC_FLOATING_POINT_EXT              = 37,
+    FAC_LOAD_PROGRAM_PARAMETERS         = 40,
+    FAC_FLOATING_POINT_SUPPPORT_ENH     = 41,
+    FAC_DFP                             = 42,
+    FAC_DFP_FAST                        = 43,
+    FAC_PFPO                            = 44,
+    FAC_MULTI_45                        = 45,
+    FAC_CMPSC_ENH                       = 47,
+    FAC_DFP_ZONED_CONVERSION            = 48,
+    FAC_MULTI_49                        = 49,
+    FAC_CONSTRAINT_TRANSACTIONAL_EXE    = 50,
+    FAC_LOCAL_TLB_CLEARING              = 51,
+    FAC_INTERLOCKED_ACCESS_2            = 52,
+    FAC_RESET_REFERENCE_BITS_MULTIPLE   = 66,
+    FAC_CPU_MEASUREMENT_COUNTER         = 67,
+    FAC_CPU_MEASUREMENT_SAMPLING        = 68,
+    FAC_TRANSACTIONAL_EXE               = 73,
+    FAC_ACCESS_EXCEPTION_FS_INDICATION  = 75,
+    FAC_MESSAGE_SECURITY_ASSIST_3       = 76,
+    FAC_MESSAGE_SECURITY_ASSIST_4       = 77,
+    FAC_ENHANCED_DAT_2                  = 78,
+} S390Facility;
+
+#endif
-- 
1.8.3.1


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

* [PATCH v3 05/16] target-s390x: Generate facility defines per cpu model
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (3 preceding siblings ...)
  2015-03-02 12:43 ` [PATCH v3 04/16] target-s390x: Introduce cpu facilities Michael Mueller
@ 2015-03-02 12:43 ` Michael Mueller
  2015-03-02 12:43 ` [PATCH v3 06/16] target-s390x: Introduce cpu models Michael Mueller
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:43 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

This patch introduces the helper "gen-facilities" which allows to generate
facility list definitions and masks 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-facilities.h" to be able to use named
facility bits instead of numbers. Its output will be feed back into the
cpu model related header file "target-s390x/cpu-models.h" by including
"target-s390x/gen-facilities.h" to implement model related data structures.

The following defines/symbols are expected to be provided by the cpu-facilities
header file:

FAC_LIST_ARCH_S390_SIZE_UINT8
FAC_N3
FAC_ZARCH
FAC_ZARCH_ACTIVE
...

The defines provided by gen-facilities follow the following schema:

FAC_LIST_CPU_S390_SIZE_UINT1 %PRIu32
FAC_LIST_CPU_S390_SIZE_UINT8 %PRIu32
FAC_LIST_CPU_S390_SIZE_UINT64 %PRIu32
FAC_LIST_CPU_S390_MASK_QEMU 0x%016PRIx64,0x%016PRIx64,...
FAC_LIST_CPU_S390_<TYPE>_GA<n> 0x%016PRIx64,0x%016PRIx64,...

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 Makefile.target               |   2 +-
 rules.mak                     |   3 +
 target-s390x/Makefile.objs    |  18 ++
 target-s390x/gen-facilities.c | 401 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 423 insertions(+), 1 deletion(-)
 create mode 100644 target-s390x/gen-facilities.c

diff --git a/Makefile.target b/Makefile.target
index 58c6ae1..d174d5e 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -188,7 +188,7 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx
 qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx
 	$(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 3a05627..d367e23 100644
--- a/rules.mak
+++ b/rules.mak
@@ -13,6 +13,9 @@ MAKEFLAGS += -rR
 %.m:
 %.mak:
 
+# default target cleanup
+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 dd62cbd..1b65776 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -3,3 +3,21 @@ obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
 obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o
 obj-$(CONFIG_KVM) += kvm.o
+
+# build and run facility generator
+#
+fac = gen-facilities
+fac-src = $(SRC_PATH)/target-$(TARGET_BASE_ARCH)
+fac-dst = $(SRC_PATH)/$(TARGET_DIR)
+fac-bin = $(TARGET_DIR)$(fac)
+fac-h = $(fac-bin).h
+GENERATED_HEADERS += $(fac-dst)$(fac).h
+
+$(fac-dst)$(fac).h: $(fac-dst)$(fac)
+	$(call quiet-command,$< >$@,"  GEN   $(fac-h)")
+
+$(fac-dst)$(fac): $(fac-src)/$(fac).c $(fac-src)/cpu-facilities.h
+	$(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(CFLAGS) -o $@ $<,"  CC    $(fac-bin)")
+
+clean-target:
+	rm -f $(fac-bin) $(fac-h)
diff --git a/target-s390x/gen-facilities.c b/target-s390x/gen-facilities.c
new file mode 100644
index 0000000..9d48bcc
--- /dev/null
+++ b/target-s390x/gen-facilities.c
@@ -0,0 +1,401 @@
+/*
+ * S390 facility list/mask generator
+ *
+ * Copyright 2015 IBM Corp.
+ *
+ * Author(s): Michael Mueller <mimu@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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <assert.h>
+#include <values.h>
+#include "cpu-facilities.h"
+
+/***** BEGIN FACILITY DEFS *****/
+
+/*******************************
+ * CMOS G7 processors
+ *******************************/
+
+/* 2064-GA1 */
+static uint16_t set_2064_GA1[] = {
+    FAC_N3,
+    FAC_ZARCH,
+    FAC_ZARCH_ACTIVE,
+};
+#define clear_2064_GA1 EmptyFacs
+
+/* 2064-GA2 */
+static uint16_t set_2064_GA2[] = {
+    FAC_EXTENDED_TRANSLATION_2,
+};
+#define clear_2064_GA2 EmptyFacs
+
+/* 2064-GA3 */
+#define set_2064_GA3 EmptyFacs
+#define clear_2064_GA3 EmptyFacs
+
+/* 2066-GA1 */
+#define set_2066_GA1 EmptyFacs
+#define clear_2066_GA1 EmptyFacs
+
+/*******************************
+ * CMOS G8 processors
+ *******************************/
+
+/* 2084-GA1 */
+static uint16_t set_2084_GA1[] = {
+    FAC_DAT_ENH,
+    FAC_MESSAGE_SECURITY_ASSIST,
+    FAC_LONG_DISPLACEMENT,
+    FAC_LONG_DISPLACEMENT_FAST,
+    FAC_HFP_MADDSUB,
+};
+#define clear_2084_GA1 EmptyFacs
+
+/* 2084-GA2 */
+static uint16_t set_2084_GA2[] = {
+    4,
+};
+#define clear_2084_GA2 EmptyFacs
+
+/* 2084-GA3 */
+static uint16_t set_2084_GA3[] = {
+    FAC_ASN_LX_REUSE,
+    FAC_EXTENDED_TRANSLATION_3,
+};
+#define clear_2084_GA3 EmptyFacs
+
+/* 2084-GA4 */
+#define set_2084_GA4 EmptyFacs
+#define clear_2084_GA4 EmptyFacs
+
+/* 2084-GA5 */
+static uint16_t set_2084_GA5[] = {
+    FAC_TOD_CLOCK_STEERING,
+};
+#define clear_2084_GA5 EmptyFacs
+
+/* 2086-GA1 */
+#define set_2086_GA1 EmptyFacs
+#define clear_2086_GA1 EmptyFacs
+
+/* 2086-GA2 */
+#define set_2086_GA2 EmptyFacs
+#define clear_2086_GA2 EmptyFacs
+
+/* 2086-GA3 */
+#define set_2086_GA3 EmptyFacs
+#define clear_2086_GA3 EmptyFacs
+
+/*******************************
+ * CMOS G9 processors
+ *******************************/
+
+/* 2094-GA1 */
+static uint16_t set_2094_GA1[] = {
+    FAC_STFLE,
+    FAC_EXTENDED_IMMEDIATE,
+    FAC_HFP_UNNORMALIZED_EXT,
+    FAC_ETF2_ENH,
+    FAC_STORE_CLOCK_FAST,
+    FAC_ETF3_ENH,
+    FAC_EXTRACT_CPU_TIME,
+};
+#define clear_2094_GA1 EmptyFacs
+
+/* 2094-GA2 */
+static uint16_t set_2094_GA2[] = {
+    FAC_SENSE_RUNNING_STATUS,
+    FAC_MOVE_WITH_OPTIONAL_SPEC,
+    FAC_COMPARE_AND_SWAP_AND_STORE,
+    FAC_FLOATING_POINT_SUPPPORT_ENH,
+    FAC_DFP,
+};
+#define clear_2094_GA2 EmptyFacs
+
+/* 2094-GA3 */
+static uint16_t set_2094_GA3[] = {
+    FAC_PFPO,
+};
+#define clear_2094_GA3 EmptyFacs
+
+/* 2096-GA1 */
+#define set_2096_GA1 EmptyFacs
+#define clear_2096_GA1 EmptyFacs
+
+/* 2096-GA2 */
+#define set_2096_GA2 EmptyFacs
+#define clear_2096_GA2 EmptyFacs
+
+/*******************************
+ * CMOS G10 processors
+ *******************************/
+
+/* 2097-GA1 */
+static uint16_t set_2097_GA1[] = {
+    FAC_ENHANCED_DAT_1,
+    FAC_CONDITIONAL_SSKE,
+    FAC_CONFIGURATION_TOPOLOGY,
+    FAC_PARSING_ENH,
+    FAC_COMPARE_AND_SWAP_AND_STORE_2,
+    FAC_GENERAL_INSTRUCTIONS_EXT,
+    FAC_EXECUTE_EXT,
+    FAC_DFP_FAST,
+};
+#define clear_2097_GA1 EmptyFacs
+
+/* 2097-GA2 */
+static uint16_t set_2097_GA2[] = {
+    65,
+    FAC_CPU_MEASUREMENT_COUNTER,
+    FAC_CPU_MEASUREMENT_SAMPLING,
+};
+#define clear_2097_GA2 EmptyFacs
+
+/* 2097-GA3 */
+static uint16_t set_2097_GA3[] = {
+    FAC_LOAD_PROGRAM_PARAMETERS,
+};
+#define clear_2097_GA3 EmptyFacs
+
+/* 2098-GA1 */
+#define set_2098_GA1 EmptyFacs
+#define clear_2098_GA1 EmptyFacs
+
+/* 2098-GA2 */
+#define set_2098_GA2 EmptyFacs
+#define clear_2098_GA2 EmptyFacs
+
+/*******************************
+ * CMOS G11 processors
+ *******************************/
+
+/* 2817-GA1 */
+static uint16_t set_2817_GA1[] = {
+    FAC_ENHANCED_MONITOR,
+    FAC_FLOATING_POINT_EXT,
+    FAC_MULTI_45,
+    46,
+    FAC_ACCESS_EXCEPTION_FS_INDICATION,
+};
+static uint16_t clear_2817_GA1[] = {
+    65,
+};
+
+/* 2817-GA2 */
+static uint16_t set_2817_GA2[] = {
+    FAC_IPTE_RANGE,
+    FAC_NONQ_KEY_SETTING,
+    FAC_CMPSC_ENH,
+    FAC_RESET_REFERENCE_BITS_MULTIPLE,
+    FAC_MESSAGE_SECURITY_ASSIST_3,
+    FAC_MESSAGE_SECURITY_ASSIST_4,
+};
+#define clear_2817_GA2 EmptyFacs
+
+/* 2818-GA1 */
+#define set_2818_GA1 EmptyFacs
+#define clear_2818_GA1 EmptyFacs
+
+/*******************************
+ * CMOS G12 processors
+ *******************************/
+
+/* 2827-GA1 */
+static uint16_t set_2827_GA1[] = {
+    FAC_DFP_ZONED_CONVERSION,
+    FAC_MULTI_49,
+    FAC_CONSTRAINT_TRANSACTIONAL_EXE,
+    FAC_LOCAL_TLB_CLEARING,
+    FAC_INTERLOCKED_ACCESS_2,
+    FAC_TRANSACTIONAL_EXE,
+    FAC_ENHANCED_DAT_2,
+};
+#define clear_2827_GA1 EmptyFacs
+
+/* 2827-GA2 */
+#define set_2827_GA2 EmptyFacs
+#define clear_2827_GA2 EmptyFacs
+
+/* 2828-GA1 */
+#define set_2828_GA1 EmptyFacs
+#define clear_2828_GA1 EmptyFacs
+
+/****** END FACILITY DEFS ******/
+
+#define S390_ARCH_FAC_LIST_SIZE_BYTE \
+    (S390_ARCH_FAC_LIST_SIZE / 8)
+
+#define _YEARS  "2014, 2015"
+#define _NAME_H "TARGET_S390X_GEN_FACILITIES_H"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+#define FAC_INITIALIZER(_name)                         \
+    {                                                  \
+        .Name = "FAC_LIST_CPU_S390_" #_name,           \
+        .SetBits =                                     \
+            { .Data = set_##_name,                     \
+              .Length = ARRAY_SIZE(set_##_name) },     \
+        .ClearBits =                                   \
+            { .Data = clear_##_name,                   \
+              .Length = ARRAY_SIZE(clear_##_name) },   \
+    }
+
+enum BitOps {
+    SetBit,
+    ClearBit,
+};
+
+typedef struct BitSpec {
+    uint16_t *Data;
+    uint32_t Length;
+} BitSpec;
+
+typedef struct FacDefSpec {
+    const char *Name;
+    BitSpec SetBits;
+    BitSpec ClearBits;
+} FacDefSpec;
+
+static uint16_t EmptyFacs[] = {};
+
+/*******************************
+ * processor GA series
+ *******************************/
+static FacDefSpec FacDef[] = {
+    FAC_INITIALIZER(2064_GA1),
+    FAC_INITIALIZER(2064_GA2),
+    FAC_INITIALIZER(2064_GA3),
+    FAC_INITIALIZER(2066_GA1),
+    FAC_INITIALIZER(2084_GA1),
+    FAC_INITIALIZER(2084_GA2),
+    FAC_INITIALIZER(2084_GA3),
+    FAC_INITIALIZER(2086_GA1),
+    FAC_INITIALIZER(2084_GA4),
+    FAC_INITIALIZER(2086_GA2),
+    FAC_INITIALIZER(2084_GA5),
+    FAC_INITIALIZER(2086_GA3),
+    FAC_INITIALIZER(2094_GA1),
+    FAC_INITIALIZER(2094_GA2),
+    FAC_INITIALIZER(2094_GA3),
+    FAC_INITIALIZER(2096_GA1),
+    FAC_INITIALIZER(2096_GA2),
+    FAC_INITIALIZER(2097_GA1),
+    FAC_INITIALIZER(2097_GA2),
+    FAC_INITIALIZER(2098_GA1),
+    FAC_INITIALIZER(2097_GA3),
+    FAC_INITIALIZER(2098_GA2),
+    FAC_INITIALIZER(2817_GA1),
+    FAC_INITIALIZER(2817_GA2),
+    FAC_INITIALIZER(2818_GA1),
+    FAC_INITIALIZER(2827_GA1),
+    FAC_INITIALIZER(2827_GA2),
+    FAC_INITIALIZER(2828_GA1),
+};
+
+/*******************************
+ * QEMU facility list mask
+ *******************************/
+#define set_MASK_QEMU EmptyFacs
+#define clear_MASK_QEMU EmptyFacs
+
+static FacDefSpec QemuMaskDef = FAC_INITIALIZER(MASK_QEMU);
+
+static void BigEndianBitOps(enum BitOps BitOp, uint64_t Facility[],
+                            uint32_t MaxWord, BitSpec Bits)
+{
+    uint32_t i, Bit, Word, WidthInBits;
+
+    WidthInBits = _TYPEBITS(typeof(Facility[0]));
+    for (i = 0; i < Bits.Length; i++) {
+        Bit = (WidthInBits - 1) - (Bits.Data[i] & (WidthInBits - 1));
+        Word = Bits.Data[i] / WidthInBits;
+        assert(Word < MaxWord);
+        switch (BitOp) {
+        case SetBit:
+            Facility[Word] |= __UINT64_C(1) << Bit;
+            break;
+        case ClearBit:
+            Facility[Word] &= ~(__UINT64_C(1) << Bit);
+            break;
+        }
+    }
+}
+
+static uint32_t PrintFacilityList(uint32_t Model, FacDefSpec FacDef[])
+{
+    uint32_t i, Words, Size;
+    uint64_t Facility[FAC_LIST_ARCH_S390_SIZE_UINT8];
+
+    for (Size = ARRAY_SIZE(Facility), i = 0; i < Size; i++) {
+        Facility[i] = __UINT64_C(0);
+    }
+    for (i = 0; i <= Model; i++) {
+        BigEndianBitOps(SetBit, Facility, Size, FacDef[i].SetBits);
+        BigEndianBitOps(ClearBit, Facility, Size, FacDef[i].ClearBits);
+    }
+    for (Words = 0, i = 0; i < Size; i++) {
+        if (Facility[i]) {
+            Words = i;
+        }
+    }
+    printf("#define %s\t", FacDef[Model].Name);
+    for (i = 0; i <= Words; i++) {
+        printf("0x%016"PRIx64"%c", Facility[i], i < Words ? ',' : '\n');
+    }
+    return ++Words;
+}
+
+static inline uint32_t Max(uint32_t uIntA, uint32_t uIntB)
+{
+    if (uIntA > uIntB) {
+        return uIntA;
+    }
+    return uIntB;
+}
+
+static inline void PrintAllFacilityDefs(void)
+{
+    uint32_t i, MaxWords, MaxBytes, MaxBits;
+
+    printf("\n/* CPU model facility list data */\n");
+    for (MaxWords = 0, i = 0; i < ARRAY_SIZE(FacDef); i++) {
+        MaxWords = Max(PrintFacilityList(i, FacDef), MaxWords);
+    }
+    printf("\n/* QEMU facility mask data */\n");
+    MaxWords = Max(PrintFacilityList(0, &QemuMaskDef), MaxWords);
+    MaxBytes = MaxWords * sizeof(uint64_t);
+    MaxBits = MaxBytes * CHARBITS;
+    printf("\n/* facility list/mask sizes */\n");
+    printf("#define FAC_LIST_CPU_S390_SIZE_UINT1\t%"PRIu32"\n", MaxBits);
+    printf("#define FAC_LIST_CPU_S390_SIZE_UINT8\t%"PRIu32"\n", MaxBytes);
+    printf("#define FAC_LIST_CPU_S390_SIZE_UINT64\t%"PRIu32"\n", MaxWords);
+}
+
+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);
+    PrintAllFacilityDefs();
+    printf("\n#endif\n");
+    return 0;
+}
-- 
1.8.3.1


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

* [PATCH v3 06/16] target-s390x: Introduce cpu models
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (4 preceding siblings ...)
  2015-03-02 12:43 ` [PATCH v3 05/16] target-s390x: Generate facility defines per cpu model Michael Mueller
@ 2015-03-02 12:43 ` Michael Mueller
  2015-03-02 12:43 ` [PATCH v3 07/16] target-s390x: Define cpu model specific facility lists Michael Mueller
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:43 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

This patch implements the static part of the s390 cpu class definitions.
It defines s390 cpu models by means of virtual cpu ids (enum) which contain
information on the cpu generation, the machine class, the GA number and
the machine type. The cpu id is used to instantiate a cpu class per cpu
model.

In addition the patch introduces the QMP enumeration AccelId. It is used
to index certain cpu model poperties per accelerator.

Furthermore it extends the existing S390CPUClass by model related properties.

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
---
 qapi-schema.json           | 11 +++++++
 target-s390x/Makefile.objs |  1 +
 target-s390x/cpu-models.c  | 77 ++++++++++++++++++++++++++++++++++++++++++++++
 target-s390x/cpu-models.h  | 71 ++++++++++++++++++++++++++++++++++++++++++
 target-s390x/cpu-qom.h     | 25 +++++++++++++++
 5 files changed, 185 insertions(+)
 create mode 100644 target-s390x/cpu-models.c
 create mode 100644 target-s390x/cpu-models.h

diff --git a/qapi-schema.json b/qapi-schema.json
index e16f8eb..ea436ec 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2473,6 +2473,17 @@
 ##
 { 'command': 'query-machines', 'returns': ['MachineInfo'] }
 
+
+##
+# @AccelId
+#
+# Defines accelerator ids
+#
+# Since: 2.3
+##
+{ 'enum': 'AccelId',
+  'data': ['qtest', 'tcg', 'kvm', 'xen'  ] }
+
 ##
 # @CpuDefinitionInfo:
 #
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index 1b65776..4ee0f1d 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,6 +1,7 @@
 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 += 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-models.c b/target-s390x/cpu-models.c
new file mode 100644
index 0000000..3520691
--- /dev/null
+++ b/target-s390x/cpu-models.c
@@ -0,0 +1,77 @@
+/*
+ * CPU models for s390
+ *
+ * Copyright 2014,2015 IBM Corp.
+ *
+ * Author(s): Michael Mueller <mimu@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-common.h"
+#include "cpu-models.h"
+
+#define S390_PROC_DEF(_name, _cpu_id, _desc)                            \
+    static void                                                         \
+    glue(_cpu_id, _cpu_class_init)                                      \
+    (ObjectClass *oc, void *data)                                       \
+    {                                                                   \
+        DeviceClass *dc = DEVICE_CLASS(oc);                             \
+        S390CPUClass *cc = S390_CPU_CLASS(oc);                          \
+                                                                        \
+        cc->is_active[ACCEL_ID_KVM] = true;                             \
+        cc->mach.ga    = cpu_ga(_cpu_id);                               \
+        cc->mach.class = cpu_class(_cpu_id);                            \
+        cc->mach.order = cpu_order(_cpu_id);                            \
+        cc->proc.gen   = cpu_generation(_cpu_id);                       \
+        cc->proc.ver   = S390_DEF_VERSION;                              \
+        cc->proc.id    = S390_DEF_ID;                                   \
+        cc->proc.type  = cpu_type(_cpu_id);                             \
+        cc->proc.ibc   = S390_DEF_IBC;                                  \
+        dc->desc       = _desc;                                         \
+    }                                                                   \
+    static const TypeInfo                                               \
+    glue(_cpu_id, _cpu_type_info) = {                                   \
+        .name       = _name "-" TYPE_S390_CPU,                          \
+        .parent     = TYPE_S390_CPU,                                    \
+        .class_init = glue(_cpu_id, _cpu_class_init),                   \
+    };                                                                  \
+    static void                                                         \
+    glue(_cpu_id, _cpu_register_types)(void)                            \
+    {                                                                   \
+        type_register_static(                                           \
+            &glue(_cpu_id, _cpu_type_info));                            \
+    }                                                                   \
+    type_init(glue(_cpu_id, _cpu_register_types))
+
+/* define S390 CPU model classes */
+S390_PROC_DEF("2064-ga1", CPU_S390_2064_GA1, "IBM zSeries 900 GA1")
+S390_PROC_DEF("2064-ga2", CPU_S390_2064_GA2, "IBM zSeries 900 GA2")
+S390_PROC_DEF("2064-ga3", CPU_S390_2064_GA3, "IBM zSeries 900 GA3")
+S390_PROC_DEF("2066-ga1", CPU_S390_2066_GA1, "IBM zSeries 800 GA1")
+S390_PROC_DEF("2084-ga1", CPU_S390_2084_GA1, "IBM zSeries 990 GA1")
+S390_PROC_DEF("2084-ga2", CPU_S390_2084_GA2, "IBM zSeries 990 GA2")
+S390_PROC_DEF("2084-ga3", CPU_S390_2084_GA3, "IBM zSeries 990 GA3")
+S390_PROC_DEF("2084-ga4", CPU_S390_2084_GA4, "IBM zSeries 990 GA4")
+S390_PROC_DEF("2084-ga5", CPU_S390_2084_GA5, "IBM zSeries 990 GA5")
+S390_PROC_DEF("2086-ga1", CPU_S390_2086_GA1, "IBM zSeries 890 GA1")
+S390_PROC_DEF("2086-ga2", CPU_S390_2086_GA2, "IBM zSeries 890 GA2")
+S390_PROC_DEF("2086-ga3", CPU_S390_2086_GA3, "IBM zSeries 890 GA3")
+S390_PROC_DEF("2094-ga1", CPU_S390_2094_GA1, "IBM System z9 EC GA1")
+S390_PROC_DEF("2094-ga2", CPU_S390_2094_GA2, "IBM System z9 EC GA2")
+S390_PROC_DEF("2094-ga3", CPU_S390_2094_GA3, "IBM System z9 EC GA3")
+S390_PROC_DEF("2096-ga1", CPU_S390_2096_GA1, "IBM System z9 BC GA1")
+S390_PROC_DEF("2096-ga2", CPU_S390_2096_GA2, "IBM System z9 BC GA2")
+S390_PROC_DEF("2097-ga1", CPU_S390_2097_GA1, "IBM System z10 EC GA1")
+S390_PROC_DEF("2097-ga2", CPU_S390_2097_GA2, "IBM System z10 EC GA2")
+S390_PROC_DEF("2097-ga3", CPU_S390_2097_GA3, "IBM System z10 EC GA3")
+S390_PROC_DEF("2098-ga1", CPU_S390_2098_GA1, "IBM System z10 BC GA1")
+S390_PROC_DEF("2098-ga2", CPU_S390_2098_GA2, "IBM System z10 BC GA2")
+S390_PROC_DEF("2817-ga1", CPU_S390_2817_GA1, "IBM zEnterprise 196 GA1")
+S390_PROC_DEF("2817-ga2", CPU_S390_2817_GA2, "IBM zEnterprise 196 GA2")
+S390_PROC_DEF("2818-ga1", CPU_S390_2818_GA1, "IBM zEnterprise 114 GA1")
+S390_PROC_DEF("2827-ga1", CPU_S390_2827_GA1, "IBM zEnterprise EC12 GA1")
+S390_PROC_DEF("2827-ga2", CPU_S390_2827_GA2, "IBM zEnterprise EC12 GA2")
+S390_PROC_DEF("2828-ga1", CPU_S390_2828_GA1, "IBM zEnterprise BC12 GA1")
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
new file mode 100644
index 0000000..db681bf
--- /dev/null
+++ b/target-s390x/cpu-models.h
@@ -0,0 +1,71 @@
+/*
+ * CPU models for s390
+ *
+ * Copyright 2014,2015 IBM Corp.
+ *
+ * Author(s): Michael Mueller <mimu@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
+
+#define S390_EC 0x1
+#define S390_BC 0x2
+
+#define S390_DEF_VERSION 0xff
+#define S390_DEF_IBC     0x0
+#define S390_DEF_ID      0xdecade
+#define S390_DEF_TYPE    0x2064
+
+#define cpu_type(x)       (((x) >>  0) & 0xffff)
+#define cpu_order(x)      (((x) >> 16) & 0xffff)
+#define cpu_ga(x)         (((x) >> 16) & 0xf)
+#define cpu_class(x)      (((x) >> 20) & 0x3)
+#define cpu_generation(x) (((x) >> 24) & 0xff)
+
+/*
+ * bits 0-7   : CMOS generation
+ * bits 8-9   : reserved
+ * bits 10-11 : machine class 0=unknown 1=EC 2=BC
+ * bits 12-15 : GA
+ * bits 16-31 : machine type
+ *
+ * note: bits are named according to s390
+ *       architecture specific endienness
+ */
+enum {
+    CPU_S390_2064_GA1 = 0x07112064,
+    CPU_S390_2064_GA2 = 0x07122064,
+    CPU_S390_2064_GA3 = 0x07132064,
+    CPU_S390_2066_GA1 = 0x07212066,
+    CPU_S390_2084_GA1 = 0x08112084,
+    CPU_S390_2084_GA2 = 0x08122084,
+    CPU_S390_2084_GA3 = 0x08132084,
+    CPU_S390_2084_GA4 = 0x08142084,
+    CPU_S390_2084_GA5 = 0x08152084,
+    CPU_S390_2086_GA1 = 0x08212086,
+    CPU_S390_2086_GA2 = 0x08222086,
+    CPU_S390_2086_GA3 = 0x08232086,
+    CPU_S390_2094_GA1 = 0x09112094,
+    CPU_S390_2094_GA2 = 0x09122094,
+    CPU_S390_2094_GA3 = 0x09132094,
+    CPU_S390_2096_GA1 = 0x09212096,
+    CPU_S390_2096_GA2 = 0x09222096,
+    CPU_S390_2097_GA1 = 0x0a112097,
+    CPU_S390_2097_GA2 = 0x0a122097,
+    CPU_S390_2097_GA3 = 0x0a132097,
+    CPU_S390_2098_GA1 = 0x0a212098,
+    CPU_S390_2098_GA2 = 0x0a222098,
+    CPU_S390_2817_GA1 = 0x0b112817,
+    CPU_S390_2817_GA2 = 0x0b122817,
+    CPU_S390_2818_GA1 = 0x0b212818,
+    CPU_S390_2827_GA1 = 0x0c112827,
+    CPU_S390_2827_GA2 = 0x0c122827,
+    CPU_S390_2828_GA1 = 0x0c212828,
+};
+
+#endif
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index 8b376df..a9a5029 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -22,6 +22,7 @@
 
 #include "qom/cpu.h"
 #include "cpu.h"
+#include "gen-facilities.h"
 
 #define TYPE_S390_CPU "s390-cpu"
 
@@ -32,6 +33,24 @@
 #define S390_CPU_GET_CLASS(obj) \
     OBJECT_GET_CLASS(S390CPUClass, (obj), TYPE_S390_CPU)
 
+/* machine related properties */
+typedef struct S390CPUMachineProps {
+    uint16_t class;      /* machine class */
+    uint16_t ga;         /* availability number of machine */
+    uint16_t order;      /* order of availability */
+} S390CPUMachineProps;
+
+/* processor related properties */
+typedef struct S390CPUProcessorProps {
+    uint16_t gen;        /* S390 CMOS generation */
+    uint16_t ver;        /* version of processor */
+    uint32_t id;         /* processor identification*/
+    uint16_t type;       /* machine type */
+    uint16_t ibc;        /* IBC value */
+                         /* processor related facility list */
+    uint64_t fac_list[FAC_LIST_CPU_S390_SIZE_UINT64];
+} S390CPUProcessorProps;
+
 /**
  * S390CPUClass:
  * @parent_realize: The parent class' realize handler.
@@ -52,6 +71,12 @@ typedef struct S390CPUClass {
     void (*load_normal)(CPUState *cpu);
     void (*cpu_reset)(CPUState *cpu);
     void (*initial_cpu_reset)(CPUState *cpu);
+    bool is_active[ACCEL_ID_MAX]; /* model enabled for given host and accel */
+    bool is_host[ACCEL_ID_MAX];   /* model markes host for given accel */
+                                  /* active facility list */
+    uint64_t fac_list[FAC_LIST_CPU_S390_SIZE_UINT64];
+    S390CPUMachineProps   mach;   /* machine specific properties */
+    S390CPUProcessorProps proc;   /* processor specific properties */
 } S390CPUClass;
 
 /**
-- 
1.8.3.1


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

* [PATCH v3 07/16] target-s390x: Define cpu model specific facility lists
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (5 preceding siblings ...)
  2015-03-02 12:43 ` [PATCH v3 06/16] target-s390x: Introduce cpu models Michael Mueller
@ 2015-03-02 12:43 ` Michael Mueller
  2015-03-02 12:44 ` [PATCH v3 08/16] target-s390x: Add cpu model alias definition routines Michael Mueller
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:43 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

This patch defines S390 cpu facilities and their presence at the
different cpu model levels. Beside defining a base which facilities
have to be requested per cpu model, these sets are associated to the
defined cpu classes and used to calculate the list of supported
cpu models in context of the current hosting machine model.

The also defined qemu side facility mask allows to implement and enable
facilities in QEMU land.

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 target-s390x/cpu-models.c | 12 ++++++++++++
 target-s390x/cpu-models.h |  8 ++++++++
 target-s390x/cpu.c        |  1 +
 3 files changed, 21 insertions(+)

diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index 3520691..bd9f0bc 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -12,6 +12,7 @@
 
 #include "qemu-common.h"
 #include "cpu-models.h"
+#include "gen-facilities.h"
 
 #define S390_PROC_DEF(_name, _cpu_id, _desc)                            \
     static void                                                         \
@@ -20,6 +21,10 @@
     {                                                                   \
         DeviceClass *dc = DEVICE_CLASS(oc);                             \
         S390CPUClass *cc = S390_CPU_CLASS(oc);                          \
+        uint64_t nbits = FAC_LIST_CPU_S390_SIZE_UINT1;                  \
+        uint64_t fac_list[FAC_LIST_CPU_S390_SIZE_UINT64] = {            \
+            glue(FAC_LIST_, _cpu_id)                                    \
+        };                                                              \
                                                                         \
         cc->is_active[ACCEL_ID_KVM] = true;                             \
         cc->mach.ga    = cpu_ga(_cpu_id);                               \
@@ -30,6 +35,7 @@
         cc->proc.id    = S390_DEF_ID;                                   \
         cc->proc.type  = cpu_type(_cpu_id);                             \
         cc->proc.ibc   = S390_DEF_IBC;                                  \
+        bitmap_copy(cc->proc.fac_list, fac_list, nbits);                \
         dc->desc       = _desc;                                         \
     }                                                                   \
     static const TypeInfo                                               \
@@ -46,6 +52,11 @@
     }                                                                   \
     type_init(glue(_cpu_id, _cpu_register_types))
 
+/* facilities implemented by qemu */
+uint64_t qemu_s390_fac_list_mask[FAC_LIST_CPU_S390_SIZE_UINT64] = {
+    FAC_LIST_CPU_S390_MASK_QEMU
+};
+
 /* define S390 CPU model classes */
 S390_PROC_DEF("2064-ga1", CPU_S390_2064_GA1, "IBM zSeries 900 GA1")
 S390_PROC_DEF("2064-ga2", CPU_S390_2064_GA2, "IBM zSeries 900 GA2")
@@ -75,3 +86,4 @@ S390_PROC_DEF("2818-ga1", CPU_S390_2818_GA1, "IBM zEnterprise 114 GA1")
 S390_PROC_DEF("2827-ga1", CPU_S390_2827_GA1, "IBM zEnterprise EC12 GA1")
 S390_PROC_DEF("2827-ga2", CPU_S390_2827_GA2, "IBM zEnterprise EC12 GA2")
 S390_PROC_DEF("2828-ga1", CPU_S390_2828_GA1, "IBM zEnterprise BC12 GA1")
+
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index db681bf..d5f0b59 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -13,6 +13,14 @@
 #ifndef TARGET_S390X_CPU_MODELS_H
 #define TARGET_S390X_CPU_MODELS_H
 
+#include "cpu-facilities.h"
+#include "gen-facilities.h"
+
+#define FAC_LIST_ARCH_S390_SIZE_UINT1 \
+    (FAC_LIST_ARCH_S390_SIZE_UINT8 * BITS_PER_BYTE)
+#define FAC_LIST_ARCH_S390_SIZE_UINT64 \
+    (FAC_LIST_ARCH_S390_SIZE_UINT8 / sizeof(uint64_t))
+
 #define S390_EC 0x1
 #define S390_BC 0x2
 
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index d2f6312..7a26b91 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -29,6 +29,7 @@
 #include "qemu/error-report.h"
 #include "hw/hw.h"
 #include "trace.h"
+#include "cpu-models.h"
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/arch_init.h"
 #endif
-- 
1.8.3.1


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

* [PATCH v3 08/16] target-s390x: Add cpu model alias definition routines
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (6 preceding siblings ...)
  2015-03-02 12:43 ` [PATCH v3 07/16] target-s390x: Define cpu model specific facility lists Michael Mueller
@ 2015-03-02 12:44 ` Michael Mueller
  2015-03-02 12:44 ` [PATCH v3 09/16] target-s390x: Update linux-headers/asm-s390/kvm.h Michael Mueller
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:44 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

This patch implements the infrastructure to dynamically add cpu
model aliases.

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 target-s390x/cpu-models.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++
 target-s390x/cpu-models.h | 11 ++++++
 target-s390x/cpu.c        |  1 +
 3 files changed, 101 insertions(+)

diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index bd9f0bc..608189d 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -87,3 +87,92 @@ S390_PROC_DEF("2827-ga1", CPU_S390_2827_GA1, "IBM zEnterprise EC12 GA1")
 S390_PROC_DEF("2827-ga2", CPU_S390_2827_GA2, "IBM zEnterprise EC12 GA2")
 S390_PROC_DEF("2828-ga1", CPU_S390_2828_GA1, "IBM zEnterprise BC12 GA1")
 
+static GSList *s390_cpu_aliases;
+
+static gint s390_cpu_compare_class_name(gconstpointer a, gconstpointer b)
+{
+    const char *aname = object_class_get_name((ObjectClass *) a);
+    const char *bname = b;
+    int blen;
+
+    if (!strcmp(bname, "none") &&
+        !strcmp(aname, TYPE_S390_CPU)) {
+        return 0;
+    }
+    blen = strlen(bname);
+    if (!strncasecmp(bname, aname, blen) &&
+        !strcmp(aname + blen, "-" TYPE_S390_CPU)) {
+        return 0;
+    }
+    return -1;
+}
+
+/**
+ * s390_cpu_class_by_name:
+ * @name: a cpu model or alias name
+ *
+ * The function searches for the requested cpu model name or an alias
+ * cpu model name and returns the associated object class.
+ *
+ * Returns: reference to object class on success or %NULL elsewise.
+ *
+ * Since: 2.3
+ */
+ObjectClass *s390_cpu_class_by_name(const char *name)
+{
+    GSList *list, *item;
+    ObjectClass *ret = NULL;
+    S390CPUAlias *alias;
+
+    for (item = s390_cpu_aliases; item != NULL; item = item->next) {
+        alias = (S390CPUAlias *) item->data;
+        if (strcmp(alias->name, name) == 0) {
+            return s390_cpu_class_by_name(alias->model);
+        }
+    }
+    list = object_class_get_list(TYPE_S390_CPU, false);
+    item = g_slist_find_custom(list, name, s390_cpu_compare_class_name);
+    if (item) {
+        ret = OBJECT_CLASS(item->data);
+    }
+    g_slist_free(list);
+    return ret;
+}
+
+/**
+ * set_s390_cpu_alias:
+ * @name: the cpu alias name
+ * @model: the cpu model name
+ *
+ * The function registers the alias @name for an existing cpu @model.
+ *
+ * Returns: %0 in case of success
+ *          -%EINVAL if name or model is %NULL or both are idential
+ *                   or model is not a valid cpu model
+ *          -%ENOMEM if internal memory allocation fails
+ *
+ * Since: 2.3
+ */
+int set_s390_cpu_alias(const char *name, const char *model)
+{
+    S390CPUAlias *alias;
+
+    if (!name || !model) {
+        return -EINVAL;
+    }
+    if (!strcmp(name, model)) {
+        return -EINVAL;
+    }
+    if (!s390_cpu_class_by_name(model)) {
+        return -EINVAL;
+    }
+    alias = g_try_malloc0(sizeof(S390CPUAlias));
+    if (!alias) {
+        return -ENOMEM;
+    }
+    alias->name = g_strdup(name);
+    alias->model = g_strdup(model);
+    s390_cpu_aliases = g_slist_append(s390_cpu_aliases, alias);
+    return 0;
+}
+
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index d5f0b59..a32f559 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -35,6 +35,17 @@
 #define cpu_class(x)      (((x) >> 20) & 0x3)
 #define cpu_generation(x) (((x) >> 24) & 0xff)
 
+ObjectClass *s390_cpu_class_by_name(const char *name);
+int set_s390_cpu_alias(const char *name, const char *model);
+
+/*
+ * S390 cpu aliases will be added dynamically
+ */
+typedef struct S390CPUAlias {
+    char *name;
+    char *model;
+} S390CPUAlias;
+
 /*
  * bits 0-7   : CMOS generation
  * bits 8-9   : reserved
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 7a26b91..1992910 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -308,6 +308,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
 #endif
     scc->cpu_reset = s390_cpu_reset;
     scc->initial_cpu_reset = s390_cpu_initial_reset;
+    cc->class_by_name = s390_cpu_class_by_name;
     cc->reset = s390_cpu_full_reset;
     cc->has_work = s390_cpu_has_work;
     cc->do_interrupt = s390_cpu_do_interrupt;
-- 
1.8.3.1


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

* [PATCH v3 09/16] target-s390x: Update linux-headers/asm-s390/kvm.h
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (7 preceding siblings ...)
  2015-03-02 12:44 ` [PATCH v3 08/16] target-s390x: Add cpu model alias definition routines Michael Mueller
@ 2015-03-02 12:44 ` Michael Mueller
  2015-03-02 12:44 ` [PATCH v3 10/16] target-s390x: Add KVM VM attribute interface for cpu models Michael Mueller
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:44 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 linux-headers/asm-s390/kvm.h | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
index d36b2fa..e38c942 100644
--- a/linux-headers/asm-s390/kvm.h
+++ b/linux-headers/asm-s390/kvm.h
@@ -57,11 +57,31 @@ struct kvm_s390_io_adapter_req {
 
 /* kvm attr_group  on vm fd */
 #define KVM_S390_VM_MEM_CTRL		0
+#define KVM_S390_VM_CPU_MODEL		3
 
 /* kvm attributes for mem_ctrl */
 #define KVM_S390_VM_MEM_ENABLE_CMMA	0
 #define KVM_S390_VM_MEM_CLR_CMMA	1
 
+/* kvm S390 processor related attributes are r/w */
+#define KVM_S390_VM_CPU_PROCESSOR	0
+struct kvm_s390_vm_cpu_processor {
+	__u64 cpuid;
+	__u16 ibc;
+	__u8  pad[6];
+	__u64 fac_list[256];
+};
+
+/* kvm S390 machine related attributes are r/o */
+#define KVM_S390_VM_CPU_MACHINE		1
+struct kvm_s390_vm_cpu_machine {
+	__u64 cpuid;
+	__u32 ibc_range;
+	__u8  pad[4];
+	__u64 fac_mask[256];
+	__u64 fac_list[256];
+};
+
 /* for KVM_GET_REGS and KVM_SET_REGS */
 struct kvm_regs {
 	/* general purpose regs for s390 */
-- 
1.8.3.1


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

* [PATCH v3 10/16] target-s390x: Add KVM VM attribute interface for cpu models
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (8 preceding siblings ...)
  2015-03-02 12:44 ` [PATCH v3 09/16] target-s390x: Update linux-headers/asm-s390/kvm.h Michael Mueller
@ 2015-03-02 12:44 ` Michael Mueller
  2015-03-02 12:44 ` [PATCH v3 11/16] target-s390x: Add cpu class initialization routines Michael Mueller
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:44 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

The patch implements routines to set and retrieve processor configuration
data and to retrieve machine configuration data. The machine related data
is used together with the cpu model facility lists to determine the list of
supported cpu models of this host. The above mentioned routines have QEMU
trace point instrumentation.

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 target-s390x/cpu-models.h |  39 ++++++++++++++++++
 target-s390x/kvm.c        | 102 ++++++++++++++++++++++++++++++++++++++++++++++
 trace-events              |   3 ++
 3 files changed, 144 insertions(+)

diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index a32f559..b6b57d4 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -46,6 +46,45 @@ typedef struct S390CPUAlias {
     char *model;
 } S390CPUAlias;
 
+typedef struct S390ProcessorProps {
+    uint64_t cpuid;
+    uint16_t ibc;
+    uint8_t  pad[6];
+    uint64_t fac_list[FAC_LIST_ARCH_S390_SIZE_UINT64];
+} S390ProcessorProps;
+
+typedef struct S390MachineProps {
+    uint64_t cpuid;
+    uint32_t ibc_range;
+    uint8_t  pad[4];
+    uint64_t fac_list_mask[FAC_LIST_ARCH_S390_SIZE_UINT64];
+    uint64_t fac_list[FAC_LIST_ARCH_S390_SIZE_UINT64];
+} S390MachineProps;
+
+#ifdef CONFIG_KVM
+int kvm_s390_get_processor_props(S390ProcessorProps *prop);
+int kvm_s390_set_processor_props(S390ProcessorProps *prop);
+bool kvm_s390_cpu_classes_initialized(void);
+bool kvm_s390_probe_mode(void);
+#else
+static inline int kvm_s390_get_processor_props(S390ProcessorProps *prob)
+{
+    return -ENOSYS;
+}
+static inline int kvm_s390_set_processor_props(S390ProcessorProps *prob)
+{
+    return -ENOSYS;
+}
+static inline bool kvm_s390_cpu_classes_initialized(void)
+{
+    return false;
+}
+static inline bool kvm_s390_probe_mode(void)
+{
+    return false;
+}
+#endif
+
 /*
  * bits 0-7   : CMOS generation
  * bits 8-9   : reserved
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index d7c57d9..5404137 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -43,6 +43,7 @@
 #include "hw/s390x/s390-pci-inst.h"
 #include "hw/s390x/s390-pci-bus.h"
 #include "hw/s390x/ipl.h"
+#include "cpu-models.h"
 
 /* #define DEBUG_KVM */
 
@@ -118,6 +119,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
 
 static int cap_sync_regs;
 static int cap_async_pf;
+static bool cpu_classes_initialized;
 
 static void *legacy_s390_alloc(size_t size, uint64_t *align);
 
@@ -173,6 +175,68 @@ static void kvm_s390_enable_cmma(KVMState *s)
     trace_kvm_enable_cmma(rc);
 }
 
+static int cpu_model_get(KVMState *s, uint64_t attr, uint64_t addr)
+{
+    struct kvm_device_attr dev_attr = {
+        .group = KVM_S390_VM_CPU_MODEL,
+        .attr = attr,
+        .addr = addr,
+    };
+
+    return kvm_vm_ioctl(s, KVM_GET_DEVICE_ATTR, &dev_attr);
+}
+
+static int cpu_model_set(KVMState *s, uint64_t attr, uint64_t addr)
+{
+    struct kvm_device_attr dev_attr = {
+        .group = KVM_S390_VM_CPU_MODEL,
+        .attr = attr,
+        .addr = addr,
+    };
+
+    return kvm_vm_ioctl(s, KVM_SET_DEVICE_ATTR, &dev_attr);
+}
+
+static int has_cpu_model_call(KVMState *s, uint64_t attr)
+{
+    int rc;
+    struct kvm_device_attr dev_attr = {
+        .group = KVM_S390_VM_CPU_MODEL,
+        .attr = attr,
+    };
+
+    if (kvm_check_extension(s, KVM_CAP_VM_ATTRIBUTES) == 0) {
+        return -ENOSYS;
+    }
+
+    rc = kvm_vm_ioctl(s, KVM_HAS_DEVICE_ATTR, &dev_attr);
+    if (rc == 0) {
+        return 0;
+    }
+    return -EFAULT;
+}
+
+static int kvm_s390_get_machine_props(KVMState *s, S390MachineProps *prop)
+{
+    int rc;
+
+    rc = has_cpu_model_call(s, KVM_S390_VM_CPU_MACHINE);
+    if (!rc) {
+        rc = cpu_model_get(s, KVM_S390_VM_CPU_MACHINE, (uint64_t) prop);
+    }
+    trace_kvm_get_machine_props(rc, prop->cpuid, prop->ibc_range);
+    return rc;
+}
+
+static void kvm_s390_setup_cpu_classes(KVMState *s)
+{
+    S390MachineProps mach;
+
+    if (!kvm_s390_get_machine_props(s, &mach)) {
+        cpu_classes_initialized = false;
+    }
+}
+
 int kvm_arch_init(KVMState *s)
 {
     cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS);
@@ -186,6 +250,8 @@ int kvm_arch_init(KVMState *s)
         || !kvm_check_extension(s, KVM_CAP_S390_COW)) {
         phys_mem_set_alloc(legacy_s390_alloc);
     }
+
+    kvm_s390_setup_cpu_classes(s);
     return 0;
 }
 
@@ -1578,3 +1644,39 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
     route->u.adapter.adapter_id = pbdev->routes.adapter.adapter_id;
     return 0;
 }
+
+int kvm_s390_get_processor_props(S390ProcessorProps *prop)
+{
+    int rc;
+
+    rc = has_cpu_model_call(kvm_state, KVM_S390_VM_CPU_PROCESSOR);
+    if (!rc) {
+        rc = cpu_model_get(kvm_state,
+                           KVM_S390_VM_CPU_PROCESSOR, (uint64_t) prop);
+    }
+    trace_kvm_get_processor_props(rc, prop->cpuid, prop->ibc);
+    return rc;
+}
+
+int kvm_s390_set_processor_props(S390ProcessorProps *prop)
+{
+    int rc;
+
+    rc = has_cpu_model_call(kvm_state, KVM_S390_VM_CPU_PROCESSOR);
+    if (!rc) {
+        rc = cpu_model_set(kvm_state,
+                           KVM_S390_VM_CPU_PROCESSOR, (uint64_t) prop);
+    }
+    trace_kvm_set_processor_props(rc);
+    return rc;
+}
+
+bool kvm_s390_cpu_classes_initialized(void)
+{
+    return cpu_classes_initialized;
+}
+
+bool kvm_s390_probe_mode(void)
+{
+    return kvm_probe_mode_enabled();
+}
diff --git a/trace-events b/trace-events
index f87b077..f39f879 100644
--- a/trace-events
+++ b/trace-events
@@ -1577,6 +1577,9 @@ mhp_pc_dimm_assigned_address(uint64_t addr) "0x%"PRIx64
 kvm_enable_cmma(int rc) "CMMA: enabling with result code %d"
 kvm_clear_cmma(int rc) "CMMA: clearing with result code %d"
 kvm_failed_cpu_state_set(int cpu_index, uint8_t state, const char *msg) "Warning: Unable to set cpu %d state %" PRIu8 " to KVM: %s"
+kvm_get_machine_props(int rc, uint64_t cpuid, uint16_t ibc) "CPU-MODEL: fetching machine properties rc=%d cpuid=0x%"PRIx64" ibc=0x%"PRIx16
+kvm_get_processor_props(int rc, uint64_t cpuid, uint32_t ibc_range) "CPU-MODEL: fetching processor properties rc=%d cpuid=0x%"PRIx64" ibc_range=0x%"PRIx32
+kvm_set_processor_props(int rc) "CPU-MODEL: requesting processor properties rc=%d"
 
 # hw/dma/i8257.c
 i8257_unregistered_dma(int nchan, int dma_pos, int dma_len) "unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d"
-- 
1.8.3.1


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

* [PATCH v3 11/16] target-s390x: Add cpu class initialization routines
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (9 preceding siblings ...)
  2015-03-02 12:44 ` [PATCH v3 10/16] target-s390x: Add KVM VM attribute interface for cpu models Michael Mueller
@ 2015-03-02 12:44 ` Michael Mueller
  2015-03-02 12:44 ` [PATCH v3 12/16] target-s390x: Prepare accelerator during cpu object realization Michael Mueller
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:44 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

This patch provides routines to dynamically update the previously defined
S390 cpu classes in the current host context. The main function performing
this process is s390_setup_cpu_classes(). It takes the current host context
as parameter to setup the classes accordingly. It basically performs the
following sub-tasks:

- Update of cpu classes with accelerator specific host and QEMU properties
- Mark adequate cpu class as default cpu class to be used for cpu model 'host'
- Invalidate cpu classes not supported by this hosting machine
- Define machine type aliases to latest GA number of a processor model
- Define aliases for common cpu model names
- Set cpu model alias 'host' to default cpu class

Forthermore the patch provides the following routines:

- cpu_desc_avail(), s390 specific stub indicating that list_cpus() can run
- s390_cpu_classes_initialized(), test if cpu classes have been initialized
- s390_probe_mode(), indicates if probe mode is active

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 target-s390x/cpu-models.c | 458 ++++++++++++++++++++++++++++++++++++++++++++++
 target-s390x/cpu-models.h |  26 +++
 target-s390x/cpu.c        |  17 +-
 target-s390x/kvm.c        |   4 +-
 4 files changed, 503 insertions(+), 2 deletions(-)

diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index 608189d..83e590a 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -13,6 +13,7 @@
 #include "qemu-common.h"
 #include "cpu-models.h"
 #include "gen-facilities.h"
+#include "qemu/error-report.h"
 
 #define S390_PROC_DEF(_name, _cpu_id, _desc)                            \
     static void                                                         \
@@ -87,8 +88,41 @@ S390_PROC_DEF("2827-ga1", CPU_S390_2827_GA1, "IBM zEnterprise EC12 GA1")
 S390_PROC_DEF("2827-ga2", CPU_S390_2827_GA2, "IBM zEnterprise EC12 GA2")
 S390_PROC_DEF("2828-ga1", CPU_S390_2828_GA1, "IBM zEnterprise BC12 GA1")
 
+/* some types for calls to g_list_foreach() with parameters */
+typedef struct ParmBoolShortShortAccel {
+    bool valid;
+    unsigned short type;
+    union {
+        unsigned short class;
+        unsigned short gen;
+        unsigned short ga;
+    };
+    AccelId accel;
+} ParmBoolShortShortAccel;
+
+typedef struct ParmAddrAddrAccel {
+    S390MachineProps *prop;
+    S390CPUClass *host_cc;
+    AccelId accel;
+} ParmAddrAddrAccel;
+
 static GSList *s390_cpu_aliases;
 
+/* compare order of two cpu classes for ascending sort */
+gint s390_cpu_class_asc_order_compare(gconstpointer a, gconstpointer b)
+{
+    S390CPUClass *cc_a = S390_CPU_CLASS((ObjectClass *) a);
+    S390CPUClass *cc_b = S390_CPU_CLASS((ObjectClass *) b);
+
+    if (cc_a->mach.order < cc_b->mach.order) {
+        return -1;
+    }
+    if (cc_a->mach.order > cc_b->mach.order) {
+        return 1;
+    }
+    return 0;
+}
+
 static gint s390_cpu_compare_class_name(gconstpointer a, gconstpointer b)
 {
     const char *aname = object_class_get_name((ObjectClass *) a);
@@ -176,3 +210,427 @@ int set_s390_cpu_alias(const char *name, const char *model)
     return 0;
 }
 
+/* return machine class for specific machine type */
+static void s390_machine_class_test_cpu_class(gpointer data, gpointer user_data)
+{
+    S390CPUClass *cc = S390_CPU_CLASS((ObjectClass *) data);
+    ParmBoolShortShortAccel *parm = user_data;
+
+    if (parm->valid || !cc->proc.type || parm->type != cc->proc.type) {
+        return;
+    }
+
+    parm->class = cc->mach.class;
+    parm->valid = true;
+}
+
+/* return machine class by machine type */
+static unsigned short machine_class(unsigned short type, void *user_data)
+{
+    GSList *list = object_class_get_list(TYPE_S390_CPU, false);
+    ParmBoolShortShortAccel parm_class, *parm = user_data;
+
+    if (parm->type != type) {
+        parm->class = 0;
+    }
+    if (!parm->class) {
+        parm_class.type = type;
+        parm_class.class = 0;
+        parm_class.valid = false;
+        g_slist_foreach(list, (GFunc) s390_machine_class_test_cpu_class,
+                        &parm_class);
+        g_slist_free(list);
+        if (parm_class.valid) {
+            parm->class = parm_class.class;
+        }
+    }
+    parm->type = type;
+
+    return parm->class;
+}
+
+/* return CMOS generation for specific machine type */
+static void s390_machine_class_test_cpu_gen(gpointer data, gpointer user_data)
+{
+    S390CPUClass *cc = S390_CPU_CLASS((ObjectClass *) data);
+    ParmBoolShortShortAccel *parm = user_data;
+
+    if (parm->valid) {
+        return;
+    }
+
+    if (parm->type == cc->proc.type) {
+        parm->gen = cc->proc.gen;
+        parm->valid = true;
+    }
+}
+
+/* return CMOS generation by machine type */
+static uint16_t machine_gen(unsigned short type)
+{
+    GSList *list = object_class_get_list(TYPE_S390_CPU, false);
+    ParmBoolShortShortAccel parm;
+
+    parm.type = type;
+    parm.gen = 0;
+    parm.valid = false;
+    g_slist_foreach(list, (GFunc) s390_machine_class_test_cpu_gen, &parm);
+    g_slist_free(list);
+
+    return parm.gen;
+}
+
+/* mark cpu class, used in host cpu model case */
+static void s390_mark_host_cpu_class(gpointer data, gpointer user_data)
+{
+    S390CPUClass *cc = S390_CPU_CLASS((ObjectClass *) data);
+    ParmAddrAddrAccel *parm = user_data;
+    ParmBoolShortShortAccel parm_tc;
+
+    if (!cc->is_active[parm->accel]) {
+        return;
+    }
+
+    parm_tc.type = 0;
+    parm_tc.class = 0;
+    if (cc->mach.class != machine_class(cpuid_type(parm->prop->cpuid),
+                                        &parm_tc)) {
+        /* sort out machines that differ from host machine class */
+        return;
+    }
+    if (!parm->host_cc) {
+        /* use first matching machine type */
+        cc->is_host[parm->accel] = true;
+        parm->host_cc = cc;
+        return;
+    }
+    if (cc->proc.gen > machine_gen(cpuid_type(parm->prop->cpuid))) {
+        /* sort out CMOS generations later than hosts generation */
+        cc->is_active[parm->accel] = false;
+        return;
+    }
+    if (cc->mach.order > parm->host_cc->mach.order) {
+        /* select later machine as host */
+        parm->host_cc->is_host[parm->accel] = false;
+        cc->is_host[parm->accel] = true;
+        parm->host_cc = cc;
+    }
+}
+
+/* update a specific cpu model class with host retrieved configuration */
+static void s390_update_cpu_class(gpointer data, gpointer user_data)
+{
+    ObjectClass *oc = data;
+    ParmAddrAddrAccel *parm = user_data;
+    S390CPUClass *cc = S390_CPU_CLASS(oc);
+    uint64_t fac_list[FAC_LIST_CPU_S390_SIZE_UINT64];
+    uint64_t nbits = FAC_LIST_CPU_S390_SIZE_UINT1;
+
+    if (!cc->proc.type) {
+        return;
+    }
+
+    /* Set processor identifier */
+    cc->proc.id = cpuid_id(parm->prop->cpuid);
+
+    /*
+     * Define model specific IBC value in current host context.
+     * IBC was introduced with CMOS version 10 i.e. type 2097.
+     * For older CPUs it is assumed to be 0x000. The BC system
+     * has always the same IBC version as the previous EC system.
+     * If the host supports IBC but not the requested type, it
+     * will be set to the oldest supported value.
+     */
+    if (has_ibc(parm->prop->ibc_range)) {
+        if (cc->proc.gen >= S390_CMOS_G10) {
+            cc->proc.ibc = ((cc->proc.gen - S390_CMOS_G10) << 4);
+            cc->proc.ibc += cc->mach.ga;
+            if (cc->mach.class == S390_BC) {
+                cc->proc.ibc++;
+            }
+            if (cc->proc.ibc < oldest_ibc(parm->prop->ibc_range)) {
+                cc->proc.ibc = oldest_ibc(parm->prop->ibc_range);
+            }
+            if (cc->proc.ibc > newest_ibc(parm->prop->ibc_range)) {
+                cc->proc.ibc = newest_ibc(parm->prop->ibc_range);
+            }
+        } else {
+            cc->proc.ibc = oldest_ibc(parm->prop->ibc_range);
+        }
+    }
+
+    /*
+     * Processor generation and GA level specific facility properties:
+     *
+     * - cc->fac_list (RFL):
+     *       resulting facility list to be requested for guest cpus
+     * - cc->proc.fac_list (PFL):
+     *       facility list defined per processor generation and GA level
+     *
+     * Machine specific facility properties reported by the host:
+     *
+     * - parm->prop->fac_list (MFL):
+     *       host specifc facility list, might be reduced by some facilities
+     *       in case the host is backed by z/VM and not a LPAR
+     * - parm->prop->fac_list_mask (MFM):
+     *       host specific facility list mask containing facilities
+     *
+     * QEMU defined properties:
+     *
+     *  - qemu_s390_fac_list_mask (QFM):
+     *        locally defined facilities, they are added to the set of
+     *        facilities requested for a guest vcpu. They are visible in
+     *        the guest and require qemu side instruction handling
+     *
+     * The calculation for the vcpu specific facility list (RFL) from the
+     * above defined lists/masks works as follows:
+     *
+     * RFL = PFL & (QFM | MFM)
+     *
+     * Set resulting/desired facilities of given cpu class
+     */
+    bitmap_or(cc->fac_list, qemu_s390_fac_list_mask,
+              parm->prop->fac_list_mask, nbits);
+    bitmap_and(cc->fac_list, cc->fac_list, cc->proc.fac_list, nbits);
+
+    /*
+     * Finally, mark the cpu class inactive if not all resulting/desired
+     * facilities are offered by the host.
+     * (RFL & MFL) != RFL
+     */
+    bitmap_and(fac_list, cc->fac_list, parm->prop->fac_list, nbits);
+    if (!bitmap_equal(fac_list, cc->fac_list, nbits)) {
+        cc->is_active[parm->accel] = false;
+    }
+}
+
+/* a cpu class that is newer then the current host */
+static void s390_set_not_supported_cpu_class(gpointer data, gpointer user_data)
+{
+    S390CPUClass *cc = S390_CPU_CLASS((ObjectClass *) data);
+    ParmAddrAddrAccel *parm = user_data;
+
+    if (!cc->is_active[parm->accel]) {
+        return;
+    }
+    if (cc->proc.gen < parm->host_cc->proc.gen) {
+        return;
+    }
+    if (cc->proc.gen == parm->host_cc->proc.gen) {
+        if (cc->mach.class == parm->host_cc->mach.class &&
+            cc->mach.ga <= parm->host_cc->mach.ga) {
+            return;
+        }
+        if (cc->mach.class == S390_EC &&
+            cc->mach.ga > parm->host_cc->mach.ga) {
+            return;
+        }
+        if (cc->mach.class == S390_BC &&
+            cc->mach.ga < parm->host_cc->mach.ga) {
+            return;
+        }
+    }
+    cc->is_active[parm->accel] = false;
+}
+
+/* set alias by type and ga */
+static int set_s390_cpu_alias_by_type_ga(unsigned short type, unsigned short ga)
+{
+    char name[8], model[16];
+
+    snprintf(name, sizeof(name), "%04x", type);
+    snprintf(model, sizeof(model), "%04x-ga%u", type, ga);
+
+    return set_s390_cpu_alias(name, model);
+}
+
+/* set alias if system has latest ga of a type */
+static void s390_set_ga_alias(gpointer data, gpointer user_data)
+{
+    S390CPUClass *cc = S390_CPU_CLASS((ObjectClass *) data);
+    ParmBoolShortShortAccel *parm = user_data;
+
+    if (!cc->is_active[parm->accel]) {
+        return;
+    }
+    if (!parm->type) {
+        parm->type = cc->proc.type;
+    }
+    if (cc->proc.type == parm->type) {
+        parm->ga = cc->mach.ga;
+        return;
+    }
+    set_s390_cpu_alias_by_type_ga(parm->type, parm->ga);
+    parm->type = cc->proc.type;
+    parm->ga = cc->mach.ga;
+}
+
+/* set host marked cpu class as alias to respective class */
+static void s390_set_host_alias_from_cpu_class(gpointer data,
+                                               gpointer user_data)
+{
+    S390CPUClass *cc = S390_CPU_CLASS((ObjectClass *) data);
+    ParmAddrAddrAccel *parm = user_data;
+
+    char model[16];
+
+    if (!cc->is_active[parm->accel] || !cc->is_host[parm->accel]) {
+        return;
+    }
+    snprintf(model, sizeof(model), "%04x-ga%u", cc->proc.type, cc->mach.ga);
+    set_s390_cpu_alias("host", model);
+}
+
+/**
+ * s390_setup_cpu_classes:
+ * @accel: the accelerator id
+ * @prop: the machine property structure's address
+ *
+ * This function validates the defined cpu classes against the given
+ * machine properties @prop. Only cpu classes that are runnable on the
+ * current host will be set active. In addition the corresponding
+ * cpuid, ibc value and the active set of facilities will be
+ * initialized. When in probe mode, the function can be called for
+ * several accelerators @accel. Though aliases will only be added when
+ * not in probe mode.
+ *
+ * Returns: %0 in case of success -%EINVAL elsewise.
+ *
+ * Since: 2.3
+ */
+int s390_setup_cpu_classes(AccelId accel, S390MachineProps *prop)
+{
+    GSList *list;
+    ParmAddrAddrAccel parm;
+    ParmBoolShortShortAccel parm_alias;
+
+    list = object_class_get_list(TYPE_S390_CPU, false);
+    list = g_slist_sort(list, s390_cpu_class_asc_order_compare);
+
+    /* update cpu classes with accellerator properties */
+    parm.accel = accel;
+    parm.prop = prop;
+    g_slist_foreach(list, (GFunc) s390_update_cpu_class, (gpointer) &parm);
+
+    /* define cpu model "host" */
+    parm.host_cc = NULL;
+    g_slist_foreach(list, (GFunc) s390_mark_host_cpu_class, (gpointer) &parm);
+
+    if (!parm.host_cc) {
+        error_report("Failed to mark host cpu class");
+        return -EINVAL;
+    }
+
+    /* inactivate cpu classes not supported by this host */
+    g_slist_foreach(list, (GFunc) s390_set_not_supported_cpu_class, &parm);
+
+    /* set machine type aliases to latest ga of model (e.g. 2064 -> 2064-ga3) */
+    parm_alias.accel = accel;
+    parm_alias.type = 0;
+    parm_alias.ga = 0;
+    g_slist_foreach(list, (GFunc) s390_set_ga_alias, &parm_alias);
+    set_s390_cpu_alias_by_type_ga(parm_alias.type, parm_alias.ga);
+
+    if (!s390_probe_mode()) {
+        /* set aliases for common model names to machine types */
+        set_s390_cpu_alias("z900",   "2064");
+        set_s390_cpu_alias("z800",   "2066");
+        set_s390_cpu_alias("z990",   "2084");
+        set_s390_cpu_alias("z890",   "2086");
+        set_s390_cpu_alias("z9-109", "2094-ga1");
+        set_s390_cpu_alias("z9",     "2094");
+        set_s390_cpu_alias("z9-ec",  "2094");
+        set_s390_cpu_alias("z9-bc",  "2096");
+        set_s390_cpu_alias("z10",    "2097");
+        set_s390_cpu_alias("z10-ec", "2097");
+        set_s390_cpu_alias("z10-bc", "2098");
+        set_s390_cpu_alias("z196",   "2817");
+        set_s390_cpu_alias("z114",   "2818");
+        set_s390_cpu_alias("zEC12",  "2827");
+        set_s390_cpu_alias("zBC12",  "2828");
+        /* set alias for cpu model "host" at end of list */
+        g_slist_foreach(list, (GFunc) s390_set_host_alias_from_cpu_class,
+                        &parm);
+    }
+
+    g_slist_free(list);
+    return 0;
+}
+
+/* list all supported cpu models and alias names */
+void s390_cpu_list_entry(gpointer data, gpointer user_data)
+{
+    ObjectClass *alias_oc, *oc = data;
+    CPUListState *s = user_data;
+    DeviceClass  *dc = DEVICE_CLASS(oc);
+    S390CPUClass *cc = S390_CPU_CLASS(oc);
+    const char *typename = object_class_get_name(oc);
+    S390CPUAlias *alias;
+    AccelId accel;
+    GSList *item;
+    char *name;
+
+    if (!kvm_enabled()) {
+        return;
+    }
+    accel = ACCEL_ID_KVM;
+    if (!cc->is_active[accel]) {
+        return;
+    }
+    name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_S390_CPU));
+    (*s->cpu_fprintf)(s->file, "s390 %-10s %s\n", name, dc->desc);
+
+    for (item = s390_cpu_aliases; item != NULL; item = item->next) {
+        alias = (S390CPUAlias *) item->data;
+        alias_oc = s390_cpu_class_by_name(alias->model);
+        if (alias_oc != oc) {
+            continue;
+        }
+        (*s->cpu_fprintf)(s->file, "s390 %-10s (alias for %s)\n",
+                          alias->name, name);
+    }
+
+    g_free(name);
+}
+
+/**
+ * s390_cpu_classes_initialized:
+ *
+ * This function indicates if the all cpu classes and their properties
+ * have been initialized.
+ *
+ * Returns: a boolean value.
+ *
+ * Since: 2.3
+ */
+bool s390_cpu_classes_initialized(void)
+{
+    if (kvm_enabled()) {
+        return kvm_s390_cpu_classes_initialized();
+    }
+    return false;
+}
+
+bool cpu_desc_avail(void)
+{
+    return s390_cpu_classes_initialized();
+}
+
+/**
+ * s390_probe_mode:
+ *
+ * This function indicates that cpu class initialization takes place
+ * in probe mode.
+ *
+ * Returns: a boolean value.
+ *
+ * Since: 2.3
+ */
+bool s390_probe_mode(void)
+{
+    if (kvm_enabled() && kvm_s390_probe_mode()) {
+        return true;
+    }
+    return false;
+}
+
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index b6b57d4..aa81c9b 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -29,12 +29,32 @@
 #define S390_DEF_ID      0xdecade
 #define S390_DEF_TYPE    0x2064
 
+/* first s390 CMOS generation supporting IBC */
+#define S390_CMOS_G10    0xa
+
 #define cpu_type(x)       (((x) >>  0) & 0xffff)
 #define cpu_order(x)      (((x) >> 16) & 0xffff)
 #define cpu_ga(x)         (((x) >> 16) & 0xf)
 #define cpu_class(x)      (((x) >> 20) & 0x3)
 #define cpu_generation(x) (((x) >> 24) & 0xff)
 
+#define cpuid_type(x)     (((x) >> 16) & 0xffff)
+#define cpuid_id(x)       (((x) >> 32) & 0xffffff)
+#define cpuid_ver(x)      (((x) >> 56) & 0xff)
+
+#define type_cpuid(x)     ((uint64_t)((x) & 0xffff) << 16)
+#define id_cpuid(x)       ((uint64_t)((x) & 0xffffff) << 32)
+#define ver_cpuid(x)      ((uint64_t)((x) & 0xff) << 56)
+
+#define oldest_ibc(x)     (((uint32_t)(x) >> 16) & 0xfff)
+#define newest_ibc(x)     ((uint32_t)(x) & 0xfff)
+#define has_ibc(x)        (oldest_ibc(x) != 0)
+
+#define S390_DEF_CPUID             \
+    (ver_cpuid(S390_DEF_VERSION) | \
+     id_cpuid(S390_DEF_ID) |       \
+     type_cpuid(S390_DEF_TYPE))
+
 ObjectClass *s390_cpu_class_by_name(const char *name);
 int set_s390_cpu_alias(const char *name, const char *model);
 
@@ -85,6 +105,12 @@ static inline bool kvm_s390_probe_mode(void)
 }
 #endif
 
+int s390_setup_cpu_classes(AccelId accel, S390MachineProps *prop);
+gint s390_cpu_class_asc_order_compare(gconstpointer a, gconstpointer b);
+void s390_cpu_list_entry(gpointer data, gpointer user_data);
+bool s390_cpu_classes_initialized(void);
+bool s390_probe_mode(void);
+
 /*
  * bits 0-7   : CMOS generation
  * bits 8-9   : reserved
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 1992910..c9200ee 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -41,7 +41,22 @@
 void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 {
 #ifdef CONFIG_KVM
-    (*cpu_fprintf)(f, "s390 %16s\n", "host");
+    CPUListState s = {
+        .file = f,
+        .cpu_fprintf = cpu_fprintf,
+    };
+    GSList *list;
+
+    if (kvm_enabled() && s390_cpu_classes_initialized()) {
+        list = object_class_get_list(TYPE_S390_CPU, false);
+        list = g_slist_sort(list, s390_cpu_class_asc_order_compare);
+        g_slist_foreach(list, s390_cpu_list_entry, &s);
+        g_slist_free(list);
+    } else {
+#endif
+        (*cpu_fprintf)(f, "s390 host\n");
+#ifdef CONFIG_KVM
+    }
 #endif
 }
 
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 5404137..07d07b2 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -233,7 +233,9 @@ static void kvm_s390_setup_cpu_classes(KVMState *s)
     S390MachineProps mach;
 
     if (!kvm_s390_get_machine_props(s, &mach)) {
-        cpu_classes_initialized = false;
+        if (!s390_setup_cpu_classes(ACCEL_ID_KVM, &mach)) {
+            cpu_classes_initialized = true;
+        }
     }
 }
 
-- 
1.8.3.1


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

* [PATCH v3 12/16] target-s390x: Prepare accelerator during cpu object realization
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (10 preceding siblings ...)
  2015-03-02 12:44 ` [PATCH v3 11/16] target-s390x: Add cpu class initialization routines Michael Mueller
@ 2015-03-02 12:44 ` Michael Mueller
  2015-03-02 12:44 ` [PATCH v3 13/16] target-s390x: New QMP command query-cpu-model Michael Mueller
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:44 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

This patch implements routine s390_cpu_model_init(). It is called by the
realize function during instantiation of an cpu object. Its task is to
initialize the current accelerator with the properties of the selected
processor model.

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 target-s390x/cpu-models.c | 36 ++++++++++++++++++++++++++++++++++++
 target-s390x/cpu-models.h |  4 ++++
 target-s390x/cpu.c        |  1 +
 3 files changed, 41 insertions(+)

diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index 83e590a..c6c1771 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -107,6 +107,7 @@ typedef struct ParmAddrAddrAccel {
 } ParmAddrAddrAccel;
 
 static GSList *s390_cpu_aliases;
+static bool cpu_models_used;
 
 /* compare order of two cpu classes for ascending sort */
 gint s390_cpu_class_asc_order_compare(gconstpointer a, gconstpointer b)
@@ -634,3 +635,38 @@ bool s390_probe_mode(void)
     return false;
 }
 
+/**
+ * s390_cpu_model_init:
+ * @cc: S390 CPU class
+ *
+ * This function intitializes the current accelerator with processor
+ * related properties.
+ *
+ * Since: 2.3
+ */
+void s390_cpu_model_init(S390CPUClass *cc)
+{
+    S390ProcessorProps proc;
+
+    /* none cpu model case */
+    if (!strcmp(object_class_get_name(OBJECT_CLASS(cc)), TYPE_S390_CPU)) {
+        return;
+    }
+
+    /* accelerator already prepared */
+    if (cpu_models_used) {
+        return;
+    }
+
+    proc.cpuid = cpuid(cc->proc);
+    proc.ibc = cc->proc.ibc;
+    bitmap_zero(proc.fac_list, FAC_LIST_ARCH_S390_SIZE_UINT1);
+    bitmap_copy(proc.fac_list, cc->fac_list, FAC_LIST_CPU_S390_SIZE_UINT1);
+
+    if (kvm_enabled()) {
+        if (!kvm_s390_set_processor_props(&proc)) {
+            cpu_models_used = true;
+        }
+    }
+}
+
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index aa81c9b..f3f914a 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -45,6 +45,9 @@
 #define type_cpuid(x)     ((uint64_t)((x) & 0xffff) << 16)
 #define id_cpuid(x)       ((uint64_t)((x) & 0xffffff) << 32)
 #define ver_cpuid(x)      ((uint64_t)((x) & 0xff) << 56)
+#define cpuid(x)          (ver_cpuid(x.ver) |  \
+                           id_cpuid(x.id) |    \
+                           type_cpuid(x.type))
 
 #define oldest_ibc(x)     (((uint32_t)(x) >> 16) & 0xfff)
 #define newest_ibc(x)     ((uint32_t)(x) & 0xfff)
@@ -110,6 +113,7 @@ gint s390_cpu_class_asc_order_compare(gconstpointer a, gconstpointer b);
 void s390_cpu_list_entry(gpointer data, gpointer user_data);
 bool s390_cpu_classes_initialized(void);
 bool s390_probe_mode(void);
+void s390_cpu_model_init(S390CPUClass *cc);
 
 /*
  * bits 0-7   : CMOS generation
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index c9200ee..2f4192e 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -178,6 +178,7 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
     CPUState *cs = CPU(dev);
     S390CPUClass *scc = S390_CPU_GET_CLASS(dev);
 
+    s390_cpu_model_init(scc);
     s390_cpu_gdb_init(cs);
     qemu_init_vcpu(cs);
 #if !defined(CONFIG_USER_ONLY)
-- 
1.8.3.1


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

* [PATCH v3 13/16] target-s390x: New QMP command query-cpu-model
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (11 preceding siblings ...)
  2015-03-02 12:44 ` [PATCH v3 12/16] target-s390x: Prepare accelerator during cpu object realization Michael Mueller
@ 2015-03-02 12:44 ` Michael Mueller
  2015-03-02 12:44 ` [PATCH v3 14/16] target-s390x: Extend QMP command query-cpu-definitions Michael Mueller
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:44 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

This patch implements a new QMP request named 'query-cpu-model'.
It returns the cpu model of cpu 0 and its backing accelerator.

request:
  {"execute" : "query-cpu-model" }

answer:
  {"return" : {"name": "2827-ga2", "accelerator": "kvm" }}

Alias names are resolved to their respective machine type and GA names
already during cpu instantiation. Thus, also a cpu model like 'host'
which is implemented as alias will return its normalized cpu model name.

Furthermore the patch implements the following functions:

- s390_cpu_typename(), returns the currently selected cpu type name or NULL
- s390_cpu_models_used(), returns true if S390 cpu models are in use

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 include/sysemu/arch_init.h |  1 +
 qapi-schema.json           | 25 +++++++++++++++++++++++++
 qmp-commands.hx            |  6 ++++++
 qmp.c                      |  5 +++++
 stubs/Makefile.objs        |  1 +
 stubs/arch-query-cpu-mod.c |  9 +++++++++
 target-s390x/cpu-models.c  | 13 +++++++++++++
 target-s390x/cpu-models.h  |  1 +
 target-s390x/cpu.c         | 29 +++++++++++++++++++++++++++++
 9 files changed, 90 insertions(+)
 create mode 100644 stubs/arch-query-cpu-mod.c

diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 54b36c1..86344a2 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -37,5 +37,6 @@ int kvm_available(void);
 int xen_available(void);
 
 CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp);
+CpuModelInfo *arch_query_cpu_model(Error **errp);
 
 #endif
diff --git a/qapi-schema.json b/qapi-schema.json
index ea436ec..e9b213f 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2507,6 +2507,31 @@
 ##
 { 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] }
 
+##
+# @CpuModelInfo:
+#
+# Virtual CPU model definition.
+#
+# @name: the name of the CPU model definition
+#
+# @accelerator: AccelId (name) of this cpu models acceletaror
+#
+# Since: 2.3
+##
+{ 'type': 'CpuModelInfo',
+  'data': { 'name': 'str', 'accelerator': 'AccelId' } }
+
+##
+# @query-cpu-model:
+#
+# Return the current virtual CPU model
+#
+# Returns: CpuModelInfo
+#
+# Since: 2.3
+##
+{ 'command': 'query-cpu-model', 'returns': 'CpuModelInfo' }
+
 # @AddfdInfo:
 #
 # Information about a file descriptor that was added to an fd set.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index a85d847..98bfedd 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3392,6 +3392,12 @@ EQMP
     },
 
     {
+        .name       = "query-cpu-model",
+        .args_type  = "",
+        .mhandler.cmd_new = qmp_marshal_input_query_cpu_model,
+    },
+
+    {
         .name       = "query-target",
         .args_type  = "",
         .mhandler.cmd_new = qmp_marshal_input_query_target,
diff --git a/qmp.c b/qmp.c
index d701cff..11b6172 100644
--- a/qmp.c
+++ b/qmp.c
@@ -573,6 +573,11 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
     return arch_query_cpu_definitions(errp);
 }
 
+CpuModelInfo *qmp_query_cpu_model(Error **errp)
+{
+    return arch_query_cpu_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 fd7a489..45daa92 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-mod.o
 stub-obj-y += bdrv-commit-all.o
 stub-obj-y += chr-baum-init.o
 stub-obj-y += chr-msmouse.o
diff --git a/stubs/arch-query-cpu-mod.c b/stubs/arch-query-cpu-mod.c
new file mode 100644
index 0000000..90ebd08
--- /dev/null
+++ b/stubs/arch-query-cpu-mod.c
@@ -0,0 +1,9 @@
+#include "qemu-common.h"
+#include "sysemu/arch_init.h"
+#include "qapi/qmp/qerror.h"
+
+CpuModelInfo *arch_query_cpu_model(Error **errp)
+{
+    error_set(errp, QERR_UNSUPPORTED);
+    return NULL;
+}
diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index c6c1771..116dbcc 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -670,3 +670,16 @@ void s390_cpu_model_init(S390CPUClass *cc)
     }
 }
 
+/**
+ * s390_cpu_models_used:
+ *
+ * This function indicates if cpus with model properties are in use.
+ *
+ * Returns: a boolean value.
+ *
+ * Since: 2.3
+ */
+bool s390_cpu_models_used(void)
+{
+    return cpu_models_used;
+}
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index f3f914a..51db298 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -114,6 +114,7 @@ void s390_cpu_list_entry(gpointer data, gpointer user_data);
 bool s390_cpu_classes_initialized(void);
 bool s390_probe_mode(void);
 void s390_cpu_model_init(S390CPUClass *cc);
+bool s390_cpu_models_used(void);
 
 /*
  * bits 0-7   : CMOS generation
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 2f4192e..cefaff1 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -37,6 +37,11 @@
 #define CR0_RESET       0xE0UL
 #define CR14_RESET      0xC2000000UL;
 
+static inline char *strdup_s390_cpu_name(S390CPUClass *cc)
+{
+    return g_strdup_printf("%04x-ga%u", cc->proc.type, cc->mach.ga);
+}
+
 /* generate CPU information for cpu -? */
 void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 {
@@ -74,6 +79,30 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
 
     return entry;
 }
+
+CpuModelInfo *arch_query_cpu_model(Error **errp)
+{
+    CpuModelInfo *info;
+    S390CPUClass *cc;
+
+    if (!s390_cpu_models_used()) {
+        return NULL;
+    }
+    info = g_try_new0(CpuModelInfo, 1);
+    if (!info) {
+        return NULL;
+    }
+    cc = S390_CPU_GET_CLASS(s390_cpu_addr2state(0));
+    info->name = strdup_s390_cpu_name(cc);
+    if (!info->name) {
+        g_free(info);
+        return NULL;
+    }
+    if (kvm_enabled()) {
+        info->accelerator = ACCEL_ID_KVM;
+    }
+    return info;
+}
 #endif
 
 static void s390_cpu_set_pc(CPUState *cs, vaddr value)
-- 
1.8.3.1


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

* [PATCH v3 14/16] target-s390x: Extend QMP command query-cpu-definitions
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (12 preceding siblings ...)
  2015-03-02 12:44 ` [PATCH v3 13/16] target-s390x: New QMP command query-cpu-model Michael Mueller
@ 2015-03-02 12:44 ` Michael Mueller
  2015-03-02 19:11   ` Eduardo Habkost
  2015-03-02 12:44 ` [PATCH v3 15/16] target-s390x: Introduce facility test routine Michael Mueller
                   ` (2 subsequent siblings)
  16 siblings, 1 reply; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:44 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

This patch implements the QMP command 'query-cpu-definitions' in the S390
context. The command returns a list of cpu model names in the current host
context. A consumer may successfully request each listed cpu model as long
for a given accelerator this model is runnable.

The QMP type AccelCpuModelInfo is introduced and the type CpuDefinitionInfo
is extended by the optional field 'accelerators'. It contains a list of named
accelerators and some indication whether the associated cpu model is runnable
or the default cpu model. The default cpu model is used if either no specific
cpu model is requested during QEMU startup or if the cpu model with name
'host' is requested.

request:
  {"execute": "query-cpu-definitions"}

answer:
  {"return":
    [{"name":"2964-ga1","accelerators":[{"name":"kvm","runnable":false,"default":false}]},
     {"name":"2828-ga1","accelerators":[{"name":"kvm","runnable":false,"default":false}]},
     {"name":"2827-ga2","accelerators":[{"name":"kvm","runnable":true,"default":true}]},
     {"name":"2827-ga1","accelerators":[{"name":"kvm","runnable":true,"default":false}]},
     {"name":"2818-ga1","accelerators":[{"name":"kvm","runnable":true,"default":false}]},
     ...
     {"name":"2064-ga1","accelerators":[{"runnable":true,"name":"kvm","default":false}]}
    ]
   }

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 qapi-schema.json          |  21 +++++++++-
 target-s390x/cpu-models.c |  15 +++++++
 target-s390x/cpu-models.h |   1 +
 target-s390x/cpu.c        | 100 +++++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 130 insertions(+), 7 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index e9b213f..44863e5 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2485,16 +2485,35 @@
   'data': ['qtest', 'tcg', 'kvm', 'xen'  ] }
 
 ##
+# @AccelCpuModelInfo:
+#
+# Accelerator specific CPU model data
+#
+# @name: the accelerator name
+#
+# @default: cpu model for 'host'
+#
+# @runnable: cpu model can be activated on hosting machine
+#
+# Since: 2.3
+#
+##
+{ 'type': 'AccelCpuModelInfo',
+  'data': { 'name': 'AccelId', 'default': 'bool', 'runnable': 'bool' } }
+
+##
 # @CpuDefinitionInfo:
 #
 # Virtual CPU definition.
 #
 # @name: the name of the CPU definition
 #
+# @accelerators: #optional cpu model offered per accelerator (since 2.3)
+#
 # Since: 1.2.0
 ##
 { 'type': 'CpuDefinitionInfo',
-  'data': { 'name': 'str' } }
+  'data': { 'name': 'str', '*accelerators': ['AccelCpuModelInfo'] } }
 
 ##
 # @query-cpu-definitions:
diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index 116dbcc..7ad61df 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -211,6 +211,21 @@ int set_s390_cpu_alias(const char *name, const char *model)
     return 0;
 }
 
+/* compare order of two cpu classes for descending sort */
+gint s390_cpu_class_desc_order_compare(gconstpointer a, gconstpointer b)
+{
+    S390CPUClass *cc_a = S390_CPU_CLASS((ObjectClass *) a);
+    S390CPUClass *cc_b = S390_CPU_CLASS((ObjectClass *) b);
+
+    if (cc_a->mach.order < cc_b->mach.order) {
+        return 1;
+    }
+    if (cc_a->mach.order > cc_b->mach.order) {
+        return -1;
+    }
+    return 0;
+}
+
 /* return machine class for specific machine type */
 static void s390_machine_class_test_cpu_class(gpointer data, gpointer user_data)
 {
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index 51db298..3605aa4 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -110,6 +110,7 @@ static inline bool kvm_s390_probe_mode(void)
 
 int s390_setup_cpu_classes(AccelId accel, S390MachineProps *prop);
 gint s390_cpu_class_asc_order_compare(gconstpointer a, gconstpointer b);
+gint s390_cpu_class_desc_order_compare(gconstpointer a, gconstpointer b);
 void s390_cpu_list_entry(gpointer data, gpointer user_data);
 bool s390_cpu_classes_initialized(void);
 bool s390_probe_mode(void);
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index cefaff1..6bf6554 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -66,18 +66,106 @@ void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 }
 
 #ifndef CONFIG_USER_ONLY
-CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
+static AccelCpuModelInfoList *qmp_query_accel_entry(AccelId accel,
+                                                    S390CPUClass *cc,
+                                                    AccelCpuModelInfoList *prev)
+{
+    AccelCpuModelInfoList *list;
+    AccelCpuModelInfo *info;
+
+    info = g_try_new0(AccelCpuModelInfo, 1);
+    if (!info) {
+        goto out;
+    }
+    info->name = accel;
+    info->runnable = cc->is_active[accel];
+    info->q_default = cc->is_host[accel];
+    list = g_try_new0(AccelCpuModelInfoList, 1);
+    if (!list) {
+        goto out;
+    }
+    list->value = info;
+    list->next = prev;
+
+    return list;
+out:
+    g_free(info);
+    return prev;
+}
+
+static void qmp_query_cpu_definition_entry(gpointer data, gpointer user_data)
+{
+    ObjectClass *oc = (ObjectClass *) data;
+    S390CPUClass *cc = S390_CPU_CLASS(oc);
+    CpuDefinitionInfoList *list, **prev = user_data;
+    CpuDefinitionInfo *info;
+
+    if (!strcmp(object_class_get_name(oc), TYPE_S390_CPU)) {
+        return;
+    }
+    info = g_try_new0(CpuDefinitionInfo, 1);
+    if (!info) {
+        goto out;
+    }
+    info->name = strdup_s390_cpu_name(cc);
+    if (kvm_enabled()) {
+        info->accelerators =
+            qmp_query_accel_entry(ACCEL_ID_KVM, cc, info->accelerators);
+    }
+    info->has_accelerators = (info->accelerators) ? true : false;
+    list = g_try_new0(CpuDefinitionInfoList, 1);
+    if (!list) {
+        goto out;
+    }
+    list->value = info;
+    list->next = *prev;
+    *prev = list;
+    return;
+out:
+    if (info) {
+        g_free(info->name);
+        g_free(info);
+    }
+}
+
+static CpuDefinitionInfoList *qmp_query_cpu_definition_host(void)
 {
-    CpuDefinitionInfoList *entry;
+    CpuDefinitionInfoList *host = NULL;
     CpuDefinitionInfo *info;
 
-    info = g_malloc0(sizeof(*info));
+    info = g_try_new0(CpuDefinitionInfo, 1);
+    if (!info) {
+        goto out;
+    }
     info->name = g_strdup("host");
 
-    entry = g_malloc0(sizeof(*entry));
-    entry->value = info;
+    host = g_try_new0(CpuDefinitionInfoList, 1);
+    if (!host) {
+        g_free(info->name);
+        g_free(info);
+        goto out;
+    }
+    host->value = info;
+out:
+    return host;
+}
+
+CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
+{
+    CpuDefinitionInfoList *list = NULL;
+    GSList *class_list;
+
+    if (!s390_probe_mode()) {
+        if (!s390_cpu_models_used()) {
+            return qmp_query_cpu_definition_host();
+        }
+    }
+    class_list = object_class_get_list(TYPE_S390_CPU, false);
+    class_list = g_slist_sort(class_list, s390_cpu_class_asc_order_compare);
+    g_slist_foreach(class_list, qmp_query_cpu_definition_entry, &list);
+    g_slist_free(class_list);
 
-    return entry;
+    return list;
 }
 
 CpuModelInfo *arch_query_cpu_model(Error **errp)
-- 
1.8.3.1


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

* [PATCH v3 15/16] target-s390x: Introduce facility test routine
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (13 preceding siblings ...)
  2015-03-02 12:44 ` [PATCH v3 14/16] target-s390x: Extend QMP command query-cpu-definitions Michael Mueller
@ 2015-03-02 12:44 ` Michael Mueller
  2015-03-02 12:44 ` [PATCH v3 16/16] target-s390x: Enable cpu model usage Michael Mueller
  2015-03-02 19:25 ` [PATCH v3 00/16] s390x cpu model implementation Eduardo Habkost
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:44 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

The patch introduces routine s390_facility_test() which allows to
verify a specific facility bit is set.

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 target-s390x/cpu-models.c | 30 ++++++++++++++++++++++++++++++
 target-s390x/cpu-models.h |  1 +
 2 files changed, 31 insertions(+)

diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index 7ad61df..5c4eac5 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -698,3 +698,33 @@ bool s390_cpu_models_used(void)
 {
     return cpu_models_used;
 }
+
+static inline int test_facility(uint64_t *fac_list, uint16_t nr)
+{
+    uint16_t word = nr / BITS_PER_LONG;
+    uint16_t be_bit = (BITS_PER_LONG - 1) - (nr % BITS_PER_LONG);
+
+    return (nr < FAC_LIST_CPU_S390_SIZE_UINT1) ?
+        (fac_list[word] >> be_bit) & __UINT64_C(1) : 0;
+}
+
+/**
+ * s390_test_facility:
+ * @nr: facility bit number to test
+ * @cc: cpu class to test
+ *
+ * The functions tests if the cpu facility identified by bit @nr is available
+ * to the cpu class @cc.
+ *
+ * Returns: a boolean value.
+ *
+ * Since: 2.3
+ */
+bool s390_test_facility(S390CPUClass *cc, uint16_t nr)
+{
+    if (!cc) {
+        return false;
+    }
+    return test_facility(cc->fac_list, nr) ? true : false;
+}
+
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index 3605aa4..557f5e5 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -116,6 +116,7 @@ bool s390_cpu_classes_initialized(void);
 bool s390_probe_mode(void);
 void s390_cpu_model_init(S390CPUClass *cc);
 bool s390_cpu_models_used(void);
+bool s390_test_facility(S390CPUClass *cc, uint16_t nr);
 
 /*
  * bits 0-7   : CMOS generation
-- 
1.8.3.1


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

* [PATCH v3 16/16] target-s390x: Enable cpu model usage
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (14 preceding siblings ...)
  2015-03-02 12:44 ` [PATCH v3 15/16] target-s390x: Introduce facility test routine Michael Mueller
@ 2015-03-02 12:44 ` Michael Mueller
  2015-03-02 19:25 ` [PATCH v3 00/16] s390x cpu model implementation Eduardo Habkost
  16 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 12:44 UTC (permalink / raw)
  To: qemu-devel, kvm, linux-s390, linux-kernel
  Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
	Richard Henderson, Eduardo Habkost, Michael Mueller

This patch enables QEMU to instantiate S390 CPUs with cpu model types.

Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
 hw/s390x/s390-virtio.c | 12 +++++++++++-
 target-s390x/helper.c  |  9 ++-------
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 412e49b..0bf7632 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -32,6 +32,7 @@
 #include "hw/virtio/virtio.h"
 #include "hw/sysbus.h"
 #include "sysemu/kvm.h"
+#include "sysemu/cpus.h"
 #include "exec/address-spaces.h"
 
 #include "hw/s390x/s390-virtio-bus.h"
@@ -153,7 +154,12 @@ void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys)
     int i;
 
     if (cpu_model == NULL) {
-        cpu_model = "host";
+        cpu_model = "none";
+    }
+
+    if (is_help_option(cpu_model)) {
+        list_cpus(stdout, &fprintf, cpu_model);
+        exit(0);
     }
 
     ipi_states = g_malloc(sizeof(S390CPU *) * smp_cpus);
@@ -163,6 +169,10 @@ void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys)
         CPUState *cs;
 
         cpu = cpu_s390x_init(cpu_model);
+        if (cpu == NULL) {
+            fprintf(stderr, "Unable to find CPU definition\n");
+            exit(1);
+        }
         cs = CPU(cpu);
 
         ipi_states[i] = cpu;
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index e0fd8fc..5b6bad2 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -22,6 +22,7 @@
 #include "exec/gdbstub.h"
 #include "qemu/timer.h"
 #include "exec/cpu_ldst.h"
+#include "cpu-models.h"
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/sysemu.h"
 #endif
@@ -66,13 +67,7 @@ void s390x_cpu_timer(void *opaque)
 
 S390CPU *cpu_s390x_init(const char *cpu_model)
 {
-    S390CPU *cpu;
-
-    cpu = S390_CPU(object_new(TYPE_S390_CPU));
-
-    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
-
-    return cpu;
+    return S390_CPU(cpu_generic_init(TYPE_S390_CPU, cpu_model));
 }
 
 #if defined(CONFIG_USER_ONLY)
-- 
1.8.3.1


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

* Re: [PATCH v3 01/16] Introduce probe mode for machine type none
  2015-03-02 12:43 ` [PATCH v3 01/16] Introduce probe mode for machine type none Michael Mueller
@ 2015-03-02 13:57   ` Andreas Färber
  2015-03-02 16:43     ` [Qemu-devel] " Michael Mueller
  2015-03-02 19:17   ` Eduardo Habkost
  1 sibling, 1 reply; 29+ messages in thread
From: Andreas Färber @ 2015-03-02 13:57 UTC (permalink / raw)
  To: qemu-devel, Edgar E. Iglesias, Peter Crosthwaite
  Cc: Michael Mueller, kvm, linux-s390, linux-kernel, Gleb Natapov,
	Alexander Graf, Christian Borntraeger, Jason J. Herne,
	Cornelia Huck, Paolo Bonzini, Richard Henderson, Eduardo Habkost,
	Alistair Francis

Am 02.03.2015 um 13:43 schrieb Michael Mueller:
> QEMU now switches into "probe mode" when the selected machine is "none" and no
> specific accelerator(s) has been requested (i.e.: "-machine none").
> 
> In probe mode a by "<ARCH>_CONFIG" defines predefined list of accelerators run
> their init() methods.
> 
> Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
> ---
>  accel.c              | 31 +++++++++++++++++++++++++------
>  include/hw/boards.h  |  1 +
>  include/sysemu/kvm.h | 10 ++++++++++
>  kvm-all.c            |  3 +++
>  4 files changed, 39 insertions(+), 6 deletions(-)

Edgar/Peter, isn't Xilinx using -machine none in TCG mode?

> @@ -78,20 +83,30 @@ static int accel_init_machine(AccelClass *acc, MachineState *ms)
>  
>  int configure_accelerator(MachineState *ms)
>  {
> -    const char *p;
> +    const char *p, *name;
>      char buf[10];
>      int ret;
>      bool accel_initialised = false;
>      bool init_failed = false;
>      AccelClass *acc = NULL;
> +    ObjectClass *oc;
> +    bool probe_mode = false;
>  
>      p = qemu_opt_get(qemu_get_machine_opts(), "accel");
>      if (p == NULL) {
> -        /* Use the default "accelerator", tcg */
> -        p = "tcg";
> +        oc = (ObjectClass *) MACHINE_GET_CLASS(current_machine);
> +        name = object_class_get_name(oc);
> +        probe_mode = !strcmp(name, "none" TYPE_MACHINE_SUFFIX);
> +        if (probe_mode) {
> +            /* Use these accelerators in probe mode, tcg should be last */
> +            p = probe_mode_accels;
> +        } else {
> +            /* Use the default "accelerator", tcg */
> +            p = "tcg";
> +        }
>      }

Can't we instead use an explicit ,accel=probe or ,accel=auto?
That would then obsolete the next patch.

Regards,
Andreas

>  
> -    while (!accel_initialised && *p != '\0') {
> +    while ((probe_mode || !accel_initialised) && *p != '\0') {
>          if (*p == ':') {
>              p++;
>          }

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu,
Graham Norton; HRB 21284 (AG Nürnberg)

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

* Re: [Qemu-devel] [PATCH v3 01/16] Introduce probe mode for machine type none
  2015-03-02 13:57   ` Andreas Färber
@ 2015-03-02 16:43     ` Michael Mueller
  2015-03-02 16:57       ` Andreas Färber
  0 siblings, 1 reply; 29+ messages in thread
From: Michael Mueller @ 2015-03-02 16:43 UTC (permalink / raw)
  To: Andreas Färber
  Cc: qemu-devel, Edgar E. Iglesias, Peter Crosthwaite, linux-s390,
	kvm, Gleb Natapov, Alexander Graf, Eduardo Habkost, linux-kernel,
	Christian Borntraeger, Jason J. Herne, Cornelia Huck,
	Paolo Bonzini, Alistair Francis, Richard Henderson

On Mon, 02 Mar 2015 14:57:21 +0100
Andreas Färber <afaerber@suse.de> wrote:

> >  int configure_accelerator(MachineState *ms)
> >  {
> > -    const char *p;
> > +    const char *p, *name;
> >      char buf[10];
> >      int ret;
> >      bool accel_initialised = false;
> >      bool init_failed = false;
> >      AccelClass *acc = NULL;
> > +    ObjectClass *oc;
> > +    bool probe_mode = false;
> >  
> >      p = qemu_opt_get(qemu_get_machine_opts(), "accel");
> >      if (p == NULL) {
> > -        /* Use the default "accelerator", tcg */
> > -        p = "tcg";
> > +        oc = (ObjectClass *) MACHINE_GET_CLASS(current_machine);
> > +        name = object_class_get_name(oc);
> > +        probe_mode = !strcmp(name, "none" TYPE_MACHINE_SUFFIX);
> > +        if (probe_mode) {
> > +            /* Use these accelerators in probe mode, tcg should be last */
> > +            p = probe_mode_accels;
> > +        } else {
> > +            /* Use the default "accelerator", tcg */
> > +            p = "tcg";
> > +        }
> >      }  
> 
> Can't we instead use an explicit ,accel=probe or ,accel=auto?
> That would then obsolete the next patch.

How would you express the following with the accel=<pseudo-accel> approach?

-probe -machine s390-ccw,accel=kvm 

Using machine "none" as default with tcg as last accelerator initialized should not break
anything.

-M none

The return code of configure_accelerator() is ignored anyway.

Thanks,
Michael


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

* Re: [Qemu-devel] [PATCH v3 01/16] Introduce probe mode for machine type none
  2015-03-02 16:43     ` [Qemu-devel] " Michael Mueller
@ 2015-03-02 16:57       ` Andreas Färber
  2015-03-03 10:55         ` Michael Mueller
  0 siblings, 1 reply; 29+ messages in thread
From: Andreas Färber @ 2015-03-02 16:57 UTC (permalink / raw)
  To: Michael Mueller
  Cc: qemu-devel, Edgar E. Iglesias, Peter Crosthwaite, linux-s390,
	kvm, Gleb Natapov, Alexander Graf, Eduardo Habkost, linux-kernel,
	Christian Borntraeger, Jason J. Herne, Cornelia Huck,
	Paolo Bonzini, Alistair Francis, Richard Henderson

Am 02.03.2015 um 17:43 schrieb Michael Mueller:
> On Mon, 02 Mar 2015 14:57:21 +0100
> Andreas Färber <afaerber@suse.de> wrote:
> 
>>>  int configure_accelerator(MachineState *ms)
>>>  {
>>> -    const char *p;
>>> +    const char *p, *name;
>>>      char buf[10];
>>>      int ret;
>>>      bool accel_initialised = false;
>>>      bool init_failed = false;
>>>      AccelClass *acc = NULL;
>>> +    ObjectClass *oc;
>>> +    bool probe_mode = false;
>>>  
>>>      p = qemu_opt_get(qemu_get_machine_opts(), "accel");
>>>      if (p == NULL) {
>>> -        /* Use the default "accelerator", tcg */
>>> -        p = "tcg";
>>> +        oc = (ObjectClass *) MACHINE_GET_CLASS(current_machine);
>>> +        name = object_class_get_name(oc);
>>> +        probe_mode = !strcmp(name, "none" TYPE_MACHINE_SUFFIX);
>>> +        if (probe_mode) {
>>> +            /* Use these accelerators in probe mode, tcg should be last */
>>> +            p = probe_mode_accels;
>>> +        } else {
>>> +            /* Use the default "accelerator", tcg */
>>> +            p = "tcg";
>>> +        }
>>>      }  
>>
>> Can't we instead use an explicit ,accel=probe or ,accel=auto?
>> That would then obsolete the next patch.
> 
> How would you express the following with the accel=<pseudo-accel> approach?
> 
> -probe -machine s390-ccw,accel=kvm 
> 
> Using machine "none" as default with tcg as last accelerator initialized should not break
> anything.
> 
> -M none

Let me ask differently: What does -machine none or -M none have to do
with probing? It reads as if you are introducing two probe modes. Why do
you need both? If we have -probe, isn't that independent of which
machine we specify? Who is going to call either, with which respective goal?

I think that changing the semantics of an absent ,accel=foo parameter to
mean something else than its longtime default of tcg is a bad idea.

Have you testing qtest with it? Doesn't -qtest imply accel=qtest or is
that always passed explicitly?

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu,
Graham Norton; HRB 21284 (AG Nürnberg)

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

* Re: [PATCH v3 14/16] target-s390x: Extend QMP command query-cpu-definitions
  2015-03-02 12:44 ` [PATCH v3 14/16] target-s390x: Extend QMP command query-cpu-definitions Michael Mueller
@ 2015-03-02 19:11   ` Eduardo Habkost
  2015-03-04  9:00     ` [Qemu-devel] " Michael Mueller
  0 siblings, 1 reply; 29+ messages in thread
From: Eduardo Habkost @ 2015-03-02 19:11 UTC (permalink / raw)
  To: Michael Mueller
  Cc: qemu-devel, kvm, linux-s390, linux-kernel, Gleb Natapov,
	Alexander Graf, Christian Borntraeger, Jason J. Herne,
	Cornelia Huck, Paolo Bonzini, Andreas Faerber, Richard Henderson

On Mon, Mar 02, 2015 at 01:44:06PM +0100, Michael Mueller wrote:
> This patch implements the QMP command 'query-cpu-definitions' in the S390
> context. The command returns a list of cpu model names in the current host
> context. A consumer may successfully request each listed cpu model as long
> for a given accelerator this model is runnable.
> 
> The QMP type AccelCpuModelInfo is introduced and the type CpuDefinitionInfo
> is extended by the optional field 'accelerators'. It contains a list of named
> accelerators and some indication whether the associated cpu model is runnable
> or the default cpu model. The default cpu model is used if either no specific
> cpu model is requested during QEMU startup or if the cpu model with name
> 'host' is requested.
> 
> request:
>   {"execute": "query-cpu-definitions"}
> 
> answer:
>   {"return":
>     [{"name":"2964-ga1","accelerators":[{"name":"kvm","runnable":false,"default":false}]},
>      {"name":"2828-ga1","accelerators":[{"name":"kvm","runnable":false,"default":false}]},
>      {"name":"2827-ga2","accelerators":[{"name":"kvm","runnable":true,"default":true}]},
>      {"name":"2827-ga1","accelerators":[{"name":"kvm","runnable":true,"default":false}]},
>      {"name":"2818-ga1","accelerators":[{"name":"kvm","runnable":true,"default":false}]},
>      ...
>      {"name":"2064-ga1","accelerators":[{"runnable":true,"name":"kvm","default":false}]}
>     ]
>    }

On x86, being runnable or not is something that depends on the
machine-type. I expect that to happen in other machines as soon as they
start implementing backwards compatiblity.

I see two options to implement that: 1) adding a "machine-type" argument
to query-cpu-definitions; 2) returning a machine-type-based dictionary
on the "runnable" property. The former sounds better to me as it won't
require enumerating all machine-types every time.

In that case, why we do need to enumerate all accelerators on every
query, either? We could have both "machine-type" and "accel" arguments
to query-cpu-definitions, so callers will just ask for the
acceleratores/machine-types they are interested into.

e.g.:

request:
  {"execute": "query-cpu-definitions",
   "arguments": {"machine":"s390-virtio", "accel":"kvm"}}

answer:
  {"return":
    [{"name":"2964-ga1","runnable":true},
     {"name":"2828-ga1","runnable":false}
     ...
    ]
  }

We can also extend this to other variables, such as extra CPU flags that
could make the CPU runnable or not. e.g.: want to know if "-machine
foo,accel=bar -cpu xxx,+yyy,-zzz" is runnable? Send this request:
  {"execute": "query-cpu-definitions",
   "arguments": {"machine":"s390-virtio", "accel":"kvm", "cpu":"xxx,+yyy,-zzz"}}
and get this response:
  {"return": [{"name":"xxx","runnable":false}]}
or maybe being more explicit in the response about the extra CPU flags:
  {"return": [{"name":"xxx,+yyy,-zzz","runnable":false}]}


>   {"execute": "query-cpu-definitions"}
> 
> answer:
>   {"return":
>     [{"name":"2964-ga1","accelerators":[{"name":"kvm","runnable":false,"default":false}]},
>      {"name":"2828-ga1","accelerators":[{"name":"kvm","runnable":false,"default":false}]},
>      {"name":"2827-ga2","accelerators":[{"name":"kvm","runnable":true,"default":true}]},
>      {"name":"2827-ga1","accelerators":[{"name":"kvm","runnable":true,"default":false}]},
>      {"name":"2818-ga1","accelerators":[{"name":"kvm","runnable":true,"default":false}]},
> 
> Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
> [...]

-- 
Eduardo

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

* Re: [PATCH v3 01/16] Introduce probe mode for machine type none
  2015-03-02 12:43 ` [PATCH v3 01/16] Introduce probe mode for machine type none Michael Mueller
  2015-03-02 13:57   ` Andreas Färber
@ 2015-03-02 19:17   ` Eduardo Habkost
  2015-03-03 10:23     ` [Qemu-devel] " Michael Mueller
  1 sibling, 1 reply; 29+ messages in thread
From: Eduardo Habkost @ 2015-03-02 19:17 UTC (permalink / raw)
  To: Michael Mueller
  Cc: qemu-devel, kvm, linux-s390, linux-kernel, Gleb Natapov,
	Alexander Graf, Christian Borntraeger, Jason J. Herne,
	Cornelia Huck, Paolo Bonzini, Andreas Faerber, Richard Henderson

On Mon, Mar 02, 2015 at 01:43:53PM +0100, Michael Mueller wrote:
> QEMU now switches into "probe mode" when the selected machine is "none" and no
> specific accelerator(s) has been requested (i.e.: "-machine none").
> 
> In probe mode a by "<ARCH>_CONFIG" defines predefined list of accelerators run
> their init() methods.
> 
> Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
> ---
[...]
>  int configure_accelerator(MachineState *ms)
>  {
> -    const char *p;
> +    const char *p, *name;
>      char buf[10];
>      int ret;
>      bool accel_initialised = false;
>      bool init_failed = false;
>      AccelClass *acc = NULL;
> +    ObjectClass *oc;
> +    bool probe_mode = false;
>  
>      p = qemu_opt_get(qemu_get_machine_opts(), "accel");
>      if (p == NULL) {
> -        /* Use the default "accelerator", tcg */
> -        p = "tcg";
> +        oc = (ObjectClass *) MACHINE_GET_CLASS(current_machine);
> +        name = object_class_get_name(oc);
> +        probe_mode = !strcmp(name, "none" TYPE_MACHINE_SUFFIX);
> +        if (probe_mode) {
> +            /* Use these accelerators in probe mode, tcg should be last */
> +            p = probe_mode_accels;

I don't fully understand the purpose of this patch yet (I will discuss
it in a reply to the cover letter). But if you really want -machine none
to trigger different behavior, why you didn't add a probe_mode field
to MachineClass, so you can set it in the mahine_none class code?

> +        } else {
> +            /* Use the default "accelerator", tcg */
> +            p = "tcg";
> +        }
>      }
[...]

-- 
Eduardo

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

* Re: [PATCH v3 00/16] s390x cpu model implementation
  2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
                   ` (15 preceding siblings ...)
  2015-03-02 12:44 ` [PATCH v3 16/16] target-s390x: Enable cpu model usage Michael Mueller
@ 2015-03-02 19:25 ` Eduardo Habkost
  16 siblings, 0 replies; 29+ messages in thread
From: Eduardo Habkost @ 2015-03-02 19:25 UTC (permalink / raw)
  To: Michael Mueller
  Cc: qemu-devel, kvm, linux-s390, linux-kernel, Gleb Natapov,
	Alexander Graf, Christian Borntraeger, Jason J. Herne,
	Cornelia Huck, Paolo Bonzini, Andreas Faerber, Richard Henderson

On Mon, Mar 02, 2015 at 01:43:52PM +0100, Michael Mueller wrote:
[...]
> 
> What's currently a little bit unclear to me is how to best initialize the
> various accelerators for machine 'none'. I played around with different
> options and finally came up with the following sugguestion:
> 
> Introduce a QEMU "probe mode" that gets entered in case the current machine
> is "none" and no specific accelerator is requested on the cmd line. When
> in that mode, loop trough a list of acellerators in configure_accelerator
> and invoke all their init methods once. The last accelerator to init shall
> be tcg.
> 
> In cpu model context that allows to initialize the S390 CPU classes for
> each single accelertor which supports it. Whence the callback for
> qemu-cpu-definitions allows to populate its answer string according to the
> above sketched extended CpuDefinitionInfo type for multiplaccelerators. 

To initialize the various accelereators, you should just be able to
create temporary QOM accelerators on the fly, when you need them. That
was the whole point of the conversion of accelerators to QOM.

So we shouldn't need any special probe mode as long as: 1) all
accelerators don't do anything destructive (that affects global QEMU
state) in their instance_init functions; 2) the probing code simply
creates the accel objects when needed, query for information, and then
destroy them.

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH v3 01/16] Introduce probe mode for machine type none
  2015-03-02 19:17   ` Eduardo Habkost
@ 2015-03-03 10:23     ` Michael Mueller
  0 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-03 10:23 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: linux-s390, kvm, Gleb Natapov, linux-kernel, Alexander Graf,
	qemu-devel, Christian Borntraeger, Jason J. Herne, Cornelia Huck,
	Paolo Bonzini, Andreas Faerber, Richard Henderson

On Mon, 2 Mar 2015 16:17:33 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> > +        if (probe_mode) {
> > +            /* Use these accelerators in probe mode, tcg should be last */
> > +            p = probe_mode_accels;  
> 
> I don't fully understand the purpose of this patch yet (I will discuss
> it in a reply to the cover letter). But if you really want -machine none
> to trigger different behavior, why you didn't add a probe_mode field
> to MachineClass, so you can set it in the mahine_none class code?

I initially had this machine attribute but, when I remember correctly, but wasn't able to
communicate it down into the target code. But anyhow, the "mode" is eventually obsolete in light
of the temporarily constructed accelerators.. I will further comment on this as reply to your
comment on the cover letter to keep it in place.

Michael


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

* Re: [Qemu-devel] [PATCH v3 01/16] Introduce probe mode for machine type none
  2015-03-02 16:57       ` Andreas Färber
@ 2015-03-03 10:55         ` Michael Mueller
  2015-03-04 19:19           ` Eduardo Habkost
  0 siblings, 1 reply; 29+ messages in thread
From: Michael Mueller @ 2015-03-03 10:55 UTC (permalink / raw)
  To: Andreas Färber
  Cc: qemu-devel, Edgar E. Iglesias, Peter Crosthwaite, linux-s390,
	kvm, Gleb Natapov, Alexander Graf, Eduardo Habkost, linux-kernel,
	Christian Borntraeger, Jason J. Herne, Cornelia Huck,
	Paolo Bonzini, Alistair Francis, Richard Henderson

On Mon, 02 Mar 2015 17:57:01 +0100
Andreas Färber <afaerber@suse.de> wrote:

> Am 02.03.2015 um 17:43 schrieb Michael Mueller:
> > On Mon, 02 Mar 2015 14:57:21 +0100
> > Andreas Färber <afaerber@suse.de> wrote:
> > 
> >>>  int configure_accelerator(MachineState *ms)
> >>>  {
> >>> -    const char *p;
> >>> +    const char *p, *name;
> >>>      char buf[10];
> >>>      int ret;
> >>>      bool accel_initialised = false;
> >>>      bool init_failed = false;
> >>>      AccelClass *acc = NULL;
> >>> +    ObjectClass *oc;
> >>> +    bool probe_mode = false;
> >>>  
> >>>      p = qemu_opt_get(qemu_get_machine_opts(), "accel");
> >>>      if (p == NULL) {
> >>> -        /* Use the default "accelerator", tcg */
> >>> -        p = "tcg";
> >>> +        oc = (ObjectClass *) MACHINE_GET_CLASS(current_machine);
> >>> +        name = object_class_get_name(oc);
> >>> +        probe_mode = !strcmp(name, "none" TYPE_MACHINE_SUFFIX);
> >>> +        if (probe_mode) {
> >>> +            /* Use these accelerators in probe mode, tcg should be last */
> >>> +            p = probe_mode_accels;
> >>> +        } else {
> >>> +            /* Use the default "accelerator", tcg */
> >>> +            p = "tcg";
> >>> +        }
> >>>      }  
> >>
> >> Can't we instead use an explicit ,accel=probe or ,accel=auto?
> >> That would then obsolete the next patch.
> > 
> > How would you express the following with the accel=<pseudo-accel> approach?
> > 
> > -probe -machine s390-ccw,accel=kvm 
> > 
> > Using machine "none" as default with tcg as last accelerator initialized should not break
> > anything.
> > 
> > -M none
> 
> Let me ask differently: What does -machine none or -M none have to do
> with probing? It reads as if you are introducing two probe modes. Why do

The machine none? nothing directly, I guess. What are real world use cases for that
machine type?

> you need both? If we have -probe, isn't that independent of which

It is just two different means to switch on the same mode.

> machine we specify? Who is going to call either, with which respective goal?

-probe itself would be sufficient but I currently do not want to enforce the use of
a new parameter. Best would be not to have that mode at all if possible. 

The intended use case is driven by management interfaces that need to draw decisions
on, in this particular case runnable cpu models, with information originated by qemu.

Let me walk through Eduardo's suggestion first and crosscheck it with my requirements
before we enter in a maybe afterwards obsolete discussion.

Thanks,
Michael

> 
> I think that changing the semantics of an absent ,accel=foo parameter to
> mean something else than its longtime default of tcg is a bad idea.
>
> Have you testing qtest with it? Doesn't -qtest imply accel=qtest or is
> that always passed explicitly?
> 
> Regards,
> Andreas
> 


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

* Re: [Qemu-devel] [PATCH v3 14/16] target-s390x: Extend QMP command query-cpu-definitions
  2015-03-02 19:11   ` Eduardo Habkost
@ 2015-03-04  9:00     ` Michael Mueller
  0 siblings, 0 replies; 29+ messages in thread
From: Michael Mueller @ 2015-03-04  9:00 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: linux-s390, kvm, Gleb Natapov, linux-kernel, Alexander Graf,
	qemu-devel, Christian Borntraeger, Jason J. Herne, Cornelia Huck,
	Paolo Bonzini, Andreas Faerber, Richard Henderson

On Mon, 2 Mar 2015 16:11:00 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> On Mon, Mar 02, 2015 at 01:44:06PM +0100, Michael Mueller wrote:
> > This patch implements the QMP command 'query-cpu-definitions' in the S390
> > context. The command returns a list of cpu model names in the current host
> > context. A consumer may successfully request each listed cpu model as long
> > for a given accelerator this model is runnable.
> > 
> > The QMP type AccelCpuModelInfo is introduced and the type CpuDefinitionInfo
> > is extended by the optional field 'accelerators'. It contains a list of named
> > accelerators and some indication whether the associated cpu model is runnable
> > or the default cpu model. The default cpu model is used if either no specific
> > cpu model is requested during QEMU startup or if the cpu model with name
> > 'host' is requested.
> > 
> > request:
> >   {"execute": "query-cpu-definitions"}
> > 
> > answer:
> >   {"return":
> >     [{"name":"2964-ga1","accelerators":[{"name":"kvm","runnable":false,"default":false}]},
> >      {"name":"2828-ga1","accelerators":[{"name":"kvm","runnable":false,"default":false}]},
> >      {"name":"2827-ga2","accelerators":[{"name":"kvm","runnable":true,"default":true}]},
> >      {"name":"2827-ga1","accelerators":[{"name":"kvm","runnable":true,"default":false}]},
> >      {"name":"2818-ga1","accelerators":[{"name":"kvm","runnable":true,"default":false}]},
> >      ...
> >      {"name":"2064-ga1","accelerators":[{"runnable":true,"name":"kvm","default":false}]}
> >     ]
> >    }
> 
> On x86, being runnable or not is something that depends on the
> machine-type. I expect that to happen in other machines as soon as they
> start implementing backwards compatiblity.
> 
> I see two options to implement that: 1) adding a "machine-type" argument
> to query-cpu-definitions; 2) returning a machine-type-based dictionary
> on the "runnable" property. The former sounds better to me as it won't
> require enumerating all machine-types every time.
> 
> In that case, why we do need to enumerate all accelerators on every
> query, either? We could have both "machine-type" and "accel" arguments
> to query-cpu-definitions, so callers will just ask for the
> acceleratores/machine-types they are interested into.
> 
> e.g.:
> 
> request:
>   {"execute": "query-cpu-definitions",
>    "arguments": {"machine":"s390-virtio", "accel":"kvm"}}
> 
> answer:
>   {"return":
>     [{"name":"2964-ga1","runnable":true},
>      {"name":"2828-ga1","runnable":false}
>      ...
>     ]
>   }

I had some discussion with out libvirt people on that. I will compile a patch implementing this
to see how it fits..

> 
> We can also extend this to other variables, such as extra CPU flags that
> could make the CPU runnable or not. e.g.: want to know if "-machine
> foo,accel=bar -cpu xxx,+yyy,-zzz" is runnable? Send this request:
>   {"execute": "query-cpu-definitions",
>    "arguments": {"machine":"s390-virtio", "accel":"kvm", "cpu":"xxx,+yyy,-zzz"}}
> and get this response:
>   {"return": [{"name":"xxx","runnable":false}]}
> or maybe being more explicit in the response about the extra CPU flags:
>   {"return": [{"name":"xxx,+yyy,-zzz","runnable":false}]}
> 
> 
> >   {"execute": "query-cpu-definitions"}
> > 
> > answer:
> >   {"return":
> >     [{"name":"2964-ga1","accelerators":[{"name":"kvm","runnable":false,"default":false}]},
> >      {"name":"2828-ga1","accelerators":[{"name":"kvm","runnable":false,"default":false}]},
> >      {"name":"2827-ga2","accelerators":[{"name":"kvm","runnable":true,"default":true}]},
> >      {"name":"2827-ga1","accelerators":[{"name":"kvm","runnable":true,"default":false}]},
> >      {"name":"2818-ga1","accelerators":[{"name":"kvm","runnable":true,"default":false}]},
> > 
> > Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
> > [...]
> 


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

* Re: [Qemu-devel] [PATCH v3 01/16] Introduce probe mode for machine type none
  2015-03-03 10:55         ` Michael Mueller
@ 2015-03-04 19:19           ` Eduardo Habkost
  2015-03-05 14:56             ` Michael Mueller
  0 siblings, 1 reply; 29+ messages in thread
From: Eduardo Habkost @ 2015-03-04 19:19 UTC (permalink / raw)
  To: Michael Mueller
  Cc: Andreas Färber, linux-s390, Peter Crosthwaite, kvm,
	Gleb Natapov, linux-kernel, qemu-devel, Alexander Graf,
	Christian Borntraeger, Jason J. Herne, Paolo Bonzini,
	Cornelia Huck, Edgar E. Iglesias, Alistair Francis,
	Richard Henderson

On Tue, Mar 03, 2015 at 11:55:24AM +0100, Michael Mueller wrote:
> On Mon, 02 Mar 2015 17:57:01 +0100
> Andreas Färber <afaerber@suse.de> wrote:
> 
> > Am 02.03.2015 um 17:43 schrieb Michael Mueller:
> > > On Mon, 02 Mar 2015 14:57:21 +0100
> > > Andreas Färber <afaerber@suse.de> wrote:
> > > 
> > >>>  int configure_accelerator(MachineState *ms)
> > >>>  {
> > >>> -    const char *p;
> > >>> +    const char *p, *name;
> > >>>      char buf[10];
> > >>>      int ret;
> > >>>      bool accel_initialised = false;
> > >>>      bool init_failed = false;
> > >>>      AccelClass *acc = NULL;
> > >>> +    ObjectClass *oc;
> > >>> +    bool probe_mode = false;
> > >>>  
> > >>>      p = qemu_opt_get(qemu_get_machine_opts(), "accel");
> > >>>      if (p == NULL) {
> > >>> -        /* Use the default "accelerator", tcg */
> > >>> -        p = "tcg";
> > >>> +        oc = (ObjectClass *) MACHINE_GET_CLASS(current_machine);
> > >>> +        name = object_class_get_name(oc);
> > >>> +        probe_mode = !strcmp(name, "none" TYPE_MACHINE_SUFFIX);
> > >>> +        if (probe_mode) {
> > >>> +            /* Use these accelerators in probe mode, tcg should be last */
> > >>> +            p = probe_mode_accels;
> > >>> +        } else {
> > >>> +            /* Use the default "accelerator", tcg */
> > >>> +            p = "tcg";
> > >>> +        }
> > >>>      }  
> > >>
> > >> Can't we instead use an explicit ,accel=probe or ,accel=auto?
> > >> That would then obsolete the next patch.
> > > 
> > > How would you express the following with the accel=<pseudo-accel> approach?
> > > 
> > > -probe -machine s390-ccw,accel=kvm 
> > > 
> > > Using machine "none" as default with tcg as last accelerator initialized should not break
> > > anything.
> > > 
> > > -M none
> > 
> > Let me ask differently: What does -machine none or -M none have to do
> > with probing? It reads as if you are introducing two probe modes. Why do
> 
> The machine none? nothing directly, I guess. What are real world use cases for that
> machine type?
> 
> > you need both? If we have -probe, isn't that independent of which
> 
> It is just two different means to switch on the same mode.
> 
> > machine we specify? Who is going to call either, with which respective goal?
> 
> -probe itself would be sufficient but I currently do not want to enforce the use of
> a new parameter. Best would be not to have that mode at all if possible. 
> 
> The intended use case is driven by management interfaces that need to draw decisions
> on, in this particular case runnable cpu models, with information originated by qemu.
> 
> Let me walk through Eduardo's suggestion first and crosscheck it with my requirements
> before we enter in a maybe afterwards obsolete discussion.

I have been working on some changes to implement x86 CPU probing code
that creates accel objects on the fly, that may be useful. See:
  https://github.com/ehabkost/qemu-hacks/tree/work/user-accel-init

Especially the commit:
  kvm: Move /dev/kvm opening/closing to open/close methods

The next steps I plan are:
 * Create AccelState object on TCG too, and somehow pass it as argument
   to cpu_x86_init()
 * Change all kvm_enabled() occurrences on target-i386/cpu.c to use
   the provided accel object (including
   x86_cpu_get_supported_feature_word() and x86_cpu_filter_features())
 * Use the new
   x86_cpu_get_supported_feature_word()/x86_cpu_filter_features() code
   to implement a is_runnable(X86CPUClass*, AccelState*) check
 * Use the new is_runnable() check to extend query-cpu-definitions for x86 too
 * Add -cpu string and machine-type arguments to the is_runnable() check

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH v3 01/16] Introduce probe mode for machine type none
  2015-03-04 19:19           ` Eduardo Habkost
@ 2015-03-05 14:56             ` Michael Mueller
  2015-03-05 15:07               ` Eduardo Habkost
  0 siblings, 1 reply; 29+ messages in thread
From: Michael Mueller @ 2015-03-05 14:56 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Andreas Färber, linux-s390, Peter Crosthwaite, kvm,
	Gleb Natapov, linux-kernel, qemu-devel, Alexander Graf,
	Christian Borntraeger, Jason J. Herne, Paolo Bonzini,
	Cornelia Huck, Edgar E. Iglesias, Alistair Francis,
	Richard Henderson

On Wed, 4 Mar 2015 16:19:25 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> On Tue, Mar 03, 2015 at 11:55:24AM +0100, Michael Mueller wrote:
> > On Mon, 02 Mar 2015 17:57:01 +0100
> > Andreas Färber <afaerber@suse.de> wrote:
> > 
> > > Am 02.03.2015 um 17:43 schrieb Michael Mueller:
> > > > On Mon, 02 Mar 2015 14:57:21 +0100
> > > > Andreas Färber <afaerber@suse.de> wrote:
> > > > 
> > > >>>  int configure_accelerator(MachineState *ms)
> > > >>>  {
> > > >>> -    const char *p;
> > > >>> +    const char *p, *name;
> > > >>>      char buf[10];
> > > >>>      int ret;
> > > >>>      bool accel_initialised = false;
> > > >>>      bool init_failed = false;
> > > >>>      AccelClass *acc = NULL;
> > > >>> +    ObjectClass *oc;
> > > >>> +    bool probe_mode = false;
> > > >>>  
> > > >>>      p = qemu_opt_get(qemu_get_machine_opts(), "accel");
> > > >>>      if (p == NULL) {
> > > >>> -        /* Use the default "accelerator", tcg */
> > > >>> -        p = "tcg";
> > > >>> +        oc = (ObjectClass *) MACHINE_GET_CLASS(current_machine);
> > > >>> +        name = object_class_get_name(oc);
> > > >>> +        probe_mode = !strcmp(name, "none" TYPE_MACHINE_SUFFIX);
> > > >>> +        if (probe_mode) {
> > > >>> +            /* Use these accelerators in probe mode, tcg should be last */
> > > >>> +            p = probe_mode_accels;
> > > >>> +        } else {
> > > >>> +            /* Use the default "accelerator", tcg */
> > > >>> +            p = "tcg";
> > > >>> +        }
> > > >>>      }  
> > > >>
> > > >> Can't we instead use an explicit ,accel=probe or ,accel=auto?
> > > >> That would then obsolete the next patch.
> > > > 
> > > > How would you express the following with the accel=<pseudo-accel> approach?
> > > > 
> > > > -probe -machine s390-ccw,accel=kvm 
> > > > 
> > > > Using machine "none" as default with tcg as last accelerator initialized should not break
> > > > anything.
> > > > 
> > > > -M none
> > > 
> > > Let me ask differently: What does -machine none or -M none have to do
> > > with probing? It reads as if you are introducing two probe modes. Why do
> > 
> > The machine none? nothing directly, I guess. What are real world use cases for that
> > machine type?
> > 
> > > you need both? If we have -probe, isn't that independent of which
> > 
> > It is just two different means to switch on the same mode.
> > 
> > > machine we specify? Who is going to call either, with which respective goal?
> > 
> > -probe itself would be sufficient but I currently do not want to enforce the use of
> > a new parameter. Best would be not to have that mode at all if possible. 
> > 
> > The intended use case is driven by management interfaces that need to draw decisions
> > on, in this particular case runnable cpu models, with information originated by qemu.
> > 
> > Let me walk through Eduardo's suggestion first and crosscheck it with my requirements
> > before we enter in a maybe afterwards obsolete discussion.
> 
> I have been working on some changes to implement x86 CPU probing code
> that creates accel objects on the fly, that may be useful. See:
>   https://github.com/ehabkost/qemu-hacks/tree/work/user-accel-init
> 
> Especially the commit:
>   kvm: Move /dev/kvm opening/closing to open/close methods
> 

So the idea is to use kvm_open/close() in the query-cpu-definitions callback on the fly without
to disturb the KVM-side data structures for the machine probe instead of going through kvm_init()
during accelerator configuration?


> The next steps I plan are:
>  * Create AccelState object on TCG too, and somehow pass it as argument
>    to cpu_x86_init()
>  * Change all kvm_enabled() occurrences on target-i386/cpu.c to use
>    the provided accel object (including
>    x86_cpu_get_supported_feature_word() and x86_cpu_filter_features())
>  * Use the new
>    x86_cpu_get_supported_feature_word()/x86_cpu_filter_features() code
>    to implement a is_runnable(X86CPUClass*, AccelState*) check
>  * Use the new is_runnable() check to extend query-cpu-definitions for x86 too
>  * Add -cpu string and machine-type arguments to the is_runnable() check
> 


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

* Re: [Qemu-devel] [PATCH v3 01/16] Introduce probe mode for machine type none
  2015-03-05 14:56             ` Michael Mueller
@ 2015-03-05 15:07               ` Eduardo Habkost
  0 siblings, 0 replies; 29+ messages in thread
From: Eduardo Habkost @ 2015-03-05 15:07 UTC (permalink / raw)
  To: Michael Mueller
  Cc: Andreas Färber, linux-s390, Peter Crosthwaite, kvm,
	Gleb Natapov, linux-kernel, qemu-devel, Alexander Graf,
	Christian Borntraeger, Jason J. Herne, Paolo Bonzini,
	Cornelia Huck, Edgar E. Iglesias, Alistair Francis,
	Richard Henderson

On Thu, Mar 05, 2015 at 03:56:03PM +0100, Michael Mueller wrote:
> On Wed, 4 Mar 2015 16:19:25 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
> 
> > On Tue, Mar 03, 2015 at 11:55:24AM +0100, Michael Mueller wrote:
> > > On Mon, 02 Mar 2015 17:57:01 +0100
> > > Andreas Färber <afaerber@suse.de> wrote:
> > > 
> > > > Am 02.03.2015 um 17:43 schrieb Michael Mueller:
> > > > > On Mon, 02 Mar 2015 14:57:21 +0100
> > > > > Andreas Färber <afaerber@suse.de> wrote:
> > > > > 
> > > > >>>  int configure_accelerator(MachineState *ms)
> > > > >>>  {
> > > > >>> -    const char *p;
> > > > >>> +    const char *p, *name;
> > > > >>>      char buf[10];
> > > > >>>      int ret;
> > > > >>>      bool accel_initialised = false;
> > > > >>>      bool init_failed = false;
> > > > >>>      AccelClass *acc = NULL;
> > > > >>> +    ObjectClass *oc;
> > > > >>> +    bool probe_mode = false;
> > > > >>>  
> > > > >>>      p = qemu_opt_get(qemu_get_machine_opts(), "accel");
> > > > >>>      if (p == NULL) {
> > > > >>> -        /* Use the default "accelerator", tcg */
> > > > >>> -        p = "tcg";
> > > > >>> +        oc = (ObjectClass *) MACHINE_GET_CLASS(current_machine);
> > > > >>> +        name = object_class_get_name(oc);
> > > > >>> +        probe_mode = !strcmp(name, "none" TYPE_MACHINE_SUFFIX);
> > > > >>> +        if (probe_mode) {
> > > > >>> +            /* Use these accelerators in probe mode, tcg should be last */
> > > > >>> +            p = probe_mode_accels;
> > > > >>> +        } else {
> > > > >>> +            /* Use the default "accelerator", tcg */
> > > > >>> +            p = "tcg";
> > > > >>> +        }
> > > > >>>      }  
> > > > >>
> > > > >> Can't we instead use an explicit ,accel=probe or ,accel=auto?
> > > > >> That would then obsolete the next patch.
> > > > > 
> > > > > How would you express the following with the accel=<pseudo-accel> approach?
> > > > > 
> > > > > -probe -machine s390-ccw,accel=kvm 
> > > > > 
> > > > > Using machine "none" as default with tcg as last accelerator initialized should not break
> > > > > anything.
> > > > > 
> > > > > -M none
> > > > 
> > > > Let me ask differently: What does -machine none or -M none have to do
> > > > with probing? It reads as if you are introducing two probe modes. Why do
> > > 
> > > The machine none? nothing directly, I guess. What are real world use cases for that
> > > machine type?
> > > 
> > > > you need both? If we have -probe, isn't that independent of which
> > > 
> > > It is just two different means to switch on the same mode.
> > > 
> > > > machine we specify? Who is going to call either, with which respective goal?
> > > 
> > > -probe itself would be sufficient but I currently do not want to enforce the use of
> > > a new parameter. Best would be not to have that mode at all if possible. 
> > > 
> > > The intended use case is driven by management interfaces that need to draw decisions
> > > on, in this particular case runnable cpu models, with information originated by qemu.
> > > 
> > > Let me walk through Eduardo's suggestion first and crosscheck it with my requirements
> > > before we enter in a maybe afterwards obsolete discussion.
> > 
> > I have been working on some changes to implement x86 CPU probing code
> > that creates accel objects on the fly, that may be useful. See:
> >   https://github.com/ehabkost/qemu-hacks/tree/work/user-accel-init
> > 
> > Especially the commit:
> >   kvm: Move /dev/kvm opening/closing to open/close methods
> > 
> 
> So the idea is to use kvm_open/close() in the query-cpu-definitions callback on the fly without
> to disturb the KVM-side data structures for the machine probe instead of going through kvm_init()
> during accelerator configuration?

If by KVM-side data structures you mean globals like kvm_state, yes. The
idea is to not disturb any global state during probe (including
kvm_state). In the branch above, the open/close methods will affect only
the local AccelState object. Code that will affect MachineState or other
global state will be in the machine_init method.

> 
> 
> > The next steps I plan are: * Create AccelState object on TCG too,
> >  and somehow pass it as argument to cpu_x86_init() * Change all
> >  kvm_enabled() occurrences on target-i386/cpu.c to use the provided
> >  accel object (including x86_cpu_get_supported_feature_word() and
> >  x86_cpu_filter_features())
> >  * Use the new
> >    x86_cpu_get_supported_feature_word()/x86_cpu_filter_features()
> >    code to implement a is_runnable(X86CPUClass*, AccelState*) check
> >    * Use the new is_runnable() check to extend query-cpu-definitions
> >    for x86 too * Add -cpu string and machine-type arguments to the
> >    is_runnable() check
> > 
> 

-- 
Eduardo

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

end of thread, other threads:[~2015-03-05 15:07 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-02 12:43 [PATCH v3 00/16] s390x cpu model implementation Michael Mueller
2015-03-02 12:43 ` [PATCH v3 01/16] Introduce probe mode for machine type none Michael Mueller
2015-03-02 13:57   ` Andreas Färber
2015-03-02 16:43     ` [Qemu-devel] " Michael Mueller
2015-03-02 16:57       ` Andreas Färber
2015-03-03 10:55         ` Michael Mueller
2015-03-04 19:19           ` Eduardo Habkost
2015-03-05 14:56             ` Michael Mueller
2015-03-05 15:07               ` Eduardo Habkost
2015-03-02 19:17   ` Eduardo Habkost
2015-03-03 10:23     ` [Qemu-devel] " Michael Mueller
2015-03-02 12:43 ` [PATCH v3 02/16] Introduce option --probe to switch into probe mode Michael Mueller
2015-03-02 12:43 ` [PATCH v3 03/16] Introduce stub routine cpu_desc_avail Michael Mueller
2015-03-02 12:43 ` [PATCH v3 04/16] target-s390x: Introduce cpu facilities Michael Mueller
2015-03-02 12:43 ` [PATCH v3 05/16] target-s390x: Generate facility defines per cpu model Michael Mueller
2015-03-02 12:43 ` [PATCH v3 06/16] target-s390x: Introduce cpu models Michael Mueller
2015-03-02 12:43 ` [PATCH v3 07/16] target-s390x: Define cpu model specific facility lists Michael Mueller
2015-03-02 12:44 ` [PATCH v3 08/16] target-s390x: Add cpu model alias definition routines Michael Mueller
2015-03-02 12:44 ` [PATCH v3 09/16] target-s390x: Update linux-headers/asm-s390/kvm.h Michael Mueller
2015-03-02 12:44 ` [PATCH v3 10/16] target-s390x: Add KVM VM attribute interface for cpu models Michael Mueller
2015-03-02 12:44 ` [PATCH v3 11/16] target-s390x: Add cpu class initialization routines Michael Mueller
2015-03-02 12:44 ` [PATCH v3 12/16] target-s390x: Prepare accelerator during cpu object realization Michael Mueller
2015-03-02 12:44 ` [PATCH v3 13/16] target-s390x: New QMP command query-cpu-model Michael Mueller
2015-03-02 12:44 ` [PATCH v3 14/16] target-s390x: Extend QMP command query-cpu-definitions Michael Mueller
2015-03-02 19:11   ` Eduardo Habkost
2015-03-04  9:00     ` [Qemu-devel] " Michael Mueller
2015-03-02 12:44 ` [PATCH v3 15/16] target-s390x: Introduce facility test routine Michael Mueller
2015-03-02 12:44 ` [PATCH v3 16/16] target-s390x: Enable cpu model usage Michael Mueller
2015-03-02 19:25 ` [PATCH v3 00/16] s390x cpu model implementation Eduardo Habkost

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).