2015-02-17 14:25:05

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 00/15] QEMU: s390: cpu model implementation

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.

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 (15):
cpu-model: Introduce probe mode for machine none
cpu-model: Introduce option --probe to switch into probe mode
cpu-model: Introduce stub routine cpu_desc_avail
cpu-model/s390: Introduce S390 CPU models
cpu-model/s390: Introduce S390 CPU facilities
cpu-model/s390: Define cpu model specific facility lists
cpu-model/s390: Add cpu model alias definition routines
cpu-model/s390: Update linux-headers/asm-s390/kvm.h
cpu-model/s390: Add KVM VM attribute interface routines
cpu-model/s390: Add cpu class initialization routines
cpu-model/s390: Add QMP command query-cpu-model
cpu-model/s390: Extend QMP command query-cpu-definitions
cpu-model/s390: Add processor property routines
cpu-model/s390: Add cpu model selection routine
cpu-model/s390: Enable S390 cpu model

accel.c | 36 +-
hw/s390x/s390-virtio.c | 6 +
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 | 55 ++-
qemu-options.hx | 8 +
qmp-commands.hx | 6 +
qmp.c | 5 +
stubs/Makefile.objs | 2 +
stubs/arch-query-cpu-mod.c | 9 +
stubs/cpu-desc-avail.c | 6 +
target-s390x/Makefile.objs | 1 +
target-s390x/cpu-facilities.h | 76 +++++
target-s390x/cpu-models.c | 754 ++++++++++++++++++++++++++++++++++++++++++
target-s390x/cpu-models.h | 339 +++++++++++++++++++
target-s390x/cpu-qom.h | 22 ++
target-s390x/cpu.c | 154 ++++++++-
target-s390x/helper.c | 3 +-
target-s390x/kvm.c | 104 ++++++
trace-events | 6 +
vl.c | 9 +-
26 files changed, 1621 insertions(+), 19 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

--
1.8.3.1


2015-02-17 14:25:07

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 01/15] cpu-model: Introduce probe mode for machine none

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 <[email protected]>
---
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

2015-02-17 14:26:58

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 02/15] cpu-model: Introduce option --probe to switch into probe mode

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 accellerators that support probing is used.

Signed-off-by: Michael Mueller <[email protected]>
---
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 8c8f142..0fabc0b 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;
@@ -3148,6 +3149,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;
@@ -4027,7 +4032,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

2015-02-17 14:30:24

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 03/15] cpu-model: Introduce stub routine cpu_desc_avail

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 <[email protected]>
Reviewed-by: Thomas Huth <[email protected]>
---
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 0fabc0b..130fb1e 100644
--- a/vl.c
+++ b/vl.c
@@ -3819,7 +3819,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

2015-02-17 14:26:20

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models

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 <[email protected]>
Reviewed-by: Thomas Huth <[email protected]>
---
qapi-schema.json | 11 +++++++
target-s390x/Makefile.objs | 1 +
target-s390x/cpu-models.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++
target-s390x/cpu-models.h | 71 +++++++++++++++++++++++++++++++++++++++++
target-s390x/cpu-qom.h | 22 +++++++++++++
target-s390x/cpu.c | 2 ++
6 files changed, 186 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..4d237c8 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.0
+##
+{ 'enum': 'AccelId',
+ 'data': ['qtest', 'tcg', 'kvm', 'xen' ] }
+
##
# @CpuDefinitionInfo:
#
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index 2c57494..9f55140 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,5 +1,6 @@
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
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..4841553
--- /dev/null
+++ b/target-s390x/cpu-models.c
@@ -0,0 +1,79 @@
+/*
+ * CPU models for s390
+ *
+ * Copyright 2014,2015 IBM Corp.
+ *
+ * Author(s): Michael Mueller <[email protected]>
+ *
+ * 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 = g_malloc0(sizeof(S390CPUMachineProps)); \
+ cc->mach->ga = cpu_ga(_cpu_id); \
+ cc->mach->class = cpu_class(_cpu_id); \
+ cc->mach->order = cpu_order(_cpu_id); \
+ cc->proc = g_malloc0(sizeof(S390CPUProcessorProps)); \
+ 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 <[email protected]>
+ *
+ * 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..1332147 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -32,6 +32,23 @@
#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 */
+ uint64_t *fac_list; /* list of facilities */
+} S390CPUProcessorProps;
+
/**
* S390CPUClass:
* @parent_realize: The parent class' realize handler.
@@ -52,6 +69,11 @@ 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 */
+ uint64_t *fac_list; /* active facility list */
+ S390CPUMachineProps *mach; /* machine specific properties */
+ S390CPUProcessorProps *proc; /* processor specific properties */
} S390CPUClass;

/**
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index d2f6312..1040765 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -325,6 +325,8 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
#endif
cc->gdb_num_core_regs = S390_NUM_CORE_REGS;
cc->gdb_core_xml_file = "s390x-core64.xml";
+ scc->mach = g_malloc0(sizeof(*scc->mach));
+ scc->proc = g_malloc0(sizeof(*scc->proc));
}

static const TypeInfo s390_cpu_type_info = {
--
1.8.3.1

2015-02-17 14:25:41

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 05/15] cpu-model/s390: Introduce S390 CPU facilities

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

Signed-off-by: Michael Mueller <[email protected]>
---
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..593b978
--- /dev/null
+++ b/target-s390x/cpu-facilities.h
@@ -0,0 +1,76 @@
+/*
+ * CPU facilities for s390
+ *
+ * Copyright 2015 IBM Corp.
+ *
+ * Author(s): Michael Mueller <[email protected]>
+ *
+ * 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 S390_ARCH_FAC_LIST_SIZE (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

2015-02-17 14:25:26

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 06/15] cpu-model/s390: Define cpu model specific facility lists

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 <[email protected]>
---
target-s390x/cpu-models.c | 13 ++++
target-s390x/cpu-models.h | 182 ++++++++++++++++++++++++++++++++++++++++++++++
target-s390x/cpu.c | 3 +
3 files changed, 198 insertions(+)

diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index 4841553..9e5c5fb 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -13,6 +13,8 @@
#include "qemu-common.h"
#include "cpu-models.h"

+#define S390_FAC_NAME(n, _cpu_id) glue(glue(glue(FAC, n), _), _cpu_id)
+
#define S390_PROC_DEF(_name, _cpu_id, _desc) \
static void \
glue(_cpu_id, _cpu_class_init) \
@@ -22,6 +24,7 @@
S390CPUClass *cc = S390_CPU_CLASS(oc); \
\
cc->is_active[ACCEL_ID_KVM] = true; \
+ cc->fac_list = g_malloc0(S390_ARCH_FAC_LIST_SIZE_BYTE);; \
cc->mach = g_malloc0(sizeof(S390CPUMachineProps)); \
cc->mach->ga = cpu_ga(_cpu_id); \
cc->mach->class = cpu_class(_cpu_id); \
@@ -32,6 +35,9 @@
cc->proc->id = S390_DEF_ID; \
cc->proc->type = cpu_type(_cpu_id); \
cc->proc->ibc = S390_DEF_IBC; \
+ cc->proc->fac_list = g_malloc0(S390_ARCH_FAC_LIST_SIZE_BYTE); \
+ cc->proc->fac_list[0] = S390_FAC_NAME(0, _cpu_id); \
+ cc->proc->fac_list[1] = S390_FAC_NAME(1, _cpu_id); \
dc->desc = _desc; \
} \
static const TypeInfo \
@@ -48,6 +54,12 @@
} \
type_init(glue(_cpu_id, _cpu_register_types))

+/* facilities iplemented by qemu */
+uint64_t qemu_s390_fac_list_mask[] = {
+ FAC0_QEMU_S390_MASK,
+ FAC1_QEMU_S390_MASK,
+};
+
/* 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")
@@ -77,3 +89,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..41af159 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -13,6 +13,13 @@
#ifndef TARGET_S390X_CPU_MODELS_H
#define TARGET_S390X_CPU_MODELS_H

+#include "cpu-facilities.h"
+
+#define S390_ARCH_FAC_LIST_SIZE_BYTE \
+ (S390_ARCH_FAC_LIST_SIZE)
+#define S390_ARCH_FAC_LIST_SIZE_UINT64 \
+ (S390_ARCH_FAC_LIST_SIZE / sizeof(uint64_t))
+
#define S390_EC 0x1
#define S390_BC 0x2

@@ -68,4 +75,179 @@ enum {
CPU_S390_2828_GA1 = 0x0c212828,
};

+#define S390_FAC_LIST_SIZE_UINT64 2
+#define S390_FAC_LIST_SIZE_BYTE \
+ (S390_FAC_LIST_SIZE_UINT64 * sizeof(uint64_t))
+#define S390_FAC_LIST_SIZE_BIT \
+ (S390_FAC_LIST_SIZE_BYTE << 3)
+
+#define FAC_BIT(WORD, BIT) \
+ (BIT / 64 == WORD ? 1ull << (63 - BIT % 64) : 0)
+
+/* S390 CPU facilities defined in QEMU mask */
+#define FAC0_QEMU_S390_MASK 0ULL
+#define FAC1_QEMU_S390_MASK 0ULL
+
+/* S390 CPU facility sets defined per CPU type and GA */
+#define FAC0_CPU_S390_2064_GA1 \
+ (FAC_BIT(0, FAC_N3) \
+ | FAC_BIT(0, FAC_ZARCH) \
+ | FAC_BIT(0, FAC_ZARCH_ACTIVE))
+#define FAC1_CPU_S390_2064_GA1 0ULL
+
+#define FAC0_CPU_S390_2064_GA2 \
+ (FAC0_CPU_S390_2064_GA1 \
+ | FAC_BIT(0, FAC_EXTENDED_TRANSLATION_2))
+#define FAC1_CPU_S390_2064_GA2 FAC1_CPU_S390_2064_GA1
+
+#define FAC0_CPU_S390_2064_GA3 FAC0_CPU_S390_2064_GA2
+#define FAC1_CPU_S390_2064_GA3 FAC1_CPU_S390_2064_GA2
+
+#define FAC0_CPU_S390_2066_GA1 FAC0_CPU_S390_2064_GA3
+#define FAC1_CPU_S390_2066_GA1 FAC1_CPU_S390_2064_GA3
+
+#define FAC0_CPU_S390_2084_GA1 \
+ (FAC0_CPU_S390_2064_GA3 \
+ | FAC_BIT(0, FAC_DAT_ENH) \
+ | FAC_BIT(0, FAC_MESSAGE_SECURITY_ASSIST) \
+ | FAC_BIT(0, FAC_LONG_DISPLACEMENT) \
+ | FAC_BIT(0, FAC_LONG_DISPLACEMENT_FAST) \
+ | FAC_BIT(0, FAC_HFP_MADDSUB))
+#define FAC1_CPU_S390_2084_GA1 FAC1_CPU_S390_2064_GA3
+
+#define FAC0_CPU_S390_2084_GA2 \
+ (FAC0_CPU_S390_2084_GA1 \
+ | FAC_BIT(0, 4))
+#define FAC1_CPU_S390_2084_GA2 FAC1_CPU_S390_2084_GA1
+
+#define FAC0_CPU_S390_2084_GA3 \
+ (FAC0_CPU_S390_2084_GA2 \
+ | FAC_BIT(0, FAC_ASN_LX_REUSE) \
+ | FAC_BIT(0, FAC_EXTENDED_TRANSLATION_3))
+#define FAC1_CPU_S390_2084_GA3 FAC1_CPU_S390_2084_GA2
+
+#define FAC0_CPU_S390_2084_GA4 FAC0_CPU_S390_2084_GA3
+#define FAC1_CPU_S390_2084_GA4 FAC1_CPU_S390_2084_GA3
+
+#define FAC0_CPU_S390_2084_GA5 \
+ (FAC0_CPU_S390_2084_GA4 \
+ | FAC_BIT(0, FAC_TOD_CLOCK_STEERING))
+#define FAC1_CPU_S390_2084_GA5 FAC1_CPU_S390_2084_GA4
+
+#define FAC0_CPU_S390_2086_GA1 FAC0_CPU_S390_2084_GA3
+#define FAC1_CPU_S390_2086_GA1 FAC1_CPU_S390_2084_GA3
+
+#define FAC0_CPU_S390_2086_GA2 FAC0_CPU_S390_2084_GA4
+#define FAC1_CPU_S390_2086_GA2 FAC1_CPU_S390_2084_GA4
+
+#define FAC0_CPU_S390_2086_GA3 FAC0_CPU_S390_2084_GA5
+#define FAC1_CPU_S390_2086_GA3 FAC1_CPU_S390_2084_GA5
+
+#define FAC0_CPU_S390_2094_GA1 \
+ (FAC0_CPU_S390_2084_GA5 \
+ | FAC_BIT(0, FAC_STFLE) \
+ | FAC_BIT(0, FAC_EXTENDED_IMMEDIATE) \
+ | FAC_BIT(0, FAC_HFP_UNNORMALIZED_EXT) \
+ | FAC_BIT(0, FAC_ETF2_ENH) \
+ | FAC_BIT(0, FAC_STORE_CLOCK_FAST) \
+ | FAC_BIT(0, FAC_ETF3_ENH) \
+ | FAC_BIT(0, FAC_EXTRACT_CPU_TIME))
+#define FAC1_CPU_S390_2094_GA1 FAC1_CPU_S390_2084_GA5
+
+#define FAC0_CPU_S390_2094_GA2 \
+ (FAC0_CPU_S390_2094_GA1 \
+ | FAC_BIT(0, FAC_SENSE_RUNNING_STATUS) \
+ | FAC_BIT(0, FAC_MOVE_WITH_OPTIONAL_SPEC) \
+ | FAC_BIT(0, FAC_COMPARE_AND_SWAP_AND_STORE) \
+ | FAC_BIT(0, FAC_FLOATING_POINT_SUPPPORT_ENH) \
+ | FAC_BIT(0, FAC_DFP))
+#define FAC1_CPU_S390_2094_GA2 FAC1_CPU_S390_2094_GA1
+
+#define FAC0_CPU_S390_2094_GA3 \
+ (FAC0_CPU_S390_2094_GA2 \
+ | FAC_BIT(0, FAC_PFPO))
+#define FAC1_CPU_S390_2094_GA3 FAC1_CPU_S390_2094_GA2
+
+#define FAC0_CPU_S390_2096_GA1 FAC0_CPU_S390_2094_GA3
+#define FAC1_CPU_S390_2096_GA1 FAC1_CPU_S390_2094_GA3
+
+#define FAC0_CPU_S390_2096_GA2 FAC0_CPU_S390_2096_GA1
+#define FAC1_CPU_S390_2096_GA2 FAC1_CPU_S390_2096_GA1
+
+#define FAC0_CPU_S390_2097_GA1 \
+ (FAC0_CPU_S390_2094_GA3 \
+ | FAC_BIT(0, FAC_ENHANCED_DAT_1) \
+ | FAC_BIT(0, FAC_CONDITIONAL_SSKE) \
+ | FAC_BIT(0, FAC_CONFIGURATION_TOPOLOGY) \
+ | FAC_BIT(0, FAC_PARSING_ENH) \
+ | FAC_BIT(0, FAC_COMPARE_AND_SWAP_AND_STORE_2) \
+ | FAC_BIT(0, FAC_GENERAL_INSTRUCTIONS_EXT) \
+ | FAC_BIT(0, FAC_EXECUTE_EXT) \
+ | FAC_BIT(0, FAC_DFP_FAST))
+#define FAC1_CPU_S390_2097_GA1 FAC1_CPU_S390_2094_GA3
+
+#define FAC0_CPU_S390_2097_GA2 FAC0_CPU_S390_2097_GA1
+#define FAC1_CPU_S390_2097_GA2 \
+ (FAC1_CPU_S390_2097_GA1 \
+ | FAC_BIT(1, 65) \
+ | FAC_BIT(1, FAC_CPU_MEASUREMENT_COUNTER) \
+ | FAC_BIT(1, FAC_CPU_MEASUREMENT_SAMPLING))
+
+#define FAC0_CPU_S390_2097_GA3 \
+ (FAC0_CPU_S390_2097_GA2 \
+ | FAC_BIT(0, FAC_LOAD_PROGRAM_PARAMETERS))
+#define FAC1_CPU_S390_2097_GA3 FAC1_CPU_S390_2097_GA2
+
+#define FAC0_CPU_S390_2098_GA1 FAC0_CPU_S390_2097_GA2
+#define FAC1_CPU_S390_2098_GA1 FAC1_CPU_S390_2097_GA2
+
+#define FAC0_CPU_S390_2098_GA2 FAC0_CPU_S390_2097_GA3
+#define FAC1_CPU_S390_2098_GA2 FAC1_CPU_S390_2097_GA3
+
+#define FAC0_CPU_S390_2817_GA1 \
+ (FAC0_CPU_S390_2097_GA3 \
+ | FAC_BIT(0, FAC_ENHANCED_MONITOR) \
+ | FAC_BIT(0, FAC_FLOATING_POINT_EXT) \
+ | FAC_BIT(0, FAC_MULTI_45) \
+ | FAC_BIT(0, 46))
+#define FAC1_CPU_S390_2817_GA1 \
+ ((FAC1_CPU_S390_2097_GA3 \
+ & ~FAC_BIT(1, 65)) \
+ | FAC_BIT(1, FAC_ACCESS_EXCEPTION_FS_INDICATION))
+
+#define FAC0_CPU_S390_2817_GA2 \
+ (FAC0_CPU_S390_2817_GA1 \
+ | FAC_BIT(0, FAC_IPTE_RANGE) \
+ | FAC_BIT(0, FAC_NONQ_KEY_SETTING) \
+ | FAC_BIT(0, FAC_CMPSC_ENH))
+#define FAC1_CPU_S390_2817_GA2 \
+ (FAC1_CPU_S390_2817_GA1 \
+ | FAC_BIT(1, FAC_RESET_REFERENCE_BITS_MULTIPLE) \
+ | FAC_BIT(1, FAC_MESSAGE_SECURITY_ASSIST_3) \
+ | FAC_BIT(1, FAC_MESSAGE_SECURITY_ASSIST_4))
+
+#define FAC0_CPU_S390_2818_GA1 FAC0_CPU_S390_2817_GA2
+#define FAC1_CPU_S390_2818_GA1 FAC1_CPU_S390_2817_GA2
+
+#define FAC0_CPU_S390_2827_GA1 \
+ (FAC0_CPU_S390_2817_GA2 \
+ | FAC_BIT(0, FAC_DFP_ZONED_CONVERSION) \
+ | FAC_BIT(0, FAC_MULTI_49) \
+ | FAC_BIT(0, FAC_CONSTRAINT_TRANSACTIONAL_EXE) \
+ | FAC_BIT(0, FAC_LOCAL_TLB_CLEARING) \
+ | FAC_BIT(0, FAC_INTERLOCKED_ACCESS_2))
+#define FAC1_CPU_S390_2827_GA1 \
+ (FAC1_CPU_S390_2817_GA2 \
+ | FAC_BIT(1, FAC_TRANSACTIONAL_EXE) \
+ | FAC_BIT(1, FAC_ENHANCED_DAT_2))
+
+#define FAC0_CPU_S390_2827_GA2 FAC0_CPU_S390_2827_GA1
+#define FAC1_CPU_S390_2827_GA2 FAC1_CPU_S390_2827_GA1
+
+#define FAC0_CPU_S390_2828_GA1 FAC0_CPU_S390_2827_GA2
+#define FAC1_CPU_S390_2828_GA1 FAC1_CPU_S390_2827_GA2
+
+#define FAC0_CPU_S390_2964_GA1 FAC0_CPU_S390_2828_GA1
+#define FAC1_CPU_S390_2964_GA1 FAC1_CPU_S390_2828_GA1
+
#endif
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 1040765..f30856e 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
@@ -327,6 +328,8 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_core_xml_file = "s390x-core64.xml";
scc->mach = g_malloc0(sizeof(*scc->mach));
scc->proc = g_malloc0(sizeof(*scc->proc));
+ scc->fac_list = g_malloc0(S390_ARCH_FAC_LIST_SIZE_BYTE);
+ scc->proc->fac_list = g_malloc0(S390_ARCH_FAC_LIST_SIZE_BYTE);
}

static const TypeInfo s390_cpu_type_info = {
--
1.8.3.1

2015-02-17 14:25:10

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 07/15] cpu-model/s390: Add cpu model alias definition routines

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

Signed-off-by: Michael Mueller <[email protected]>
Reviewed-by: Cornelia Huck <[email protected]>
---
target-s390x/cpu-models.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++
target-s390x/cpu-models.h | 11 +++++++
2 files changed, 88 insertions(+)

diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index 9e5c5fb..8d2c2e2 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -90,3 +90,80 @@ 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;
+
+ blen = strlen(bname);
+ if (!strncasecmp(bname, aname, blen) &&
+ !strcmp(aname + blen, "-" TYPE_S390_CPU)) {
+ return 0;
+ }
+ return -1;
+}
+
+/**
+ * s390_cpu_class_by_name - retrive cpu object class by given name
+ * @name: the cpu model name
+ *
+ * Returns: address of object class on success
+ * NULL if name is not a valid model name
+ */
+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 - define a alias for an existing cpu model
+ * @name: the cpu alias name
+ * @model: the cpu model name
+ *
+ * Returns: 0 on 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
+ */
+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 41af159..623a7b2 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -34,6 +34,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
--
1.8.3.1

2015-02-17 14:28:28

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 08/15] cpu-model/s390: Update linux-headers/asm-s390/kvm.h

Signed-off-by: Michael Mueller <[email protected]>
---
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

2015-02-17 14:25:23

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 09/15] cpu-model/s390: Add KVM VM attribute interface routines

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 <[email protected]>
---
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 623a7b2..76b3456 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -45,6 +45,45 @@ typedef struct S390CPUAlias {
char *model;
} S390CPUAlias;

+typedef struct S390ProcessorProps {
+ uint64_t cpuid;
+ uint16_t ibc;
+ uint8_t pad[6];
+ uint64_t fac_list[S390_ARCH_FAC_LIST_SIZE_UINT64];
+} S390ProcessorProps;
+
+typedef struct S390MachineProps {
+ uint64_t cpuid;
+ uint32_t ibc_range;
+ uint8_t pad[4];
+ uint64_t fac_list_mask[S390_ARCH_FAC_LIST_SIZE_UINT64];
+ uint64_t fac_list[S390_ARCH_FAC_LIST_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 6f2d5b4..c518489 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -42,6 +42,7 @@
#include "qapi-event.h"
#include "hw/s390x/s390-pci-inst.h"
#include "hw/s390x/s390-pci-bus.h"
+#include "cpu-models.h"

/* #define DEBUG_KVM */

@@ -117,6 +118,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);

@@ -172,6 +174,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);
@@ -185,6 +249,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;
}

@@ -1570,3 +1636,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

2015-02-17 14:29:04

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 10/15] cpu-model/s390: Add cpu class initialization routines

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_test_facility(), facility bit probe function for QEMU land
- s390_probe_mode, test if running in probe mode

Signed-off-by: Michael Mueller <[email protected]>
---
target-s390x/cpu-models.c | 464 ++++++++++++++++++++++++++++++++++++++++++++++
target-s390x/cpu-models.h | 27 +++
target-s390x/cpu.c | 17 +-
target-s390x/kvm.c | 4 +-
4 files changed, 510 insertions(+), 2 deletions(-)

diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index 8d2c2e2..9f40998 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 "qemu/error-report.h"

#define S390_FAC_NAME(n, _cpu_id) glue(glue(glue(FAC, n), _), _cpu_id)

@@ -90,8 +91,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);
@@ -167,3 +201,433 @@ 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);
+ unsigned int i;
+
+ 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
+ */
+ for (i = 0; i < S390_FAC_LIST_SIZE_UINT64; i++) {
+ cc->fac_list[i] = cc->proc->fac_list[i] &
+ (qemu_s390_fac_list_mask[i] | parm->prop->fac_list_mask[i]);
+ }
+
+ /*
+ * Finally, mark the cpu class inactive if not all resulting/desired
+ * facilities are offered by the host.
+ * (RFL & MFL) != RFL
+ */
+ for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_UINT64 &&
+ cc->is_active[parm->accel]; i++) {
+ if ((cc->fac_list[i] & parm->prop->fac_list[i]) != cc->fac_list[i]) {
+ 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->mach->order > parm->host_cc->mach->order) {
+ 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 - initialize the cpu classes for a given accelerator
+ * type, mark the default cpu model and define aliases
+ * @accel: the accelerator id
+ * @prop: the addresd to a machine property structure initialized with
+ * machine related properties of the hosting machine
+ *
+ * Returns: 0 in case of success
+ * -EINVAL in case no valid default model was identified
+ */
+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);
+
+ /* 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 - indicates if the all cpu classes and
+ * their properties have been initialized
+ *
+ * Returns: true in case they are initialized
+ * false in case they are not iniialized
+ */
+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();
+}
+
+static inline uint64_t big_endian_bit(unsigned long nr)
+{
+ return 1ul << (BITS_PER_LONG - (nr % BITS_PER_LONG));
+};
+
+static inline int test_facility(unsigned long nr, uint64_t *fac_list)
+{
+ uint64_t *ptr;
+
+ if (nr >= S390_ARCH_FAC_LIST_SIZE_BYTE * BITS_PER_BYTE) {
+ return 0;
+ }
+ ptr = fac_list + (nr / BITS_PER_LONG);
+
+ return !!(*ptr & big_endian_bit(nr));
+}
+
+/**
+ * s390_test_facility - test if given facility bit is set facility list
+ * of given cpu class
+ * @class: address of cpu class to test
+ * @nr: bit number to test
+ *
+ * Returns: true in case it is set
+ * false in case it is not set
+ */
+bool s390_test_facility(S390CPUClass *cc, unsigned long nr)
+{
+ if (cc) {
+ return test_facility(nr, cc->fac_list) ? true : false;
+ }
+ return false;
+}
+
+/**
+ * s390_probe_mode - indicates that the current machine was initialized
+ * in probe mode
+ *
+ * Returns: true if in probe mode
+ * false if in standard mode
+ */
+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 76b3456..be94667 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -28,12 +28,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);

@@ -84,6 +104,13 @@ 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_test_facility(S390CPUClass *cc, unsigned long nr);
+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 f30856e..d27832b 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 c518489..ce2392a 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -232,7 +232,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

2015-02-17 14:29:06

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 11/15] cpu-model/s390: Add QMP command query-cpu-model

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 <[email protected]>
---
include/sysemu/arch_init.h | 1 +
qapi-schema.json | 23 +++++++++++++++++++++++
qmp-commands.hx | 6 ++++++
qmp.c | 5 +++++
stubs/Makefile.objs | 1 +
stubs/arch-query-cpu-mod.c | 9 +++++++++
target-s390x/cpu-models.c | 25 +++++++++++++++++++++++++
target-s390x/cpu-models.h | 2 ++
target-s390x/cpu.c | 32 ++++++++++++++++++++++++++++++++
9 files changed, 104 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 4d237c8..9431fc2 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2507,6 +2507,29 @@
##
{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] }

+##
+# @CpuModelInfo:
+#
+# Virtual CPU model definition.
+#
+# @name: the name of the CPU model definition
+#
+# Since: 2.3.0
+##
+{ 'type': 'CpuModelInfo',
+ 'data': { 'name': 'str', '*accelerator': 'AccelId' } }
+
+##
+# @query-cpu-model:
+#
+# Return to current virtual CPU model
+#
+# Returns: CpuModelInfo
+#
+# Since: 2.3.0
+##
+{ '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 6b2c4be..d32abbc 100644
--- a/qmp.c
+++ b/qmp.c
@@ -568,6 +568,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 9f40998..4d03adc 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -110,6 +110,7 @@ typedef struct ParmAddrAddrAccel {
} ParmAddrAddrAccel;

static GSList *s390_cpu_aliases;
+static const char *selected_cpu_typename;

/* compare order of two cpu classes for ascending sort */
gint s390_cpu_class_asc_order_compare(gconstpointer a, gconstpointer b)
@@ -631,3 +632,27 @@ bool s390_probe_mode(void)
return false;
}

+/**
+ * s390_cpu_typename - get name of selected cpu class type
+ *
+ * Returns: address to name of selected cpu class type
+ * NULL if no cpu class type has been selected yet
+ */
+const char *s390_cpu_typename(void)
+{
+ return selected_cpu_typename;
+}
+
+/**
+ * s390_cpu_models_used - indicates that cpus with model properties
+ * are in use
+ *
+ * Returns: true if a cpu model type name has been selected
+ * false if either no cpu class type was selected yet or the
+ * selected type is TYPE_S390_CPU
+ */
+bool s390_cpu_models_used(void)
+{
+ return s390_cpu_typename() && strcmp(s390_cpu_typename(), TYPE_S390_CPU);
+}
+
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index be94667..23ac2c4 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -110,6 +110,8 @@ void s390_cpu_list_entry(gpointer data, gpointer user_data);
bool s390_cpu_classes_initialized(void);
bool s390_test_facility(S390CPUClass *cc, unsigned long nr);
bool s390_probe_mode(void);
+const char *s390_cpu_typename(void);
+bool s390_cpu_models_used(void);

/*
* bits 0-7 : CMOS generation
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index d27832b..d98578b 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,33 @@ 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_CLASS(object_class_by_name(s390_cpu_typename()));
+ info->name = strdup_s390_cpu_name(cc);
+ if (!info->name) {
+ g_free(info);
+ return NULL;
+ }
+ info->accelerator = ACCEL_ID_MAX;
+ if (kvm_enabled()) {
+ info->accelerator = ACCEL_ID_KVM;
+ }
+ info->has_accelerator = (info->accelerator != ACCEL_ID_MAX);
+
+ return info;
+}
#endif

static void s390_cpu_set_pc(CPUState *cs, vaddr value)
--
1.8.3.1

2015-02-17 14:28:46

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 12/15] cpu-model/s390: Extend QMP command query-cpu-definitions

This patch implements the QMP command 'query-cpu-definitions' in the S390
context. The command returns a in terms of machine release date descending
sorted 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.

Thy 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 either no specific cpu
was requested during QEMU startup or the cpu model with named 'host'.

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 <[email protected]>
---
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 9431fc2..a5d38ae 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2485,16 +2485,35 @@
'data': ['qtest', 'tcg', 'kvm', 'xen' ] }

##
+# @AccelCpuModelInfo:
+#
+# Accelerator specific CPU model data
+#
+# @id: the accelerator id
+#
+# @default: cpu model for 'host'
+#
+# @runnable: cpu model can be activated on hosting machine
+#
+# Since: 2.3.0
+#
+##
+{ '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.0)
+#
# 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 4d03adc..c63b4c2 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -202,6 +202,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 23ac2c4..d41fc37 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -106,6 +106,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_test_facility(S390CPUClass *cc, unsigned long nr);
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index d98578b..42d38b0 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

2015-02-17 14:25:16

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 13/15] cpu-model/s390: Add processor property routines

This patch implements the functions:

- s390_get_proceccor_props()
- s390_set_proceccor_props()

They can be used to request or retrieve processor related information from an accelerator.
That information comprises the cpu identifier, the ICB value and the facility lists.

Signed-off-by: Michael Mueller <[email protected]>
---
target-s390x/cpu-models.c | 36 ++++++++++++++++++++++++++++++++++++
target-s390x/cpu-models.h | 2 ++
2 files changed, 38 insertions(+)

diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index c63b4c2..9bc4d89 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -579,6 +579,42 @@ void s390_cpu_list_entry(gpointer data, gpointer user_data)
}

/**
+ * s390_get_processor_props - retrieves processor properties from
+ * from the currently used accelerator
+ * @prop: address to processor property structure to store the
+ * retrieved processor properties
+ *
+ * Returns: 0 in case of success
+ * -ENOSYS in case the current accelerator has no processor
+ * properties implemented
+ */
+int s390_get_processor_props(S390ProcessorProps *prop)
+{
+ if (kvm_enabled()) {
+ return kvm_s390_get_processor_props(prop);
+ }
+ return -ENOSYS;
+}
+
+/**
+ * s390_set_processor_props - stores processor properties in the
+ * currently used accelerator
+ * @prop: address to processor property structure to store the
+ * retrieved processor properties
+ *
+ * Returns: 0 in case of success
+ * -ENOSYS in case the current accelerator has no processor
+ * properties implemented
+ */
+int s390_set_processor_props(S390ProcessorProps *prop)
+{
+ if (kvm_enabled()) {
+ return kvm_s390_set_processor_props(prop);
+ }
+ return -ENOSYS;
+}
+
+/**
* s390_cpu_classes_initialized - indicates if the all cpu classes and
* their properties have been initialized
*
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index d41fc37..bc478d8 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -108,6 +108,8 @@ 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);
+int s390_get_processor_props(S390ProcessorProps *prop);
+int s390_set_processor_props(S390ProcessorProps *prop);
bool s390_cpu_classes_initialized(void);
bool s390_test_facility(S390CPUClass *cc, unsigned long nr);
bool s390_probe_mode(void);
--
1.8.3.1

2015-02-17 14:27:00

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 14/15] cpu-model/s390: Add cpu model selection routine

This patch basically implements the routine:

- s390_select_cpu_model()

It tests if the the cpu classes have been initialized and the requested
cpu model is either a valid model or a valid alias. If these conditions
are met, the associated cpu model properties (cpu identifier, ibc value,
cpu facilities) are established with the current accelerator. If also this
step was successful, QEMU stores the related cpu model type name to be
returned by subsequent calls to this routine. This will guarantee all
cpus will use the same model.

Here an example of a returned cpu type name: '2827-ga2-s390-cpu'

If one of the priviously mentioned steps fail, QEMU stores and returns the
default cpu model type name: 's390-cpu'.

The function has a trace point.

Signed-off-by: Michael Mueller <[email protected]>
---
target-s390x/cpu-models.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
target-s390x/cpu-models.h | 4 ++++
trace-events | 3 +++
3 files changed, 52 insertions(+)

diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index 9bc4d89..bd36d10 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 "qemu/error-report.h"
+#include "trace.h"

#define S390_FAC_NAME(n, _cpu_id) glue(glue(glue(FAC, n), _), _cpu_id)

@@ -707,3 +708,47 @@ bool s390_cpu_models_used(void)
return s390_cpu_typename() && strcmp(s390_cpu_typename(), TYPE_S390_CPU);
}

+/**
+ * s390_select_cpu_model - select the cpu model to be used by QEMU
+ * @model: the cpu model name
+ *
+ * Returns: the cpu class type name (<type>-<ga>-s390-cpu) associated
+ * to the requested cpu model
+ * TYPE_S390_CPU in case the requested model is invalid or
+ * cannot be requested for the currently used accelerator
+ */
+const char *s390_select_cpu_model(const char *model)
+{
+ S390ProcessorProps proc;
+ const char *typename;
+ S390CPUClass *cc;
+
+ /* return already selected cpu typename */
+ typename = s390_cpu_typename();
+ if (typename) {
+ goto out;
+ }
+
+ /* return standard cpu typename when cpu models are unavailable */
+ typename = TYPE_S390_CPU;
+ if (!s390_cpu_classes_initialized() || !model) {
+ goto out;
+ }
+ cc = S390_CPU_CLASS(s390_cpu_class_by_name(model));
+ if (!cc) {
+ goto out;
+ }
+ proc.cpuid = cpuid(cc->proc);
+ proc.ibc = cc->proc->ibc;
+ memcpy(proc.fac_list, cc->fac_list, S390_FAC_LIST_SIZE_BYTE);
+ if (s390_set_processor_props(&proc)) {
+ goto out;
+ }
+
+ /* return requested cpu typename in success case */
+ typename = object_class_get_name((ObjectClass *) cc);
+out:
+ selected_cpu_typename = typename;
+ trace_select_cpu_model(model, typename);
+ return typename;
+}
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index bc478d8..254e1ef 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -44,6 +44,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)
@@ -115,6 +118,7 @@ bool s390_test_facility(S390CPUClass *cc, unsigned long nr);
bool s390_probe_mode(void);
const char *s390_cpu_typename(void);
bool s390_cpu_models_used(void);
+const char *s390_select_cpu_model(const char *model);

/*
* bits 0-7 : CMOS generation
diff --git a/trace-events b/trace-events
index f39f879..014fa12 100644
--- a/trace-events
+++ b/trace-events
@@ -1588,3 +1588,6 @@ i8257_unregistered_dma(int nchan, int dma_pos, int dma_len) "unregistered DMA ch
cpu_set_state(int cpu_index, uint8_t state) "setting cpu %d state to %" PRIu8
cpu_halt(int cpu_index) "halting cpu %d"
cpu_unhalt(int cpu_index) "unhalting cpu %d"
+
+# target-s390x/cpu-model.c
+select_cpu_model(const char *model, const char *typename) "CPU-MODEL: requested: %s selected: %s"
--
1.8.3.1

2015-02-17 14:26:04

by Michael Mueller

[permalink] [raw]
Subject: [RFC PATCH v2 15/15] cpu-model/s390: Enable S390 cpu model

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

Signed-off-by: Michael Mueller <[email protected]>
---
hw/s390x/s390-virtio.c | 6 ++++++
target-s390x/helper.c | 3 ++-
2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index c215cd8..aabd772 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"
@@ -152,6 +153,11 @@ void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys)
cpu_model = "host";
}

+ if (is_help_option(cpu_model)) {
+ list_cpus(stdout, &fprintf, cpu_model);
+ exit(0);
+ }
+
ipi_states = g_malloc(sizeof(S390CPU *) * smp_cpus);

for (i = 0; i < smp_cpus; i++) {
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 5958343..568428d 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
@@ -75,7 +76,7 @@ S390CPU *cpu_s390x_init(const char *cpu_model)
{
S390CPU *cpu;

- cpu = S390_CPU(object_new(TYPE_S390_CPU));
+ cpu = S390_CPU(object_new(s390_select_cpu_model(cpu_model)));

object_property_set_bool(OBJECT(cpu), true, "realized", NULL);

--
1.8.3.1

2015-02-17 18:03:28

by Eric Blake

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 11/15] cpu-model/s390: Add QMP command query-cpu-model

On 02/17/2015 07:24 AM, Michael Mueller wrote:
> 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 <[email protected]>
> ---
>
> +##
> +# @CpuModelInfo:
> +#
> +# Virtual CPU model definition.
> +#
> +# @name: the name of the CPU model definition
> +#
> +# Since: 2.3.0
> +##
> +{ 'type': 'CpuModelInfo',
> + 'data': { 'name': 'str', '*accelerator': 'AccelId' } }

You didn't document '*accelerator', including mention that it is
optional (why would it not be output always?).

> +
> +##
> +# @query-cpu-model:
> +#
> +# Return to current virtual CPU model

s/to/the/

> +#
> +# Returns: CpuModelInfo
> +#
> +# Since: 2.3.0

We aren't very consistent on '2.3' vs. '2.3.0', so I won't complain
about that.

> +##
> +{ 'command': 'query-cpu-model', 'returns': 'CpuModelInfo' }

Seems reasonable from the interface point of view; I have not closely
reviewed the implementation.

--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org


Attachments:
signature.asc (604.00 B)
OpenPGP digital signature

2015-02-17 18:10:55

by Eric Blake

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 12/15] cpu-model/s390: Extend QMP command query-cpu-definitions

On 02/17/2015 07:24 AM, Michael Mueller wrote:
> This patch implements the QMP command 'query-cpu-definitions' in the S390
> context. The command returns a in terms of machine release date descending
> sorted list of cpu model names in the current host context.

returns a list of cpu model names sorted by descending release dates.

Does guaranteeing the sorting as part of the interface really matter, or
would it be better to just return the list with no documented sorting
(where callers treat it as unsorted)?

> A consumer may
> successfully request each listed cpu model as long for a given accelerator
> this model is runnable.
>
> Thy 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 either no specific cpu
> was requested during QEMU startup or the cpu model with named 'host'.
>
> 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}]}
> ]
> }
>

Looks okay from an interface perspective.

> Signed-off-by: Michael Mueller <[email protected]>
> ---
> 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 9431fc2..a5d38ae 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -2485,16 +2485,35 @@
> 'data': ['qtest', 'tcg', 'kvm', 'xen' ] }
>
> ##
> +# @AccelCpuModelInfo:
> +#
> +# Accelerator specific CPU model data
> +#
> +# @id: the accelerator id
> +#

There is no 'id' field below, did you mean 'name'?

> +# @default: cpu model for 'host'
> +#
> +# @runnable: cpu model can be activated on hosting machine
> +#
> +# Since: 2.3.0
> +#
> +##
> +{ '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.0)
> +#

Must the field be optional, or will we always provide it? Since this is
an output-only field, it is okay for back-compat to make the new field
unconditional.

--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org


Attachments:
signature.asc (604.00 B)
OpenPGP digital signature

2015-02-17 19:16:37

by Eric Blake

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 02/15] cpu-model: Introduce option --probe to switch into probe mode

On 02/17/2015 07:24 AM, Michael Mueller wrote:
> 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 accellerators that support probing is used.

s/accellerators/accelerators/

>
> Signed-off-by: Michael Mueller <[email protected]>
> ---
> accel.c | 13 ++++++++-----
> include/sysemu/accel.h | 2 +-
> qemu-options.hx | 8 ++++++++
> vl.c | 7 ++++++-
> 4 files changed, 23 insertions(+), 7 deletions(-)
>

--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org


Attachments:
signature.asc (604.00 B)
OpenPGP digital signature

2015-02-18 08:40:24

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 11/15] cpu-model/s390: Add QMP command query-cpu-model

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tue, 17 Feb 2015 11:03:11 -0700
Eric Blake <[email protected]> wrote:

> On 02/17/2015 07:24 AM, Michael Mueller wrote:
> > 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 <[email protected]>
> > ---
> >
> > +##
> > +# @CpuModelInfo:
> > +#
> > +# Virtual CPU model definition.
> > +#
> > +# @name: the name of the CPU model definition
> > +#
> > +# Since: 2.3.0
> > +##
> > +{ 'type': 'CpuModelInfo',
> > + 'data': { 'name': 'str', '*accelerator': 'AccelId' } }
>
> You didn't document '*accelerator', including mention that it is
> optional (why would it not be output always?).

Right, as it is a new command and all cpus once implementing it have an associated accelerator
there is no point in making it optional. Will add a comment as well.
>
> > +
> > +##
> > +# @query-cpu-model:
> > +#
> > +# Return to current virtual CPU model
>
> s/to/the/

yep

>
> > +#
> > +# Returns: CpuModelInfo
> > +#
> > +# Since: 2.3.0
>
> We aren't very consistent on '2.3' vs. '2.3.0', so I won't complain
> about that.

But you seem to prefer major and minor only, so I will skip the trailing 0.

>
> > +##
> > +{ 'command': 'query-cpu-model', 'returns': 'CpuModelInfo' }
>
> Seems reasonable from the interface point of view; I have not closely
> reviewed the implementation.
>

Thanks
Michael
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBAgAGBQJU5E/fAAoJELPcPLQSJsKQYksP/inWhcSnQF6WgNTaF2qsEqyG
6kRyAwfVID9k0Rh1Eh3fDKbDDrtXe1pB3dbHlX6JWWrDCQCzfFxbRDElK3lX4k1g
ryAi9ZRPZ7TB88eGIS66vQ4J/O9WWe/I7tzoX2yeFcMRNa9+8dpyluPHWNYbeN6f
KkzQy15PabCiggwQuDfm+X4jiV7HtIdxRVNuOJV4j2U8p6Wp5YaZMEp8MJQ2tDMe
Uion91VZ2izLQ/rn+QIb1F28om03LWfh47sKzam9l9oomFglGhmHXkEktL+KCQTK
MSUQOiIK3rSzZiFq5dsjIAOo1bkrjYpPxUfxq0xDjreJoGkd1sbtQ663QHG0RUTT
1G0BNKHxNggkxoxyChaEYWopNyZ2wMEn3XBaVHvnfDqDyymsWo3nAQVWIMwFpHth
vSfBLY3CJnAW4HnDiaV3+sNDlFZlttzPE5jVXibR98sCdQORNEpCt9frdu1AToGB
MCiAwJMc1qescJMghsogCUzG9ElA7wbvGIv+e/uEGj7LB/1H0ZMIpN/QU9NDd3Fi
XpldGvPLIWRJq7/l8c6/KNg8SbTn1prtGZ1pKNOlkmn+BeEQjcihEmGOStoWny48
1hT08enhBJ9skXvWlGTvYBlohQ6vERwZ5B9E4tmSeLRQG+4YkE3JTyb0FJJScBoV
l1X+PmwiT2AfeXLlDHlm
=6Qmi
-----END PGP SIGNATURE-----
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2015-02-18 09:08:32

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 02/15] cpu-model: Introduce option --probe to switch into probe mode

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tue, 17 Feb 2015 12:16:20 -0700
Eric Blake <[email protected]> wrote:

> On 02/17/2015 07:24 AM, Michael Mueller wrote:
> > 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 accellerators that support probing is used.
>
> s/accellerators/accelerators/

ups

>
> >
> > Signed-off-by: Michael Mueller <[email protected]>
> > ---
> > accel.c | 13 ++++++++-----
> > include/sysemu/accel.h | 2 +-
> > qemu-options.hx | 8 ++++++++
> > vl.c | 7 ++++++-
> > 4 files changed, 23 insertions(+), 7 deletions(-)
> >
>

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBAgAGBQJU5FZ/AAoJELPcPLQSJsKQxGMP/0MnqhT4bAL98hgRnhPZyoEt
wGSB4zoBQ0VnhQ7XiXe2HhVn2y8I9XI2pn/GpQgDInlMQ7HYhM7UtWD3/Wlrp0ky
MyCNrsD0/cT3bjAhZ0OlGC3fqujVLVmxGc5wQrmymYKKNaWMoDNQt3PFYk6ZKHSh
2RzLFkWSzx3iWKcsZ5aA0Sxms21L0c+TPx9/EAvUohyul5tyGe0Sf7TleS0YBjLH
O4y1QmiXaFdGLag/wp535bSG1s4JkOxYgWKWohxVs7qwl0NNMbQPiL1Z9NO3ushs
5J9BjLD54fhmXnHEFHBaS1o//hL12wkssyUBdiCObpANltGZN23qvsh5zh2Rv/Sb
QqYDCBimqxn5Y4J9xUIzONNmrQ3y5jyJTuNK0Q9Wd9lEklgs9r5Bn/ro0/zKSCVH
zgLsjFqS6Rh2MZnu8Vvi8bEtle7zwYiQ0TfpFn1oaGJlzO7+9S6RbLIAO0XQlDxT
0R097n3D0VtLVznyHvJuRdyO4fdNuy4joo03Oej0/8HpKqaQxZhUSP7ReaIvcqyw
kqM2q0wPyIemFrg6WrNb2pVAqljSFOHNl0dNQPuoprWP3M6cXVWfE8IO01kjNIiy
muR2dh2w03JiPm3jwNEe+bEsw3lx7cLYx5fxh/8A7VD5Fh9nIVEawJXG5359hUiV
etSL5sdva53IUMkxWetu
=FFkJ
-----END PGP SIGNATURE-----
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2015-02-18 09:29:45

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 12/15] cpu-model/s390: Extend QMP command query-cpu-definitions

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tue, 17 Feb 2015 11:09:34 -0700
Eric Blake <[email protected]> wrote:

> On 02/17/2015 07:24 AM, Michael Mueller wrote:
> > This patch implements the QMP command 'query-cpu-definitions' in the S390
> > context. The command returns a in terms of machine release date descending
> > sorted list of cpu model names in the current host context.
>
> returns a list of cpu model names sorted by descending release dates.
>
> Does guaranteeing the sorting as part of the interface really matter, or
> would it be better to just return the list with no documented sorting
> (where callers treat it as unsorted)?

Yep, that is an implementation detail and I don't depend on that. If a sequence would be required
one cold model a field named "order". But as said, I don't require that and will update the
comment by dropping the "sorted list" part.

>
> > A consumer may
> > successfully request each listed cpu model as long for a given accelerator
> > this model is runnable.
> >
> > Thy 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 either no specific cpu
> > was requested during QEMU startup or the cpu model with named 'host'.
> >
> > 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}]}
> > ]
> > }
> >
>
> Looks okay from an interface perspective.
>
> > Signed-off-by: Michael Mueller <[email protected]>
> > ---
> > 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 9431fc2..a5d38ae 100644
> > --- a/qapi-schema.json
> > +++ b/qapi-schema.json
> > @@ -2485,16 +2485,35 @@
> > 'data': ['qtest', 'tcg', 'kvm', 'xen' ] }
> >
> > ##
> > +# @AccelCpuModelInfo:
> > +#
> > +# Accelerator specific CPU model data
> > +#
> > +# @id: the accelerator id
> > +#
>
> There is no 'id' field below, did you mean 'name'?

I did rename that one time to often :-), will s/id/name/g ...

>
> > +# @default: cpu model for 'host'
> > +#
> > +# @runnable: cpu model can be activated on hosting machine
> > +#
> > +# Since: 2.3.0
> > +#
> > +##
> > +{ '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.0)
> > +#
>
> Must the field be optional, or will we always provide it? Since this is
> an output-only field, it is okay for back-compat to make the new field
> unconditional.

It will be always provided when an accelerator supports cpu models and implements the
probing mode. As I'm currently adopting it for s390/kvm only, I can't enforce it for all
other arch/accelerator combinations as it is an extension of an existing command...

Thanks
Michael

>

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBAgAGBQJU5Ft5AAoJELPcPLQSJsKQ520P/A3EQqyY7buhBZWwVDQcA49J
FSzjyEt2JAJmZAlMFMaxbVDwJcm5PXEbCHR1+NuDXuyEYsPxqG7TxvP+3yLR2lLa
QbucHGd9M789Tg0hy2YPifIIB93LY5Kb3SNxhL52olyIrnsovHoBCbboMlmmKTk7
KyH6q2KXddjWtZbHy9WGQY91r56yMdsbfIxbYMJuJbJ/9Hr0lh0xB6W77mL8GIrV
dbURjaZXwgoGecVAlyEQcpInS2fl6XSX7Y2rCAq9Jp/9ZNfSQdOai19Md2cQ1JLi
92qYwgT8XV6bZOHJ1E8xc7+KlJRRH4MvYbWTNCVHEA3ewE5rYkspe92fEj82GZnc
eJV+hjZcq9cNaOF8bvhpjy+9zW8WdrwsQKbXNEeJDzDmnYhaaKcdKRa6qUDwYLQW
eg+TAfO+G9YNYfEpJH5okCo3t7elpYlkdcOvNtj1X2gFAmpjkbeVOUWSD1JmtJ5u
+s3XUagvQdzoIdpsziob0NEpLU62QFcqAa3ZNSY/FE7itTMnZs2+rvbYUxGyRjqz
BbEwPDoAMcFCO6CdK/hoZxV8RbCRH+MoDy+oLKXbxsF1rJcFfe5VGUQBTbYJUNEO
l87sUJBw5AqcU5/VpnuQn/unVCupQxour63T6WxzobvFT+rpMIR8mUQXaAEe9RfJ
8G8A5VXn8C4zrC2Am5G5
=cpfo
-----END PGP SIGNATURE-----
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2015-02-20 13:54:29

by Alexander Graf

[permalink] [raw]
Subject: Re: [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models



On 17.02.15 15:24, Michael Mueller wrote:
> 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 <[email protected]>
> Reviewed-by: Thomas Huth <[email protected]>
> ---
> qapi-schema.json | 11 +++++++
> target-s390x/Makefile.objs | 1 +
> target-s390x/cpu-models.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++
> target-s390x/cpu-models.h | 71 +++++++++++++++++++++++++++++++++++++++++
> target-s390x/cpu-qom.h | 22 +++++++++++++
> target-s390x/cpu.c | 2 ++
> 6 files changed, 186 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..4d237c8 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.0
> +##
> +{ 'enum': 'AccelId',
> + 'data': ['qtest', 'tcg', 'kvm', 'xen' ] }
> +
> ##
> # @CpuDefinitionInfo:
> #
> diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
> index 2c57494..9f55140 100644
> --- a/target-s390x/Makefile.objs
> +++ b/target-s390x/Makefile.objs
> @@ -1,5 +1,6 @@
> 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
> 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..4841553
> --- /dev/null
> +++ b/target-s390x/cpu-models.c
> @@ -0,0 +1,79 @@
> +/*
> + * CPU models for s390
> + *
> + * Copyright 2014,2015 IBM Corp.
> + *
> + * Author(s): Michael Mueller <[email protected]>
> + *
> + * 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 = g_malloc0(sizeof(S390CPUMachineProps)); \
> + cc->mach->ga = cpu_ga(_cpu_id); \
> + cc->mach->class = cpu_class(_cpu_id); \
> + cc->mach->order = cpu_order(_cpu_id); \
> + cc->proc = g_malloc0(sizeof(S390CPUProcessorProps)); \
> + 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 <[email protected]>
> + *
> + * 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..1332147 100644
> --- a/target-s390x/cpu-qom.h
> +++ b/target-s390x/cpu-qom.h
> @@ -32,6 +32,23 @@
> #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 */
> + uint64_t *fac_list; /* list of facilities */

Just make this uint64_t fac_list[2]. That way we don't have to track any
messy allocations.


Alex

2015-02-20 13:55:40

by Alexander Graf

[permalink] [raw]
Subject: Re: [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models



On 17.02.15 15:24, Michael Mueller wrote:
> 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 <[email protected]>
> Reviewed-by: Thomas Huth <[email protected]>
> ---
> qapi-schema.json | 11 +++++++
> target-s390x/Makefile.objs | 1 +
> target-s390x/cpu-models.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++
> target-s390x/cpu-models.h | 71 +++++++++++++++++++++++++++++++++++++++++
> target-s390x/cpu-qom.h | 22 +++++++++++++
> target-s390x/cpu.c | 2 ++
> 6 files changed, 186 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..4d237c8 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.0
> +##
> +{ 'enum': 'AccelId',
> + 'data': ['qtest', 'tcg', 'kvm', 'xen' ] }
> +
> ##
> # @CpuDefinitionInfo:
> #
> diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
> index 2c57494..9f55140 100644
> --- a/target-s390x/Makefile.objs
> +++ b/target-s390x/Makefile.objs
> @@ -1,5 +1,6 @@
> 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
> 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..4841553
> --- /dev/null
> +++ b/target-s390x/cpu-models.c
> @@ -0,0 +1,79 @@
> +/*
> + * CPU models for s390
> + *
> + * Copyright 2014,2015 IBM Corp.
> + *
> + * Author(s): Michael Mueller <[email protected]>
> + *
> + * 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 = g_malloc0(sizeof(S390CPUMachineProps)); \
> + cc->mach->ga = cpu_ga(_cpu_id); \
> + cc->mach->class = cpu_class(_cpu_id); \
> + cc->mach->order = cpu_order(_cpu_id); \
> + cc->proc = g_malloc0(sizeof(S390CPUProcessorProps)); \
> + 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 <[email protected]>
> + *
> + * 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..1332147 100644
> --- a/target-s390x/cpu-qom.h
> +++ b/target-s390x/cpu-qom.h
> @@ -32,6 +32,23 @@
> #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 */
> + uint64_t *fac_list; /* list of facilities */
> +} S390CPUProcessorProps;
> +
> /**
> * S390CPUClass:
> * @parent_realize: The parent class' realize handler.
> @@ -52,6 +69,11 @@ 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 */
> + uint64_t *fac_list; /* active facility list */
> + S390CPUMachineProps *mach; /* machine specific properties */
> + S390CPUProcessorProps *proc; /* processor specific properties */

Sorry, same here. Just put the structs straight into the class struct.


Alex

2015-02-20 13:59:25

by Alexander Graf

[permalink] [raw]
Subject: Re: [RFC PATCH v2 09/15] cpu-model/s390: Add KVM VM attribute interface routines



On 17.02.15 15:24, Michael Mueller wrote:
> 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 <[email protected]>
> ---
> 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 623a7b2..76b3456 100644
> --- a/target-s390x/cpu-models.h
> +++ b/target-s390x/cpu-models.h
> @@ -45,6 +45,45 @@ typedef struct S390CPUAlias {
> char *model;
> } S390CPUAlias;
>
> +typedef struct S390ProcessorProps {
> + uint64_t cpuid;
> + uint16_t ibc;
> + uint8_t pad[6];
> + uint64_t fac_list[S390_ARCH_FAC_LIST_SIZE_UINT64];
> +} S390ProcessorProps;
> +
> +typedef struct S390MachineProps {
> + uint64_t cpuid;
> + uint32_t ibc_range;
> + uint8_t pad[4];
> + uint64_t fac_list_mask[S390_ARCH_FAC_LIST_SIZE_UINT64];
> + uint64_t fac_list[S390_ARCH_FAC_LIST_SIZE_UINT64];
> +} S390MachineProps;

What are those structs there for? To convert between a kvm facing
interface to an internal interface?

I don't think they're necessary. The internal layout is visible from the
KVM code. Just either spawn the class straight from the kvm file or if
you consider that ugly, pass the values of that struct that you need as
function parameters to a function in cpu-models.c.


Alex

2015-02-20 14:03:35

by Alexander Graf

[permalink] [raw]
Subject: Re: [RFC PATCH v2 13/15] cpu-model/s390: Add processor property routines



On 17.02.15 15:24, Michael Mueller wrote:
> This patch implements the functions:
>
> - s390_get_proceccor_props()
> - s390_set_proceccor_props()
>
> They can be used to request or retrieve processor related information from an accelerator.
> That information comprises the cpu identifier, the ICB value and the facility lists.
>
> Signed-off-by: Michael Mueller <[email protected]>

Hrm, I still seem to miss the point of this interface. What do you need
it for?


Alex

2015-02-20 15:00:56

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models

On Fri, 20 Feb 2015 14:54:23 +0100
Alexander Graf <[email protected]> wrote:

> >
> > +/* 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 */
> > + uint64_t *fac_list; /* list of facilities */
>
> Just make this uint64_t fac_list[2]. That way we don't have to track any
> messy allocations.

It will be something like "uint64_t fac_list[S390_CPU_FAC_LIST_SIZE_UINT64]" and in total 2KB not
just 16 bytes but I will change it.


2015-02-20 15:02:34

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models

On Fri, 20 Feb 2015 14:55:32 +0100
Alexander Graf <[email protected]> wrote:

> > /**
> > * S390CPUClass:
> > * @parent_realize: The parent class' realize handler.
> > @@ -52,6 +69,11 @@ 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 */
> > + uint64_t *fac_list; /* active facility list */
> > + S390CPUMachineProps *mach; /* machine specific properties */
> > + S390CPUProcessorProps *proc; /* processor specific properties */
>
> Sorry, same here. Just put the structs straight into the class struct.

Yep, consistent.

2015-02-20 15:18:16

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 09/15] cpu-model/s390: Add KVM VM attribute interface routines

On Fri, 20 Feb 2015 14:59:20 +0100
Alexander Graf <[email protected]> wrote:

> > +typedef struct S390ProcessorProps {
> > + uint64_t cpuid;
> > + uint16_t ibc;
> > + uint8_t pad[6];
> > + uint64_t fac_list[S390_ARCH_FAC_LIST_SIZE_UINT64];
> > +} S390ProcessorProps;
> > +
> > +typedef struct S390MachineProps {
> > + uint64_t cpuid;
> > + uint32_t ibc_range;
> > + uint8_t pad[4];
> > + uint64_t fac_list_mask[S390_ARCH_FAC_LIST_SIZE_UINT64];
> > + uint64_t fac_list[S390_ARCH_FAC_LIST_SIZE_UINT64];
> > +} S390MachineProps;
>
> What are those structs there for? To convert between a kvm facing
> interface to an internal interface?

Yes, that's their current use, but if the interface structs:

+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];
+};

are visible here, I'll reuse them... But stop, that will not work in the
--disable-kvm case... I need them!
>
> I don't think they're necessary. The internal layout is visible from the
> KVM code. Just either spawn the class straight from the kvm file or if
> you consider that ugly, pass the values of that struct that you need as
> function parameters to a function in cpu-models.c.

2015-02-20 15:22:23

by Alexander Graf

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models




> Am 20.02.2015 um 16:00 schrieb Michael Mueller <[email protected]>:
>
> On Fri, 20 Feb 2015 14:54:23 +0100
> Alexander Graf <[email protected]> wrote:
>
>>>
>>> +/* 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 */
>>> + uint64_t *fac_list; /* list of facilities */
>>
>> Just make this uint64_t fac_list[2]. That way we don't have to track any
>> messy allocations.
>
> It will be something like "uint64_t fac_list[S390_CPU_FAC_LIST_SIZE_UINT64]" and in total 2KB not
> just 16 bytes but I will change it.

Why? Do we actually need that many? This is a qemu internal struct.

Alex-

2015-02-20 15:32:22

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 13/15] cpu-model/s390: Add processor property routines

On Fri, 20 Feb 2015 15:03:30 +0100
Alexander Graf <[email protected]> wrote:

> >
> > - s390_get_proceccor_props()
> > - s390_set_proceccor_props()
> >
> > They can be used to request or retrieve processor related information from an accelerator.
> > That information comprises the cpu identifier, the ICB value and the facility lists.
> >
> > Signed-off-by: Michael Mueller <[email protected]>
>
> Hrm, I still seem to miss the point of this interface. What do you need
> it for?

These functions make the internal s390 cpu model API independent from a specific accelerator:

int s390_set_processor_props(S390ProcessorProps *prop)
{
if (kvm_enabled()) {
return kvm_s390_set_processor_props(prop);
}
return -ENOSYS;
}

It's called by:

s390_select_cpu_model(const char *model)

which is itself called by:

S390CPU *cpu_s390x_init(const char *cpu_model)
{
S390CPU *cpu;

cpu = S390_CPU(object_new(s390_select_cpu_model(cpu_model)));

object_property_set_bool(OBJECT(cpu), true, "realized", NULL);

return cpu;
}

So above s390_set/get_processor_props() the code is accelerator independent.

Michael




2015-02-20 15:42:04

by Andreas Färber

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 13/15] cpu-model/s390: Add processor property routines

Am 20.02.2015 um 16:32 schrieb Michael Mueller:
> On Fri, 20 Feb 2015 15:03:30 +0100
> Alexander Graf <[email protected]> wrote:
>
>>>
>>> - s390_get_proceccor_props()
>>> - s390_set_proceccor_props()
>>>
>>> They can be used to request or retrieve processor related information from an accelerator.
>>> That information comprises the cpu identifier, the ICB value and the facility lists.
>>>
>>> Signed-off-by: Michael Mueller <[email protected]>
>>
>> Hrm, I still seem to miss the point of this interface. What do you need
>> it for?
>
> These functions make the internal s390 cpu model API independent from a specific accelerator:
>
> int s390_set_processor_props(S390ProcessorProps *prop)
> {
> if (kvm_enabled()) {
> return kvm_s390_set_processor_props(prop);
> }
> return -ENOSYS;
> }
>
> It's called by:
>
> s390_select_cpu_model(const char *model)
>
> which is itself called by:
>
> S390CPU *cpu_s390x_init(const char *cpu_model)
> {
> S390CPU *cpu;
>
> cpu = S390_CPU(object_new(s390_select_cpu_model(cpu_model)));
>
> object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
>
> return cpu;
> }
>
> So above s390_set/get_processor_props() the code is accelerator independent.

Can't you just implement the class-level name-to-ObjectClass callback
that other CPUs have grown for the above use case?

Also a general comment: cpu-model/ is not an existing directory nor one
you add, so please use "target-s390x: Add foo to S390CPU" or so.

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)

2015-02-20 15:50:03

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models

On Fri, 20 Feb 2015 16:22:20 +0100
Alexander Graf <[email protected]> wrote:

> >>
> >> Just make this uint64_t fac_list[2]. That way we don't have to track any
> >> messy allocations.
> >
> > It will be something like "uint64_t fac_list[S390_CPU_FAC_LIST_SIZE_UINT64]" and in total 2KB
> > not just 16 bytes but I will change it.
>
> Why? Do we actually need that many? This is a qemu internal struct.

How do you know that 2 is a good size?

I want to have this independent from a future machine of the z/Arch. The kernel stores the full
facility set, KVM does and there is no good reason for QEMU not to do. If other accelerators
decide to just implement 64 or 128 bits of facilities that's ok...

Michael

2015-02-20 16:02:49

by Richard Henderson

[permalink] [raw]
Subject: Re: [RFC PATCH v2 10/15] cpu-model/s390: Add cpu class initialization routines

On 02/17/2015 06:24 AM, Michael Mueller wrote:
> +/**
> + * s390_test_facility - test if given facility bit is set facility list
> + * of given cpu class
> + * @class: address of cpu class to test
> + * @nr: bit number to test
> + *
> + * Returns: true in case it is set
> + * false in case it is not set
> + */
> +bool s390_test_facility(S390CPUClass *cc, unsigned long nr)
> +{
> + if (cc) {
> + return test_facility(nr, cc->fac_list) ? true : false;
> + }
> + return false;
> +}

Where do you see this being used?


r~

2015-02-20 16:04:21

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 13/15] cpu-model/s390: Add processor property routines

On Fri, 20 Feb 2015 16:41:49 +0100
Andreas Färber <[email protected]> wrote:

> Can't you just implement the class-level name-to-ObjectClass callback
> that other CPUs have grown for the above use case?

If it fulfills the requirements sure. Please point me to an example, sounds that
s390_select_cpu_model() is doing something similar to that, just that it hooks in
the s390_set_processor_props() call.

const char *s390_select_cpu_model(const char *model)
{
S390ProcessorProps proc;
const char *typename;
S390CPUClass *cc;

/* return already selected cpu typename */
typename = s390_cpu_typename();
if (typename) {
goto out;
}

/* return standard cpu typename when cpu models are unavailable */
typename = TYPE_S390_CPU;
if (!s390_cpu_classes_initialized() || !model) {
goto out;
}
cc = S390_CPU_CLASS(s390_cpu_class_by_name(model));
if (!cc) {
goto out;
}
proc.cpuid = cpuid(cc->proc);
proc.ibc = cc->proc->ibc;
memcpy(proc.fac_list, cc->fac_list, S390_ARCH_FAC_LIST_SIZE_BYTE);
if (s390_set_processor_props(&proc)) {
goto out;
}

/* return requested cpu typename in success case */
typename = object_class_get_name((ObjectClass *) cc);
out:
selected_cpu_typename = typename;
trace_select_cpu_model(model, typename);
return typename;
}


>
> Also a general comment: cpu-model/ is not an existing directory nor one
> you add, so please use "target-s390x: Add foo to S390CPU" or so.

2015-02-20 16:05:58

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 13/15] cpu-model/s390: Add processor property routines

On Fri, 20 Feb 2015 16:41:49 +0100
Andreas Färber <[email protected]> wrote:

> Also a general comment: cpu-model/ is not an existing directory nor one
> you add, so please use "target-s390x: Add foo to S390CPU" or so.

I will address this with v3, thanks a lot for the hint, I never saw this as directories though...

Michael

2015-02-20 16:13:04

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 10/15] cpu-model/s390: Add cpu class initialization routines

On Fri, 20 Feb 2015 08:02:42 -0800
Richard Henderson <[email protected]> wrote:

> > +/**
> > + * s390_test_facility - test if given facility bit is set facility list
> > + * of given cpu class
> > + * @class: address of cpu class to test
> > + * @nr: bit number to test
> > + *
> > + * Returns: true in case it is set
> > + * false in case it is not set
> > + */
> > +bool s390_test_facility(S390CPUClass *cc, unsigned long nr)
> > +{
> > + if (cc) {
> > + return test_facility(nr, cc->fac_list) ? true : false;
> > + }
> > + return false;
> > +}
>
> Where do you see this being used?

Good spot, it's not being used yet. It's planned to be used with a patch that implements zPCI
related instructions on QEMU side. Maybe you have seen the discussion from Frank Blaschka in this
e-mail list in regard to that.

Michael

2015-02-20 16:27:39

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 10/15] cpu-model/s390: Add cpu class initialization routines

On Fri, 20 Feb 2015 17:12:49 +0100
Michael Mueller <[email protected]> wrote:

> Good spot, it's not being used yet. It's planned to be used with a patch that implements zPCI
> related instructions on QEMU side. Maybe you have seen the discussion from Frank Blaschka in
> this e-mail list in regard to that.

I will factor it out.

2015-02-20 16:28:32

by Andreas Färber

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 13/15] cpu-model/s390: Add processor property routines

Am 20.02.2015 um 17:04 schrieb Michael Mueller:
> On Fri, 20 Feb 2015 16:41:49 +0100
> Andreas Färber <[email protected]> wrote:
>
>> Can't you just implement the class-level name-to-ObjectClass callback
>> that other CPUs have grown for the above use case?
>
> If it fulfills the requirements sure. Please point me to an example,

Take a look at include/qom/cpu.h CPUClass::class_by_name and git-grep
the existing targets - most implement it already. It's a generic hook to
be used from everywhere rather than a local function specific to the
legacy init function. Apart from the error handling it should be
straight-forward.

> sounds that
> s390_select_cpu_model() is doing something similar to that, just that it hooks in
> the s390_set_processor_props() call.
>
> const char *s390_select_cpu_model(const char *model)
> {
> S390ProcessorProps proc;
> const char *typename;
> S390CPUClass *cc;
>
> /* return already selected cpu typename */
> typename = s390_cpu_typename();
> if (typename) {
> goto out;
> }
>
> /* return standard cpu typename when cpu models are unavailable */
> typename = TYPE_S390_CPU;
> if (!s390_cpu_classes_initialized() || !model) {
> goto out;
> }
> cc = S390_CPU_CLASS(s390_cpu_class_by_name(model));
> if (!cc) {
> goto out;
> }
> proc.cpuid = cpuid(cc->proc);
> proc.ibc = cc->proc->ibc;
> memcpy(proc.fac_list, cc->fac_list, S390_ARCH_FAC_LIST_SIZE_BYTE);
> if (s390_set_processor_props(&proc)) {
> goto out;
> }

Sorry for my ignorance, but what is proc actually needed for? For
initializing the class, there's .class_init (and cc->fac_list apparently
is initialized here). If you need to pass info to KVM, you can do so in
DeviceClass::realize when the vCPU actually goes "live". A
string-to-string (or string-to-ObjectClass) translation function seems
like a weird point in time to take action with global effect.

Anyway, please implement the generic callback, then you can still call
it from your own helper functions if needed.

Regards,
Andreas

>
> /* return requested cpu typename in success case */
> typename = object_class_get_name((ObjectClass *) cc);
> out:
> selected_cpu_typename = typename;
> trace_select_cpu_model(model, typename);
> return typename;
> }

--
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)

2015-02-20 16:34:41

by Andreas Färber

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 10/15] cpu-model/s390: Add cpu class initialization routines

Am 20.02.2015 um 17:12 schrieb Michael Mueller:
> On Fri, 20 Feb 2015 08:02:42 -0800
> Richard Henderson <[email protected]> wrote:
>
>>> +/**
>>> + * s390_test_facility - test if given facility bit is set facility list
>>> + * of given cpu class
>>> + * @class: address of cpu class to test
>>> + * @nr: bit number to test
>>> + *
>>> + * Returns: true in case it is set
>>> + * false in case it is not set
>>> + */

Please note that QEMU uses gtk-doc style, where the description goes
between arguments and Returns:, and the function name gets a ':'.
There's also fancy syntax like #CPUClass, %true, etc.

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)

2015-02-20 16:53:31

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 13/15] cpu-model/s390: Add processor property routines

On Fri, 20 Feb 2015 17:28:14 +0100
Andreas Färber <[email protected]> wrote:

Andreas,

> Sorry for my ignorance, but what is proc actually needed for? For
> initializing the class, there's .class_init (and cc->fac_list apparently
> is initialized here). If you need to pass info to KVM, you can do so in

yes, it is communication to the accelerator to prepare its local cpu model related data
structures which are used to initialize a vcpu (e.g. the facility list beside others)

> DeviceClass::realize when the vCPU actually goes "live". A

I will look what "goes live" in detail means here, it should at least be before
kvm_arch_vcpu_setup() gets triggered on accelerator side.

> string-to-string (or string-to-ObjectClass) translation function seems
> like a weird point in time to take action with global effect.
>
> Anyway, please implement the generic callback, then you can still call
> it from your own helper functions if needed.

Thanks a lot!
Michael

2015-02-20 16:56:06

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 10/15] cpu-model/s390: Add cpu class initialization routines

On Fri, 20 Feb 2015 17:34:28 +0100
Andreas Färber <[email protected]> wrote:

> Please note that QEMU uses gtk-doc style, where the description goes
> between arguments and Returns:, and the function name gets a ':'.
> There's also fancy syntax like #CPUClass, %true, etc.

On my TODOs...

Thanks,
Michael

2015-02-20 16:57:58

by Alexander Graf

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models



On 20.02.15 16:49, Michael Mueller wrote:
> On Fri, 20 Feb 2015 16:22:20 +0100
> Alexander Graf <[email protected]> wrote:
>
>>>>
>>>> Just make this uint64_t fac_list[2]. That way we don't have to track any
>>>> messy allocations.
>>>
>>> It will be something like "uint64_t fac_list[S390_CPU_FAC_LIST_SIZE_UINT64]" and in total 2KB
>>> not just 16 bytes but I will change it.
>>
>> Why? Do we actually need that many? This is a qemu internal struct.
>
> How do you know that 2 is a good size?

Because all CPUs we have in our list only expose 128 bits?

> I want to have this independent from a future machine of the z/Arch. The kernel stores the full
> facility set, KVM does and there is no good reason for QEMU not to do. If other accelerators
> decide to just implement 64 or 128 bits of facilities that's ok...

So you want to support CPUs that are not part of the list?


Alex

2015-02-20 16:59:19

by Alexander Graf

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 09/15] cpu-model/s390: Add KVM VM attribute interface routines



On 20.02.15 16:18, Michael Mueller wrote:
> On Fri, 20 Feb 2015 14:59:20 +0100
> Alexander Graf <[email protected]> wrote:
>
>>> +typedef struct S390ProcessorProps {
>>> + uint64_t cpuid;
>>> + uint16_t ibc;
>>> + uint8_t pad[6];
>>> + uint64_t fac_list[S390_ARCH_FAC_LIST_SIZE_UINT64];
>>> +} S390ProcessorProps;
>>> +
>>> +typedef struct S390MachineProps {
>>> + uint64_t cpuid;
>>> + uint32_t ibc_range;
>>> + uint8_t pad[4];
>>> + uint64_t fac_list_mask[S390_ARCH_FAC_LIST_SIZE_UINT64];
>>> + uint64_t fac_list[S390_ARCH_FAC_LIST_SIZE_UINT64];
>>> +} S390MachineProps;
>>
>> What are those structs there for? To convert between a kvm facing
>> interface to an internal interface?
>
> Yes, that's their current use, but if the interface structs:
>
> +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];
> +};
>
> are visible here, I'll reuse them... But stop, that will not work in the
> --disable-kvm case... I need them!

I meant it the other way around - do KVM specific patching of the cpu
types from kvm.c.

But please give a nutshell explanation on what exactly you're patching
at all here.


Alex

2015-02-20 17:00:24

by Alexander Graf

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 13/15] cpu-model/s390: Add processor property routines



On 20.02.15 16:32, Michael Mueller wrote:
> On Fri, 20 Feb 2015 15:03:30 +0100
> Alexander Graf <[email protected]> wrote:
>
>>>
>>> - s390_get_proceccor_props()
>>> - s390_set_proceccor_props()
>>>
>>> They can be used to request or retrieve processor related information from an accelerator.
>>> That information comprises the cpu identifier, the ICB value and the facility lists.
>>>
>>> Signed-off-by: Michael Mueller <[email protected]>
>>
>> Hrm, I still seem to miss the point of this interface. What do you need
>> it for?
>
> These functions make the internal s390 cpu model API independent from a specific accelerator:
>
> int s390_set_processor_props(S390ProcessorProps *prop)
> {
> if (kvm_enabled()) {
> return kvm_s390_set_processor_props(prop);
> }
> return -ENOSYS;
> }
>
> It's called by:
>
> s390_select_cpu_model(const char *model)
>
> which is itself called by:
>
> S390CPU *cpu_s390x_init(const char *cpu_model)
> {
> S390CPU *cpu;
>
> cpu = S390_CPU(object_new(s390_select_cpu_model(cpu_model)));
>
> object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
>
> return cpu;
> }
>
> So above s390_set/get_processor_props() the code is accelerator independent.

Any particular reason you can't do it like PPC?


Alex

2015-02-20 17:38:08

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models

On Fri, 20 Feb 2015 17:57:52 +0100
Alexander Graf <[email protected]> wrote:

> Because all CPUs we have in our list only expose 128 bits?

Here a STFLE result on a EC12 GA2, already more than 128 bits... Is that model on the list?

[mimu@p57lp59 s390xfac]$ ./s390xfac -b
fac[0] = 0xfbfffffbfcfff840
fac[1] = 0xffde000000000000
fac[2] = 0x1800000000000000
>
> > I want to have this independent from a future machine of the z/Arch. The kernel stores the
> > full facility set, KVM does and there is no good reason for QEMU not to do. If other
> > accelerators decide to just implement 64 or 128 bits of facilities that's ok...
>
> So you want to support CPUs that are not part of the list?

The architecture at least defines more than 2 or 3. Do you want me to limit it to an arbitrary
size?. Only in QEMU or also in the KVM interface?

Thanks
Michael

2015-02-20 17:50:22

by Alexander Graf

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models




> Am 20.02.2015 um 18:37 schrieb Michael Mueller <[email protected]>:
>
> On Fri, 20 Feb 2015 17:57:52 +0100
> Alexander Graf <[email protected]> wrote:
>
>> Because all CPUs we have in our list only expose 128 bits?
>
> Here a STFLE result on a EC12 GA2, already more than 128 bits... Is that model on the list?

If that model has 3 elements, yes, the array should span 3.

I hope it's in the list. Every model wecare about should be, no?

>
> [mimu@p57lp59 s390xfac]$ ./s390xfac -b
> fac[0] = 0xfbfffffbfcfff840
> fac[1] = 0xffde000000000000
> fac[2] = 0x1800000000000000
>>
>>> I want to have this independent from a future machine of the z/Arch. The kernel stores the
>>> full facility set, KVM does and there is no good reason for QEMU not to do. If other
>>> accelerators decide to just implement 64 or 128 bits of facilities that's ok...
>>
>> So you want to support CPUs that are not part of the list?
>
> The architecture at least defines more than 2 or 3. Do you want me to limit it to an arbitrary
> size?. Only in QEMU or also in the KVM interface?

Only internally in QEMU. The kvm interface should definitely be as big as the spec allows!

Alex

>
> Thanks
> Michael
>

2015-02-20 18:12:03

by Richard Henderson

[permalink] [raw]
Subject: Re: [RFC PATCH v2 10/15] cpu-model/s390: Add cpu class initialization routines

On 02/17/2015 06:24 AM, Michael Mueller wrote:
> +static inline uint64_t big_endian_bit(unsigned long nr)
> +{
> + return 1ul << (BITS_PER_LONG - (nr % BITS_PER_LONG));
> +};

This is buggy. NR=0 should map to 63, not 64.

> + return !!(*ptr & big_endian_bit(nr));

Personally I dislike !! as an idiom. Given that big_endian_bit isn't used
anywhere else, can we integrate it and change this to

static inline int test_facility(unsigned long nr, uint64_t *fac_list)
{
unsigned long word = nr / BITS_PER_LONG;
unsigned long be_bit = 63 - (nr % BITS_PER_LONG);
return (fac_list[word] >> be_bit) & 1;
}


r~

2015-02-20 18:42:28

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 09/15] cpu-model/s390: Add KVM VM attribute interface routines

On Fri, 20 Feb 2015 17:59:14 +0100
Alexander Graf <[email protected]> wrote:

> But please give a nutshell explanation on what exactly you're patching
> at all here.

Please don't ask in riddles... :-)

S390ProcessorProps are attributes that represent cpu model related properties of the processor.

typedef struct S390ProcessorProps {
uint64_t cpuid;
uint16_t ibc;
uint8_t pad[6];
uint64_t fac_list[S390_ARCH_FAC_LIST_SIZE_UINT64];
} S390ProcessorProps;

S390MachineProps are attributes that represent cpu model related properties that a specific host
offers.

fac_list_mask are the facilities that are supported by the accelerator code and the hosting
machine in case of KVM it is kvm_s390_fac_list_mask & STFLE, fac_list is STFLE only

typedef struct S390MachineProps {
uint64_t cpuid;
uint32_t ibc_range;
uint8_t pad[4];
uint64_t fac_list_mask[S390_ARCH_FAC_LIST_SIZE_UINT64];
uint64_t fac_list[S390_ARCH_FAC_LIST_SIZE_UINT64];
} S390MachineProps;

The various S390CPUModel classes represent all well defined cpu models (those which have been
implemented as real machines). Not all of these models are executable on a given host. Only the
most current machine implementation is able to run all models. The list of "runnable" cpu models
is calculated by "matching" the S390MachineProps with the S390CPUModel classes and the
qemu_s390_fac_list_mask[] (indicates the facilities that are implemented by QEMU itself.)

The qemu cpu_model is translated to the respective S390CPUModel class and its processor
properties (S390ProcessorProps) are used with the s390_set_proceccor_props() call to communicate
them to the accelerator what specific cpuid,ibc,fac_list shall be used.

Michael

2015-02-20 18:59:39

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 10/15] cpu-model/s390: Add cpu class initialization routines

On Fri, 20 Feb 2015 10:11:55 -0800
Richard Henderson <[email protected]> wrote:

> > +static inline uint64_t big_endian_bit(unsigned long nr)
> > +{
> > + return 1ul << (BITS_PER_LONG - (nr % BITS_PER_LONG));
> > +};
>
> This is buggy. NR=0 should map to 63, not 64.

I'm sure I was asked to replace my constant 64 and 63 with that defines and at the end I messed
it up... :-(

>
> > + return !!(*ptr & big_endian_bit(nr));
>
> Personally I dislike !! as an idiom. Given that big_endian_bit isn't used
> anywhere else, can we integrate it and change this to
>
> static inline int test_facility(unsigned long nr, uint64_t *fac_list)
> {
> unsigned long word = nr / BITS_PER_LONG;
> unsigned long be_bit = 63 - (nr % BITS_PER_LONG);
> return (fac_list[word] >> be_bit) & 1;
> }

Yes, I just use it in this context. I will integrate your version.

BTW I changed the whole facility defining code to be generated by an external helper at compile
time. That is more simple and safe to change. I will send it with v3. See attachment for an
example of the generated header file.

Thanks,
Michael


Attachments:
(No filename) (1.08 kB)
gen-facilities.h (2.39 kB)
Download all attachments

2015-02-20 19:21:46

by Alexander Graf

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 10/15] cpu-model/s390: Add cpu class initialization routines




> Am 20.02.2015 um 19:59 schrieb Michael Mueller <[email protected]>:
>
> On Fri, 20 Feb 2015 10:11:55 -0800
> Richard Henderson <[email protected]> wrote:
>
>>> +static inline uint64_t big_endian_bit(unsigned long nr)
>>> +{
>>> + return 1ul << (BITS_PER_LONG - (nr % BITS_PER_LONG));
>>> +};
>>
>> This is buggy. NR=0 should map to 63, not 64.
>
> I'm sure I was asked to replace my constant 64 and 63 with that defines and at the end I messed
> it up... :-(
>
>>
>>> + return !!(*ptr & big_endian_bit(nr));
>>
>> Personally I dislike !! as an idiom. Given that big_endian_bit isn't used
>> anywhere else, can we integrate it and change this to
>>
>> static inline int test_facility(unsigned long nr, uint64_t *fac_list)
>> {
>> unsigned long word = nr / BITS_PER_LONG;
>> unsigned long be_bit = 63 - (nr % BITS_PER_LONG);
>> return (fac_list[word] >> be_bit) & 1;
>> }
>
> Yes, I just use it in this context. I will integrate your version.
>
> BTW I changed the whole facility defining code to be generated by an external helper at compile
> time. That is more simple and safe to change. I will send it with v3. See attachment for an
> example of the generated header file.

Please make sure to use ULL with constants and uint64_t on variables. Long is almost always wrong in QEMU.

Alex

>
> Thanks,
> Michael
>
> <gen-facilities.h>

2015-02-20 19:29:50

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 13/15] cpu-model/s390: Add processor property routines

On Fri, 20 Feb 2015 18:00:19 +0100
Alexander Graf <[email protected]> wrote:

> > So above s390_set/get_processor_props() the code is accelerator independent.
>
> Any particular reason you can't do it like PPC?

That seems to be a short question... and when I started one year ago, I oriented myself on
the PPC version and I'm also willing to revisit it but I can't give you a quick answer different
from no currently to that.

There are no PVRs for s390x CPUs and thus I came up with "pseudo PVRs":

/*
* 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,
CPU_S390_2964_GA1 = 0x0d112964,
};

And initially I had a version that was limiting the accelerator to be able to implement just them
with all their properties encapsulated in the a accelerator as well. After identifying the real
processor related attributes defining the model, I changed the interface such that KVM or
other accelerators give hints what it is able to support in dependency of the current code
version and the hosting machine and let QEMU decide how to set these attributes
(cpuid,ibc,fac_list). Thus I think the implementation is now quite open and easily adoptable also
for TCG and possibly others as well. Eventually the integration and also some trigger points of
my code are to adjust. So coming back to your question, the answer is still no for the whole item
but eventually yes if you have limited it to the s390_set/get_processor_props() triggers. But I
have to look into it first again. I will do that when I'm back on Tuesday morning.

Thanks and have a nice WE
Michael

2015-02-20 19:35:18

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 10/15] cpu-model/s390: Add cpu class initialization routines

On Fri, 20 Feb 2015 20:21:45 +0100
Alexander Graf <[email protected]> wrote:

>
>
>
> > Am 20.02.2015 um 19:59 schrieb Michael Mueller <[email protected]>:
> >
> > On Fri, 20 Feb 2015 10:11:55 -0800
> > Richard Henderson <[email protected]> wrote:
> >
> >>> +static inline uint64_t big_endian_bit(unsigned long nr)
> >>> +{
> >>> + return 1ul << (BITS_PER_LONG - (nr % BITS_PER_LONG));
> >>> +};
> >>
> >> This is buggy. NR=0 should map to 63, not 64.
> >
> > I'm sure I was asked to replace my constant 64 and 63 with that defines and at the end I
> > messed it up... :-(
> >
> >>
> >>> + return !!(*ptr & big_endian_bit(nr));
> >>
> >> Personally I dislike !! as an idiom. Given that big_endian_bit isn't used
> >> anywhere else, can we integrate it and change this to
> >>
> >> static inline int test_facility(unsigned long nr, uint64_t *fac_list)
> >> {
> >> unsigned long word = nr / BITS_PER_LONG;
> >> unsigned long be_bit = 63 - (nr % BITS_PER_LONG);
> >> return (fac_list[word] >> be_bit) & 1;
> >> }
> >
> > Yes, I just use it in this context. I will integrate your version.
> >
> > BTW I changed the whole facility defining code to be generated by an external helper at
> > compile time. That is more simple and safe to change. I will send it with v3. See attachment
> > for an example of the generated header file.
>
> Please make sure to use ULL with constants and uint64_t on variables. Long is almost always
> wrong in QEMU.

yep

>
> Alex
>
> >
> > Thanks,
> > Michael
> >
> > <gen-facilities.h>
>

2015-02-20 19:43:14

by Michael Mueller

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models

On Fri, 20 Feb 2015 18:50:20 +0100
Alexander Graf <[email protected]> wrote:

>
>
>
> > Am 20.02.2015 um 18:37 schrieb Michael Mueller <[email protected]>:
> >
> > On Fri, 20 Feb 2015 17:57:52 +0100
> > Alexander Graf <[email protected]> wrote:
> >
> >> Because all CPUs we have in our list only expose 128 bits?
> >
> > Here a STFLE result on a EC12 GA2, already more than 128 bits... Is that model on the list?
>
> If that model has 3 elements, yes, the array should span 3.
>
> I hope it's in the list. Every model wecare about should be, no?
>

On my list? Yes!

> >
> > [mimu@p57lp59 s390xfac]$ ./s390xfac -b
> > fac[0] = 0xfbfffffbfcfff840
> > fac[1] = 0xffde000000000000
> > fac[2] = 0x1800000000000000
> >>
> >>> I want to have this independent from a future machine of the z/Arch. The kernel stores the
> >>> full facility set, KVM does and there is no good reason for QEMU not to do. If other
> >>> accelerators decide to just implement 64 or 128 bits of facilities that's ok...
> >>
> >> So you want to support CPUs that are not part of the list?
> >
> > The architecture at least defines more than 2 or 3. Do you want me to limit it to an arbitrary
> > size?. Only in QEMU or also in the KVM interface?
>
> Only internally in QEMU. The kvm interface should definitely be as big as the spec allows!

Right, now we're on the same page again. That can be taken in consideration. ... Although it's
just and optimization. :-)

Michael

>
> Alex
>
> >
> > Thanks
> > Michael
> >
>

2015-02-20 19:55:17

by Alexander Graf

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models



On 20.02.15 20:43, Michael Mueller wrote:
> On Fri, 20 Feb 2015 18:50:20 +0100
> Alexander Graf <[email protected]> wrote:
>
>>
>>
>>
>>> Am 20.02.2015 um 18:37 schrieb Michael Mueller <[email protected]>:
>>>
>>> On Fri, 20 Feb 2015 17:57:52 +0100
>>> Alexander Graf <[email protected]> wrote:
>>>
>>>> Because all CPUs we have in our list only expose 128 bits?
>>>
>>> Here a STFLE result on a EC12 GA2, already more than 128 bits... Is that model on the list?
>>
>> If that model has 3 elements, yes, the array should span 3.
>>
>> I hope it's in the list. Every model wecare about should be, no?
>>
>
> On my list? Yes!
>
>>>
>>> [mimu@p57lp59 s390xfac]$ ./s390xfac -b
>>> fac[0] = 0xfbfffffbfcfff840
>>> fac[1] = 0xffde000000000000
>>> fac[2] = 0x1800000000000000
>>>>
>>>>> I want to have this independent from a future machine of the z/Arch. The kernel stores the
>>>>> full facility set, KVM does and there is no good reason for QEMU not to do. If other
>>>>> accelerators decide to just implement 64 or 128 bits of facilities that's ok...
>>>>
>>>> So you want to support CPUs that are not part of the list?
>>>
>>> The architecture at least defines more than 2 or 3. Do you want me to limit it to an arbitrary
>>> size?. Only in QEMU or also in the KVM interface?
>>
>> Only internally in QEMU. The kvm interface should definitely be as big as the spec allows!
>
> Right, now we're on the same page again. That can be taken in consideration. ... Although it's
> just and optimization. :-)

Yeah. You could also consider using the QEMU built-in bitmap type and
functions and just convert from there. That would give you native
support for bit values > 64.


Alex

2015-02-23 12:57:06

by Christian Borntraeger

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models

Am 20.02.2015 um 16:22 schrieb Alexander Graf:
>
>
>
>> Am 20.02.2015 um 16:00 schrieb Michael Mueller <[email protected]>:
>>
>> On Fri, 20 Feb 2015 14:54:23 +0100
>> Alexander Graf <[email protected]> wrote:
>>
>>>>
>>>> +/* 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 */
>>>> + uint64_t *fac_list; /* list of facilities */
>>>
>>> Just make this uint64_t fac_list[2]. That way we don't have to track any
>>> messy allocations.
>>
>> It will be something like "uint64_t fac_list[S390_CPU_FAC_LIST_SIZE_UINT64]" and in total 2KB not
>> just 16 bytes but I will change it.
>
> Why? Do we actually need that many? This is a qemu internal struct.

The kernel already enabled the 3rd word for z13 support,
https://git.kernel.org/cgit/linux/kernel/git/s390/linux.git/commit/?id=f8b2dcbd9e6d1479b9b5a9e9e78bbaf783bde819

so make it at least 3.

2015-02-23 13:27:25

by Christian Borntraeger

[permalink] [raw]
Subject: Re: [Qemu-devel] [RFC PATCH v2 04/15] cpu-model/s390: Introduce S390 CPU models

Am 23.02.2015 um 13:56 schrieb Christian Borntraeger:
> Am 20.02.2015 um 16:22 schrieb Alexander Graf:
>>
>>
>>
>>> Am 20.02.2015 um 16:00 schrieb Michael Mueller <[email protected]>:
>>>
>>> On Fri, 20 Feb 2015 14:54:23 +0100
>>> Alexander Graf <[email protected]> wrote:
>>>
>>>>>
>>>>> +/* 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 */
>>>>> + uint64_t *fac_list; /* list of facilities */
>>>>
>>>> Just make this uint64_t fac_list[2]. That way we don't have to track any
>>>> messy allocations.
>>>
>>> It will be something like "uint64_t fac_list[S390_CPU_FAC_LIST_SIZE_UINT64]" and in total 2KB not
>>> just 16 bytes but I will change it.
>>
>> Why? Do we actually need that many? This is a qemu internal struct.
>
> The kernel already enabled the 3rd word for z13 support,
> https://git.kernel.org/cgit/linux/kernel/git/s390/linux.git/commit/?id=f8b2dcbd9e6d1479b9b5a9e9e78bbaf783bde819
>
> so make it at least 3.


This should have been

commit 8070361799ae1e3f4ef347bd10f0a508ac10acfb
Author: Martin Schwidefsky <[email protected]>
Date: Mon Oct 6 17:53:53 2014 +0200

s390: add support for vector extension

which uses bit 129.