* [Qemu-devel] [PATCH v1 RFC 00/10] QEMU: s390: cpu model implementation
@ 2014-05-13 15:00 Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 01/10] QEMU: introduce function cpudesc_avail Michael Mueller
` (9 more replies)
0 siblings, 10 replies; 13+ messages in thread
From: Michael Mueller @ 2014-05-13 15:00 UTC (permalink / raw)
To: qemu-devel, kvm, linux-s390, linux-kernel
Cc: mimu, Gleb Natapov, Alexander Graf, Christian Borntraeger,
Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
Richard Henderson
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.
Michael Mueller (10):
QEMU: introduce function cpudesc_avail
QEMU: s390: cpu model cpu class definition
QEMU: s390: cpu model facilities support
QEMU: s390: cpu model alias support
s390: update linux-headers for kvm VM device attributes
QEMU: s390: cpu model kvm VM attr interface routines
QEMU: s390: cpu model class initialization
QEMU: s390: cpu model QMP query-cpu-definitions
QEMU: s390: cpu model QMP query-cpu-model
QEMU: s390: cpu model enablement
arch_init.c | 8 +
hw/s390x/s390-virtio-ccw.c | 2 +
hw/s390x/s390-virtio.c | 104 ++++++++
hw/s390x/s390-virtio.h | 1 +
include/sysemu/arch_init.h | 2 +
linux-headers/asm-s390/kvm.h | 26 ++
linux-headers/linux/kvm.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/Makefile.objs | 1 +
target-s390x/cpu-models.c | 586 +++++++++++++++++++++++++++++++++++++++++++
target-s390x/cpu-models.h | 362 ++++++++++++++++++++++++++
target-s390x/cpu-qom.h | 22 ++
target-s390x/cpu.c | 171 ++++++++++++-
target-s390x/cpu.h | 3 +
target-s390x/kvm.c | 66 +++++
vl.c | 2 +-
20 files changed, 1395 insertions(+), 6 deletions(-)
create mode 100644 stubs/arch-query-cpu-mod.c
create mode 100644 target-s390x/cpu-models.c
create mode 100644 target-s390x/cpu-models.h
--
1.8.3.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v1 RFC 01/10] QEMU: introduce function cpudesc_avail
2014-05-13 15:00 [Qemu-devel] [PATCH v1 RFC 00/10] QEMU: s390: cpu model implementation Michael Mueller
@ 2014-05-13 15:00 ` Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 02/10] QEMU: s390: cpu model cpu class definition Michael Mueller
` (8 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Michael Mueller @ 2014-05-13 15:00 UTC (permalink / raw)
To: qemu-devel, kvm, linux-s390, linux-kernel
Cc: mimu, Gleb Natapov, Alexander Graf, Christian Borntraeger,
Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
Richard Henderson
This patch introduces the function cpudesc_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.
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
arch_init.c | 8 ++++++++
include/sysemu/arch_init.h | 1 +
vl.c | 2 +-
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch_init.c b/arch_init.c
index 995f56d..207d720 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -1346,6 +1346,14 @@ int xen_available(void)
#endif
}
+bool cpudesc_avail(void)
+{
+ bool is_avail = true;
+#if defined(cpudesc_ready)
+ is_avail = cpudesc_ready();
+#endif
+ return is_avail;
+}
TargetInfo *qmp_query_target(Error **errp)
{
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 182d48d..cadcedc 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -35,6 +35,7 @@ void audio_init(void);
int tcg_available(void);
int kvm_available(void);
int xen_available(void);
+bool cpudesc_avail(void);
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp);
diff --git a/vl.c b/vl.c
index 73e0661..ddd98f7 100644
--- a/vl.c
+++ b/vl.c
@@ -4009,7 +4009,7 @@ int main(int argc, char **argv, char **envp)
*/
cpudef_init();
- if (cpu_model && is_help_option(cpu_model)) {
+ if (cpudesc_avail() && cpu_model && is_help_option(cpu_model)) {
list_cpus(stdout, &fprintf, cpu_model);
exit(0);
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v1 RFC 02/10] QEMU: s390: cpu model cpu class definition
2014-05-13 15:00 [Qemu-devel] [PATCH v1 RFC 00/10] QEMU: s390: cpu model implementation Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 01/10] QEMU: introduce function cpudesc_avail Michael Mueller
@ 2014-05-13 15:00 ` Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 03/10] QEMU: s390: cpu model facilities support Michael Mueller
` (7 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Michael Mueller @ 2014-05-13 15:00 UTC (permalink / raw)
To: qemu-devel, kvm, linux-s390, linux-kernel
Cc: mimu, Gleb Natapov, Alexander Graf, Christian Borntraeger,
Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
Richard Henderson
This patch implements the static part of the s390 cpu class definitions.
It defines single cpu models by means of virtual cpu ids 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
id.
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
target-s390x/Makefile.objs | 1 +
target-s390x/cpu-models.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++
target-s390x/cpu-models.h | 67 +++++++++++++++++++++++++++++++++++++
target-s390x/cpu-qom.h | 22 +++++++++++++
target-s390x/cpu.c | 2 ++
5 files changed, 174 insertions(+)
create mode 100644 target-s390x/cpu-models.c
create mode 100644 target-s390x/cpu-models.h
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index f873146..6a38ce9 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) += 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..8f1fa64
--- /dev/null
+++ b/target-s390x/cpu-models.c
@@ -0,0 +1,82 @@
+/*
+ * CPU models for s390
+ *
+ * Copyright 2014 IBM Corp.
+ *
+ * Author(s): Michael Mueller <mimu@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include "cpu.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 = true; \
+ cc->is_host = false; \
+ cc->fac_list = NULL; \
+ 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; \
+ cc->proc->fac_list = NULL; \
+ 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..4abd39a
--- /dev/null
+++ b/target-s390x/cpu-models.h
@@ -0,0 +1,67 @@
+/*
+ * CPU models for s390
+ *
+ * Copyright 2014 IBM Corp.
+ *
+ * Author(s): Michael Mueller <mimu@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#ifndef TARGET_S390X_CPU_MODELS_H
+#define TARGET_S390X_CPU_MODELS_H
+
+#define S390_EC 0x1
+#define S390_BC 0x2
+
+#define S390_DEF_VERSION 0xff
+#define S390_DEF_IBC 0x0
+#define S390_DEF_ID 0xdecade
+
+#define 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
+ */
+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 ac0460e..c34bce5 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; /* true if cpu class supported by host */
+ bool is_host; /* true if cpu class respresents "host" */
+ 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 dfd83e8..7fa588c 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -256,6 +256,8 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
#endif
dc->vmsd = &vmstate_s390_cpu;
cc->gdb_num_core_regs = S390_NUM_REGS;
+ 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
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v1 RFC 03/10] QEMU: s390: cpu model facilities support
2014-05-13 15:00 [Qemu-devel] [PATCH v1 RFC 00/10] QEMU: s390: cpu model implementation Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 01/10] QEMU: introduce function cpudesc_avail Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 02/10] QEMU: s390: cpu model cpu class definition Michael Mueller
@ 2014-05-13 15:00 ` Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 04/10] QEMU: s390: cpu model alias support Michael Mueller
` (6 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Michael Mueller @ 2014-05-13 15:00 UTC (permalink / raw)
To: qemu-devel, kvm, linux-s390, linux-kernel
Cc: mimu, Gleb Natapov, Alexander Graf, Christian Borntraeger,
Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
Richard Henderson
This patch defines S390 cpu facilities and their presence at the
different cpu model levels. The implemented functions allow to
calculate cpu model specific facility sets. These sets are associated
to the defined cpu classes used to calculate the list of supported
cpu models.
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
target-s390x/cpu-models.c | 27 +++++-
target-s390x/cpu-models.h | 234 ++++++++++++++++++++++++++++++++++++++++++++++
target-s390x/cpu.c | 3 +
3 files changed, 262 insertions(+), 2 deletions(-)
diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index 8f1fa64..e437bd0 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -13,6 +13,9 @@
#include "cpu.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) \
@@ -23,7 +26,7 @@
\
cc->is_active = true; \
cc->is_host = false; \
- cc->fac_list = NULL; \
+ 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); \
@@ -34,7 +37,9 @@
cc->proc->id = S390_DEF_ID; \
cc->proc->type = cpu_type(_cpu_id); \
cc->proc->ibc = S390_DEF_IBC; \
- cc->proc->fac_list = NULL; \
+ 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 \
@@ -80,3 +85,21 @@ 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")
+
+static inline unsigned long bit_in_word(unsigned int nr)
+{
+ return 1ul << (__WORDSIZE - 1 - (nr % __WORDSIZE));
+};
+
+/* test a specific bit in facility set to be set */
+static inline int test_facility(unsigned long nr, unsigned long *fac_list)
+{
+ unsigned long *ptr;
+
+ if (nr >= S390_FAC_LIST_SIZE_BIT) {
+ return 0;
+ }
+ ptr = fac_list + (nr / __WORDSIZE);
+
+ return (*ptr & bit_in_word(nr)) != 0;
+}
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index 4abd39a..6f9a1a1 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -13,6 +13,20 @@
#ifndef TARGET_S390X_CPU_MODELS_H
#define TARGET_S390X_CPU_MODELS_H
+#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)
+
+/* maximum size of facilities and facility mask is 2k bytes */
+#define S390_ARCH_FAC_LIST_SIZE_BYTE 2048
+#define S390_ARCH_FAC_LIST_SIZE_UINT64 \
+ (S390_ARCH_FAC_LIST_SIZE_BYTE / sizeof(uint64_t))
+#define S390_ARCH_FAC_MASK_SIZE_BYTE S390_ARCH_FAC_LIST_SIZE_BYTE
+#define S390_ARCH_FAC_MASK_SIZE_UINT64 \
+ (S390_ARCH_FAC_MASK_SIZE_BYTE / sizeof(uint64_t))
+
#define S390_EC 0x1
#define S390_BC 0x2
@@ -20,6 +34,9 @@
#define S390_DEF_IBC 0x0
#define S390_DEF_ID 0xdecade
+#define FAC_BIT(WORD, BIT) \
+ (BIT / 64 == WORD ? 1ull << (63 - BIT % 64) : 0)
+
#define cpu_type(x) (((x) >> 0) & 0xffff)
#define cpu_order(x) (((x) >> 16) & 0xffff)
#define cpu_ga(x) (((x) >> 16) & 0xf)
@@ -64,4 +81,221 @@ enum {
CPU_S390_2828_GA1 = 0x0c212828,
};
+/* S390 CPU facilities */
+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;
+
+/* 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 0ul
+
+#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
+
#endif
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 7fa588c..10a03f9 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -24,6 +24,7 @@
*/
#include "cpu.h"
+#include "cpu-models.h"
#include "qemu-common.h"
#include "qemu/timer.h"
#include "hw/hw.h"
@@ -258,6 +259,8 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_num_core_regs = S390_NUM_REGS;
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
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v1 RFC 04/10] QEMU: s390: cpu model alias support
2014-05-13 15:00 [Qemu-devel] [PATCH v1 RFC 00/10] QEMU: s390: cpu model implementation Michael Mueller
` (2 preceding siblings ...)
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 03/10] QEMU: s390: cpu model facilities support Michael Mueller
@ 2014-05-13 15:00 ` Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 05/10] s390: update linux-headers for kvm VM device attributes Michael Mueller
` (5 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Michael Mueller @ 2014-05-13 15:00 UTC (permalink / raw)
To: qemu-devel, kvm, linux-s390, linux-kernel
Cc: mimu, Gleb Natapov, Alexander Graf, Christian Borntraeger,
Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
Richard Henderson
This patch implements the infrastructure to dynamically add cpu model aliases.
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
target-s390x/cpu-models.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++
target-s390x/cpu-models.h | 12 +++++++++
2 files changed, 76 insertions(+)
diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index e437bd0..25147a4 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -86,6 +86,9 @@ 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")
+/* S390 CPU aliases can be added dynamically to this list */
+GSList *s390_cpu_aliases;
+
static inline unsigned long bit_in_word(unsigned int nr)
{
return 1ul << (__WORDSIZE - 1 - (nr % __WORDSIZE));
@@ -103,3 +106,64 @@ static inline int test_facility(unsigned long nr, unsigned long *fac_list)
return (*ptr & bit_in_word(nr)) != 0;
}
+
+static gint s390_cpu_compare_class_name(gconstpointer a, gconstpointer b)
+{
+ ObjectClass *oc = (ObjectClass *)a;
+ const char *name = b;
+
+ if (strncasecmp(name, object_class_get_name(oc), strlen(name)) == 0 &&
+ strcmp(object_class_get_name(oc) + strlen(name),
+ "-" TYPE_S390_CPU) == 0) {
+ return 0;
+ }
+
+ return -1;
+}
+
+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;
+}
+
+/* define a new s390 cpu alias */
+int set_s390_cpu_alias(const char *name, const char *model)
+{
+ S390CPUAlias *alias;
+
+ if (!name || !model) {
+ return -EINVAL;
+ }
+ if (!g_strcmp0(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 6f9a1a1..f5c8112 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -43,6 +43,18 @@
#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;
+extern GSList *s390_cpu_aliases;
+
/*
* bits 0-7 : CMOS generation
* bits 8-9 : reserved
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v1 RFC 05/10] s390: update linux-headers for kvm VM device attributes
2014-05-13 15:00 [Qemu-devel] [PATCH v1 RFC 00/10] QEMU: s390: cpu model implementation Michael Mueller
` (3 preceding siblings ...)
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 04/10] QEMU: s390: cpu model alias support Michael Mueller
@ 2014-05-13 15:00 ` Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 06/10] QEMU: s390: cpu model kvm VM attr interface routines Michael Mueller
` (4 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Michael Mueller @ 2014-05-13 15:00 UTC (permalink / raw)
To: qemu-devel, kvm, linux-s390, linux-kernel
Cc: mimu, Gleb Natapov, Alexander Graf, Christian Borntraeger,
Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
Richard Henderson
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
| 26 ++++++++++++++++++++++++++
| 1 +
2 files changed, 27 insertions(+)
--git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
index c003c6a..2fba454 100644
--- a/linux-headers/asm-s390/kvm.h
+++ b/linux-headers/asm-s390/kvm.h
@@ -54,6 +54,32 @@ struct kvm_s390_io_adapter_req {
__u64 addr;
};
+/* kvm attr_group on vm fd */
+#define KVM_S390_VM_CPU_MODEL 1
+
+/* kvm attributes for mem_ctrl */
+#define KVM_S390_VM_MEM_CLR_CMMA 1
+
+/* kvm S390 processor related attributes */
+#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 */
+#define KVM_S390_VM_CPU_MACHINE 1
+struct kvm_s390_vm_cpu_machine {
+ __u64 cpuid;
+ __u32 ibc_range;
+ __u64 fac_mask[256];
+ __u8 pad[4];
+ __u64 hard_fac_list[256];
+ __u64 soft_fac_list[256];
+};
+
/* for KVM_GET_REGS and KVM_SET_REGS */
struct kvm_regs {
/* general purpose regs for s390 */
--git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index b278ab3..770ce38 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -743,6 +743,7 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_IOAPIC_POLARITY_IGNORED 97
#define KVM_CAP_ENABLE_CAP_VM 98
#define KVM_CAP_S390_IRQCHIP 99
+#define KVM_CAP_VM_ATTRIBUTES 101
#ifdef KVM_CAP_IRQ_ROUTING
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v1 RFC 06/10] QEMU: s390: cpu model kvm VM attr interface routines
2014-05-13 15:00 [Qemu-devel] [PATCH v1 RFC 00/10] QEMU: s390: cpu model implementation Michael Mueller
` (4 preceding siblings ...)
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 05/10] s390: update linux-headers for kvm VM device attributes Michael Mueller
@ 2014-05-13 15:00 ` Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 07/10] QEMU: s390: cpu model class initialization Michael Mueller
` (3 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Michael Mueller @ 2014-05-13 15:00 UTC (permalink / raw)
To: qemu-devel, kvm, linux-s390, linux-kernel
Cc: mimu, Gleb Natapov, Alexander Graf, Christian Borntraeger,
Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
Richard Henderson
The patch implements routines to set and retrieve processor configuration
data and to retrieve machine configuration data. The machine related data
will be used to determine the list of supported cpu models of this host.
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
target-s390x/cpu-models.h | 21 +++++++++++++++
target-s390x/cpu.c | 2 ++
target-s390x/kvm.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 89 insertions(+)
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index f5c8112..3533c96 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -55,6 +55,27 @@ typedef struct S390CPUAlias {
} S390CPUAlias;
extern GSList *s390_cpu_aliases;
+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_mask[S390_ARCH_FAC_MASK_SIZE_UINT64];
+ uint64_t hard_fac_list[S390_ARCH_FAC_LIST_SIZE_UINT64];
+ uint64_t soft_fac_list[S390_ARCH_FAC_LIST_SIZE_UINT64];
+} S390MachineProps;
+
+int kvm_s390_has_cpu_model_call(uint64_t attr);
+int kvm_s390_get_processor_props(S390ProcessorProps *prob);
+int kvm_s390_set_processor_props(S390ProcessorProps *prob);
+int kvm_s390_get_machine_props(S390MachineProps *prob);
+
/*
* bits 0-7 : CMOS generation
* bits 8-9 : reserved
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 10a03f9..5e292e7 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -28,6 +28,8 @@
#include "qemu-common.h"
#include "qemu/timer.h"
#include "hw/hw.h"
+#include "cpu-qom.h"
+#include "cpu-models.h"
#ifndef CONFIG_USER_ONLY
#include "sysemu/arch_init.h"
#endif
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index b7b0edc..b69d5d0 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -33,6 +33,7 @@
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "cpu.h"
+#include "cpu-models.h"
#include "sysemu/device_tree.h"
#include "qapi/qmp/qjson.h"
#include "monitor/monitor.h"
@@ -93,6 +94,8 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
static int cap_sync_regs;
static int cap_async_pf;
+static uint64_t cpu_model_call_cache;
+
static void *legacy_s390_alloc(size_t size);
int kvm_arch_init(KVMState *s)
@@ -959,3 +962,66 @@ int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
}
return kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick);
}
+
+static int cpu_model_get(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(kvm_state, KVM_GET_DEVICE_ATTR, &dev_attr);
+}
+
+static int cpu_model_set(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(kvm_state, KVM_SET_DEVICE_ATTR, &dev_attr);
+}
+
+int kvm_s390_has_cpu_model_call(uint64_t attr)
+{
+ int rc;
+ struct kvm_device_attr dev_attr = {
+ .group = KVM_S390_VM_CPU_MODEL,
+ .attr = attr,
+ };
+
+ if (dev_attr.attr >= sizeof(cpu_model_call_cache)) {
+ return 0;
+ }
+
+ if (cpu_model_call_cache & (1UL << dev_attr.attr)) {
+ return 1;
+ }
+
+ rc = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &dev_attr);
+ if (rc == 0) {
+ cpu_model_call_cache |= (1UL << dev_attr.attr);
+ return 1;
+ }
+
+ return 0;
+}
+
+int kvm_s390_get_processor_props(S390ProcessorProps *prop)
+{
+ return cpu_model_get(KVM_S390_VM_CPU_PROCESSOR, (uint64_t) prop);
+}
+
+int kvm_s390_set_processor_props(S390ProcessorProps *prop)
+{
+ return cpu_model_set(KVM_S390_VM_CPU_PROCESSOR, (uint64_t) prop);
+}
+
+int kvm_s390_get_machine_props(S390MachineProps *prop)
+{
+ return cpu_model_get(KVM_S390_VM_CPU_MACHINE, (uint64_t) prop);
+}
+
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v1 RFC 07/10] QEMU: s390: cpu model class initialization
2014-05-13 15:00 [Qemu-devel] [PATCH v1 RFC 00/10] QEMU: s390: cpu model implementation Michael Mueller
` (5 preceding siblings ...)
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 06/10] QEMU: s390: cpu model kvm VM attr interface routines Michael Mueller
@ 2014-05-13 15:00 ` Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 08/10] QEMU: s390: cpu model QMP query-cpu-definitions Michael Mueller
` (2 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Michael Mueller @ 2014-05-13 15:00 UTC (permalink / raw)
To: qemu-devel, kvm, linux-s390, linux-kernel
Cc: mimu, Gleb Natapov, Alexander Graf, Christian Borntraeger,
Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
Richard Henderson
This patch provides routines to dynamically update the previously defined S390
cpu classes in the current host context. The main function issuing 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 KVM host properties
- mark cpu class for cpu model "host"
- invalidate cpu classes not supported by this host
- set machine type aliases to latest ga of model (e.g. 2064 -> 2064-ga3)
- set aliases for common model names to machine types
- set alias for cpu model "host"
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
target-s390x/cpu-models.c | 401 ++++++++++++++++++++++++++++++++++++++++++++++
target-s390x/cpu-models.h | 25 +++
target-s390x/cpu.c | 26 ++-
target-s390x/cpu.h | 3 +
4 files changed, 454 insertions(+), 1 deletion(-)
diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index 25147a4..19bbb30 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -12,6 +12,7 @@
#include "cpu.h"
#include "cpu-models.h"
+#include "qemu/error-report.h"
#define S390_FAC_NAME(n, _cpu_id) \
glue(glue(glue(FAC, n), _), _cpu_id)
@@ -86,8 +87,42 @@ 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 arguments */
+typedef struct ArgTCV {
+ unsigned short type;
+ unsigned short class;
+ bool valid;
+} ArgTCV;
+
+typedef struct ArgTGV {
+ unsigned short type;
+ unsigned short gen;
+ bool valid;
+} ArgTGV;
+
+typedef struct ArgTC {
+ unsigned short type;
+ unsigned short class;
+} ArgTC;
+
+typedef struct ArgPH {
+ S390MachineProps *prop;
+ S390CPUClass *host_cc;
+} ArgPH;
+
+typedef struct ArgH {
+ S390CPUClass *host_cc;
+} ArgH;
+
+typedef struct ArgTG {
+ unsigned short type;
+ unsigned short ga;
+} ArgTG;
+
/* S390 CPU aliases can be added dynamically to this list */
GSList *s390_cpu_aliases;
+bool s390_cpu_classes_prepared;
+bool s390_use_sofl;
static inline unsigned long bit_in_word(unsigned int nr)
{
@@ -107,6 +142,21 @@ static inline int test_facility(unsigned long nr, unsigned long *fac_list)
return (*ptr & bit_in_word(nr)) != 0;
}
+/* 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)
{
ObjectClass *oc = (ObjectClass *)a;
@@ -167,3 +217,354 @@ 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);
+ ArgTCV *arg = user_data;
+
+ if (arg->valid || !cc->proc->type || arg->type != cc->proc->type) {
+ return;
+ }
+
+ arg->class = cc->mach->class;
+ arg->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);
+ ArgTC *arg = user_data;
+ ArgTCV arg_class;
+
+ if (arg->type != type) {
+ arg->class = 0;
+ }
+ if (!arg->class) {
+ arg_class.type = type;
+ arg_class.class = 0;
+ arg_class.valid = false;
+ g_slist_foreach(list, (GFunc) s390_machine_class_test_cpu_class,
+ &arg_class);
+ g_slist_free(list);
+ if (arg_class.valid) {
+ arg->class = arg_class.class;
+ }
+ }
+ arg->type = type;
+
+ return arg->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);
+ ArgTGV *arg = user_data;
+
+ if (arg->valid) {
+ return;
+ }
+
+ if (arg->type == cc->proc->type) {
+ arg->gen = cc->proc->gen;
+ arg->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);
+ ArgTGV arg_gen;
+
+ arg_gen.type = type;
+ arg_gen.gen = 0;
+ arg_gen.valid = false;
+ g_slist_foreach(list, (GFunc) s390_machine_class_test_cpu_gen,
+ &arg_gen);
+ g_slist_free(list);
+
+ return arg_gen.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);
+ ArgPH *arg = user_data;
+ ArgTC arg_tc;
+
+ if (!cc->is_active) {
+ return;
+ }
+
+ arg_tc.type = 0;
+ arg_tc.class = 0;
+ if (cc->mach->class != machine_class(
+ cpuid_type(arg->prop->cpuid), &arg_tc)) {
+ /* sort out machines that differ from host machine class */
+ return;
+ }
+ if (!arg->host_cc) {
+ /* use first matching machine type */
+ cc->is_host = true;
+ arg->host_cc = cc;
+ return;
+ }
+ if (cc->proc->gen > machine_gen(cpuid_type(arg->prop->cpuid))) {
+ /* sort out CMOS generations later than hosts generation */
+ cc->is_active = false;
+ return;
+ }
+ if (cc->mach->order > arg->host_cc->mach->order) {
+ /* select later machine as host */
+ arg->host_cc->is_host = false;
+ cc->is_host = true;
+ arg->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;
+ S390MachineProps *prop = user_data;
+ S390CPUClass *cc = S390_CPU_CLASS(oc);
+ unsigned int i;
+
+ if (!cc->proc->type) {
+ return;
+ }
+
+ /* set processor identifier */
+ cc->proc->id = cpuid_id(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 lowest supported value.
+ */
+ if (has_ibc(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 < lowest_ibc(prop->ibc_range)) {
+ cc->proc->ibc = lowest_ibc(prop->ibc_range);
+ }
+ if (cc->proc->ibc > latest_ibc(prop->ibc_range)) {
+ cc->proc->ibc = latest_ibc(prop->ibc_range);
+ }
+ } else {
+ cc->proc->ibc = lowest_ibc(prop->ibc_range);
+ }
+ }
+
+ /* set desired facility list of class */
+ for (i = 0; i < S390_FAC_LIST_SIZE_UINT64; i++) {
+ cc->fac_list[i] = prop->fac_mask[i] & cc->proc->fac_list[i];
+ }
+
+ /* mark cpu class inactive if not all desired facility bits are available */
+ for (i = 0; i < S390_FAC_LIST_SIZE_BIT && cc->is_active; i++) {
+ if (test_facility(i, cc->fac_list) &&
+ !test_facility(i, prop->hard_fac_list)) {
+ cc->is_active = false;
+ }
+ }
+
+ /* extend desired facility list by offered soft facility list */
+ if (s390_use_sofl) {
+ for (i = 0; i < S390_FAC_LIST_SIZE_UINT64; i++) {
+ cc->fac_list[i] |= prop->fac_mask[i] & prop->soft_fac_list[i];
+ }
+ }
+}
+
+/* a cpu class that is newer then the current host */
+static void s390_deactivate_not_supported_cpu_class(gpointer data,
+ gpointer user_data)
+{
+ S390CPUClass *cc = S390_CPU_CLASS((ObjectClass *) data);
+ ArgH *arg = user_data;
+
+ if (!cc->is_active) {
+ return;
+ }
+ if (cc->mach->order > arg->host_cc->mach->order) {
+ cc->is_active = 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_from_cpu_class(gpointer data, gpointer user_data)
+{
+ S390CPUClass *cc = S390_CPU_CLASS((ObjectClass *) data);
+ ArgTG *arg = user_data;
+
+ if (!cc->is_active) {
+ return;
+ }
+ if (!arg->type) {
+ arg->type = cc->proc->type;
+ }
+ if (cc->proc->type == arg->type) {
+ arg->ga = cc->mach->ga;
+ return;
+ }
+ set_s390_cpu_alias_by_type_ga(arg->type, arg->ga);
+ arg->type = cc->proc->type;
+ arg->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);
+ char model[16];
+
+ if (!cc->is_active || !cc->is_host) {
+ return;
+ }
+ snprintf(model, sizeof(model), "%04x-ga%u", cc->proc->type, cc->mach->ga);
+ set_s390_cpu_alias("host", model);
+}
+
+/*
+ * apply host properties retrieved from KVM to cpu model classes,
+ * then find cpu model host and define further aliases
+ */
+int s390_setup_cpu_classes(S390MachineProps *prop)
+{
+ GSList *list;
+ ArgPH arg_host;
+ ArgH arg_deactivate;
+ ArgTG arg_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 KVM properties */
+ g_slist_foreach(list, (GFunc) s390_update_cpu_class, (gpointer) prop);
+
+ /* define cpu model "host" */
+ arg_host.prop = prop;
+ arg_host.host_cc = NULL;
+ g_slist_foreach(list, (GFunc) s390_mark_host_cpu_class,
+ (gpointer) &arg_host);
+
+ if (!arg_host.host_cc) {
+ error_report("Failed to mark host cpu class: %m");
+ return -EINVAL;
+ }
+
+ /* invalidate cpu classes not supported by this host */
+ arg_deactivate.host_cc = arg_host.host_cc;
+ g_slist_foreach(list, (GFunc) s390_deactivate_not_supported_cpu_class,
+ &arg_deactivate);
+
+ /* set machine type aliases to latest ga of model (e.g. 2064 -> 2064-ga3) */
+ arg_alias.type = 0;
+ arg_alias.ga = 0;
+ g_slist_foreach(list, (GFunc) s390_set_ga_alias_from_cpu_class, &arg_alias);
+ set_s390_cpu_alias_by_type_ga(arg_alias.type, arg_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" */
+ g_slist_foreach(list, (GFunc) s390_set_host_alias_from_cpu_class, NULL);
+
+ g_slist_free(list);
+
+ s390_cpu_classes_prepared = true;
+
+ 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;
+ GSList *item;
+ char *name;
+
+ if (!cc->is_active) {
+ 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);
+}
+
+/* copy cpu class properties to another cpu class */
+void s390_update_cpu_class_properties(S390CPUClass *dst, S390CPUClass *src)
+{
+ if (!dst || !src->is_active) {
+ return;
+ }
+ dst->is_active = src->is_active;
+ dst->is_host = src->is_host;
+ memcpy(dst->fac_list, src->fac_list,
+ S390_FAC_LIST_SIZE_BYTE);
+ dst->mach->order = src->mach->order;
+ dst->mach->class = src->mach->class;
+ dst->mach->ga = src->mach->ga;
+ dst->proc->ver = src->proc->ver;
+ dst->proc->id = src->proc->id;
+ dst->proc->type = src->proc->type;
+ dst->proc->ibc = src->proc->ibc;
+ dst->proc->gen = src->proc->gen;
+ memcpy(dst->proc->fac_list, src->proc->fac_list,
+ S390_FAC_LIST_SIZE_BYTE);
+}
diff --git a/target-s390x/cpu-models.h b/target-s390x/cpu-models.h
index 3533c96..cc917d4 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -37,12 +37,27 @@
#define FAC_BIT(WORD, BIT) \
(BIT / 64 == WORD ? 1ull << (63 - BIT % 64) : 0)
+/* 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 lowest_ibc(x) (((x) >> 16) & 0xfff)
+#define latest_ibc(x) ((x) & 0xfff)
+#define has_ibc(x) (lowest_ibc(x) != 0x0)
+
ObjectClass *s390_cpu_class_by_name(const char *name);
int set_s390_cpu_alias(const char *name, const char *model);
@@ -71,10 +86,20 @@ typedef struct S390MachineProps {
uint64_t soft_fac_list[S390_ARCH_FAC_LIST_SIZE_UINT64];
} S390MachineProps;
+/* indicates the cpu classes have been successfully updated */
+extern bool s390_cpu_classes_prepared;
+
+/* indicates use of soft facilities is requested */
+extern bool s390_use_sofl;
+
int kvm_s390_has_cpu_model_call(uint64_t attr);
int kvm_s390_get_processor_props(S390ProcessorProps *prob);
int kvm_s390_set_processor_props(S390ProcessorProps *prob);
int kvm_s390_get_machine_props(S390MachineProps *prob);
+int s390_setup_cpu_classes(S390MachineProps *prop);
+gint s390_cpu_class_asc_order_compare(gconstpointer a, gconstpointer b);
+void s390_cpu_list_entry(gpointer data, gpointer user_data);
+void s390_update_cpu_class_properties(S390CPUClass *dst, S390CPUClass *src);
/*
* bits 0-7 : CMOS generation
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 5e292e7..741f3ce 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -41,7 +41,31 @@
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()) {
+ 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
+}
+
+bool s390_cpudesc_ready(void)
+{
+#ifdef CONFIG_KVM
+ return s390_cpu_classes_prepared;
+#else
+ return true;
#endif
}
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index aad277a..7c1c431 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -519,6 +519,9 @@ static inline bool css_present(uint8_t cssid)
void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf);
#define cpu_list s390_cpu_list
+bool s390_cpudesc_ready(void);
+#define cpudesc_ready s390_cpudesc_ready
+
#include "exec/exec-all.h"
#define EXCP_EXT 1 /* external interrupt */
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v1 RFC 08/10] QEMU: s390: cpu model QMP query-cpu-definitions
2014-05-13 15:00 [Qemu-devel] [PATCH v1 RFC 00/10] QEMU: s390: cpu model implementation Michael Mueller
` (6 preceding siblings ...)
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 07/10] QEMU: s390: cpu model class initialization Michael Mueller
@ 2014-05-13 15:00 ` Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 09/10] QEMU: s390: cpu model QMP query-cpu-model Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 10/10] QEMU: s390: cpu model enablement Michael Mueller
9 siblings, 0 replies; 13+ messages in thread
From: Michael Mueller @ 2014-05-13 15:00 UTC (permalink / raw)
To: qemu-devel, kvm, linux-s390, linux-kernel
Cc: mimu, Gleb Natapov, Alexander Graf, Christian Borntraeger,
Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
Richard Henderson
This patch implements the QMP command "query-cpu-definitions" in the S390
context. The command returns a descending sorted list of cpu model names
derived from the currently (in the current host context) supported set of
cpu classes. That means a consumer can successfully request each reported
cpu model. Implicitly, the first reported cpu model is the host cpu model.
request: {"execute": "query-cpu-definitions"}
answer: {"return": [{"name": "2827-ga1"}, {"name": "2818-ga1"}, {"name": "2817-ga2"},
{"name": "2817-ga1"}, {"name": "2098-ga2"}, {"name": "2098-ga1"}, {"name": "2097-ga3"},
{"name": "2097-ga2"}, {"name": "2097-ga1"}, {"name": "2096-ga2"}, {"name": "2096-ga1"},
{"name": "2094-ga3"}, {"name": "2094-ga2"}, {"name": "2094-ga1"}, {"name": "2086-ga3"},
{"name": "2086-ga2"}, {"name": "2086-ga1"}, {"name": "2084-ga5"}, {"name": "2084-ga4"},
{"name": "2084-ga3"}, {"name": "2084-ga2"}, {"name": "2084-ga1"}, {"name": "2068-ga1"},
{"name": "2064-ga3"}, {"name": "2064-ga2"}, {"name": "2064-ga1"}]}
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
target-s390x/cpu-models.c | 16 ++++++++
target-s390x/cpu-models.h | 3 ++
target-s390x/cpu.c | 96 +++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 111 insertions(+), 4 deletions(-)
diff --git a/target-s390x/cpu-models.c b/target-s390x/cpu-models.c
index 19bbb30..ed087cb 100644
--- a/target-s390x/cpu-models.c
+++ b/target-s390x/cpu-models.c
@@ -123,6 +123,7 @@ typedef struct ArgTG {
GSList *s390_cpu_aliases;
bool s390_cpu_classes_prepared;
bool s390_use_sofl;
+bool s390_cpu_model_mode;
static inline unsigned long bit_in_word(unsigned int nr)
{
@@ -218,6 +219,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 cc917d4..c2675cb 100644
--- a/target-s390x/cpu-models.h
+++ b/target-s390x/cpu-models.h
@@ -88,6 +88,8 @@ typedef struct S390MachineProps {
/* indicates the cpu classes have been successfully updated */
extern bool s390_cpu_classes_prepared;
+/* indicates qemu is running without cpu models */
+extern bool s390_cpu_model_mode;
/* indicates use of soft facilities is requested */
extern bool s390_use_sofl;
@@ -100,6 +102,7 @@ int s390_setup_cpu_classes(S390MachineProps *prop);
gint s390_cpu_class_asc_order_compare(gconstpointer a, gconstpointer b);
void s390_cpu_list_entry(gpointer data, gpointer user_data);
void s390_update_cpu_class_properties(S390CPUClass *dst, S390CPUClass *src);
+gint s390_cpu_class_desc_order_compare(gconstpointer a, gconstpointer b);
/*
* bits 0-7 : CMOS generation
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 741f3ce..6479659 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -37,6 +37,13 @@
#define CR0_RESET 0xE0UL
#define CR14_RESET 0xC2000000UL;
+#ifdef CONFIG_KVM
+typedef struct CpuDefinition {
+ CpuDefinitionInfoList *head;
+ CpuDefinitionInfoList *tail;
+} CpuDefinition;
+#endif
+
/* generate CPU information for cpu -? */
void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf)
{
@@ -70,18 +77,99 @@ bool s390_cpudesc_ready(void)
}
#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_KVM
+static void s390_query_cpu_definition(gpointer data, gpointer user_data)
+{
+ S390CPUClass *cc = S390_CPU_CLASS((ObjectClass *) data);
+ char model[16];
+ CpuDefinition *cpu_definition = user_data;
+ CpuDefinitionInfo *info;
+ CpuDefinitionInfoList *entry;
+
+ if (!cc->is_active) {
+ return;
+ }
+
+ info = g_try_malloc0(sizeof(*info));
+ if (!info) {
+ goto out_info;
+ }
+
+ snprintf(model, sizeof(model), "%04x-ga%u", cc->proc->type, cc->mach->ga);
+ info->name = g_strdup(model);
+ if (!info->name) {
+ goto out_name;
+ }
+
+ entry = g_try_malloc0(sizeof(*entry));
+ if (!entry) {
+ goto out_entry;
+ }
+ entry->value = info;
+ entry->next = NULL;
+
+ if (cpu_definition->tail) {
+ cpu_definition->tail->next = entry;
+ cpu_definition->tail = cpu_definition->tail->next;
+ } else {
+ cpu_definition->head = cpu_definition->tail = entry;
+ }
+ return;
+
+out_entry:
+ g_free(info->name);
+out_name:
+ g_free(info);
+out_info:
+ return;
+}
+#endif
+
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
{
CpuDefinitionInfoList *entry;
CpuDefinitionInfo *info;
- info = g_malloc0(sizeof(*info));
- info->name = g_strdup("host");
+#ifdef CONFIG_KVM
+ GSList *list;
+ CpuDefinition cpu_definition;
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
+ /* There are no valid cpu classes defined in this case. */
+ if (!s390_cpu_model_mode) {
+ return NULL;
+ }
+ list = object_class_get_list(TYPE_S390_CPU, false);
+ list = g_slist_sort(list, s390_cpu_class_desc_order_compare);
+ cpu_definition.head = NULL;
+ cpu_definition.tail = NULL;
+ g_slist_foreach(list, s390_query_cpu_definition, &cpu_definition);
+ g_slist_free(list);
+
+ return cpu_definition.head;
+#endif
+
+ info = g_try_malloc0(sizeof(*info));
+ if (!info) {
+ goto out_info;
+ }
+ info->name = g_strdup("host");
+ if (!info->name) {
+ goto out_name;
+ }
+ entry = g_try_malloc0(sizeof(*entry));
+ if (!entry) {
+ goto out_entry;
+ }
+ entry->value = info;
return entry;
+
+out_entry:
+ g_free(info->name);
+out_name:
+ g_free(info);
+out_info:
+ return NULL;
}
#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v1 RFC 09/10] QEMU: s390: cpu model QMP query-cpu-model
2014-05-13 15:00 [Qemu-devel] [PATCH v1 RFC 00/10] QEMU: s390: cpu model implementation Michael Mueller
` (7 preceding siblings ...)
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 08/10] QEMU: s390: cpu model QMP query-cpu-definitions Michael Mueller
@ 2014-05-13 15:00 ` Michael Mueller
2014-05-13 15:29 ` Eric Blake
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 10/10] QEMU: s390: cpu model enablement Michael Mueller
9 siblings, 1 reply; 13+ messages in thread
From: Michael Mueller @ 2014-05-13 15:00 UTC (permalink / raw)
To: qemu-devel, kvm, linux-s390, linux-kernel
Cc: mimu, Gleb Natapov, Alexander Graf, Christian Borntraeger,
Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
Richard Henderson
This patch implements a new QMP request named "query-cpu-model". It returns
the cpu model of cpu 0. eg:
request: '{"execute" : "query-cpu-model" }
answer: '{"return" : {"name": "2827-ga2"}}
Alias names are resolved to their respective machine type and GA names
already during cpu instantiation. Thus, also a cpu name like "host",
which is implemented as alias, will return its normalized cpu model name.
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
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.c | 42 ++++++++++++++++++++++++++++++++++++++++++
7 files changed, 87 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 cadcedc..dcdb1ed 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -38,5 +38,6 @@ int xen_available(void);
bool cpudesc_avail(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 36cb964..0a95f7b 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3460,6 +3460,29 @@
##
{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] }
+##
+# @CpuModelInfo:
+#
+# Virtual CPU model definition.
+#
+# @name: the name of the CPU model definition
+#
+# Since: 2.1.0
+##
+{ 'type': 'CpuModelInfo',
+ 'data': { 'name': 'str' } }
+
+##
+# @query-cpu-model:
+#
+# Return to current virtual CPU model
+#
+# Returns: CpuModelInfo
+#
+# Since: 2.1.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 cae890e..e56d3a9 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3247,6 +3247,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 a7f432b..1903db1 100644
--- a/qmp.c
+++ b/qmp.c
@@ -486,6 +486,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 d99e2b9..f6db116 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 += clock-warp.o
stub-obj-y += cpu-get-clock.o
stub-obj-y += cpu-get-icount.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.c b/target-s390x/cpu.c
index 6479659..132b468 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -37,6 +37,8 @@
#define CR0_RESET 0xE0UL
#define CR14_RESET 0xC2000000UL;
+#define CPU_MODEL_NAME_LEN 32
+
#ifdef CONFIG_KVM
typedef struct CpuDefinition {
CpuDefinitionInfoList *head;
@@ -171,6 +173,46 @@ out_name:
out_info:
return NULL;
}
+
+CpuModelInfo *arch_query_cpu_model(Error **errp)
+{
+ CpuModelInfo *cpu_model;
+ S390CPUClass *cc;
+ S390CPU *cpu;
+
+ cpu = s390_cpu_addr2state(0);
+ if (!cpu) {
+ goto out_no_cpu;
+ }
+ cc = S390_CPU_GET_CLASS(cpu);
+ if (!cc) {
+ goto out_no_cpu;
+ }
+ if (!cc->proc->type) {
+ goto out_no_cpu;
+ }
+ cpu_model = g_try_malloc0(sizeof(*cpu_model));
+ if (!cpu_model) {
+ goto out_no_mem;
+ }
+ cpu_model->name = g_try_malloc0(CPU_MODEL_NAME_LEN);
+ if (!cpu_model->name) {
+ goto out_no_mem;
+ }
+ snprintf(cpu_model->name, CPU_MODEL_NAME_LEN - 1, "%04x-ga%u",
+ cc->proc->type, cc->mach->ga);
+ if (s390_use_sofl) {
+ strncat(cpu_model->name, ",+sofl", CPU_MODEL_NAME_LEN - 1);
+ }
+ return cpu_model;
+
+out_no_mem:
+ if (cpu_model) {
+ g_free(cpu_model);
+ }
+out_no_cpu:
+ return NULL;
+}
#endif
static void s390_cpu_set_pc(CPUState *cs, vaddr value)
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v1 RFC 10/10] QEMU: s390: cpu model enablement
2014-05-13 15:00 [Qemu-devel] [PATCH v1 RFC 00/10] QEMU: s390: cpu model implementation Michael Mueller
` (8 preceding siblings ...)
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 09/10] QEMU: s390: cpu model QMP query-cpu-model Michael Mueller
@ 2014-05-13 15:00 ` Michael Mueller
9 siblings, 0 replies; 13+ messages in thread
From: Michael Mueller @ 2014-05-13 15:00 UTC (permalink / raw)
To: qemu-devel, kvm, linux-s390, linux-kernel
Cc: mimu, Gleb Natapov, Alexander Graf, Christian Borntraeger,
Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
Richard Henderson
This patch enables all previous cpu model related patches and
allows the feature to become active. It basically implements
the host properties being fetched from the host and applied to
the predefined S390 cpu classes during initialization of the
HW platform. In a second step, the requsted cpu model determines
from which cpu class the cpus become instantiated.
In S390/KVM context, the cpudesc_avail() function returns false
to avoid the list_cpus() function to be called early. As soon an
cpu model configuration has been successfully requested and
the cpu classes have been updated accordingly, the function
also returns true.
This patch starts using cpu class s390-cpu as common cpu class
also for cpus with model properties defined. All cpus will be
instantiated by means of this class, but the cpu model related
properties of the class will be updated on behalf of the cpu model.
This will allow in future to change cpu models concurrently without
dropping or recreating of cpu objects derived from different cpu
classes. This class is required in the absence of a class
transformation operation.
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
---
hw/s390x/s390-virtio-ccw.c | 2 +
hw/s390x/s390-virtio.c | 104 +++++++++++++++++++++++++++++++++++++++++++++
hw/s390x/s390-virtio.h | 1 +
3 files changed, 107 insertions(+)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 0d4f6ae..38ec425 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -106,6 +106,8 @@ static void ccw_init(QEMUMachineInitArgs *args)
args->initrd_filename, "s390-ccw.img");
s390_flic_init();
+ s390_set_cpu_model(args->cpu_model);
+
/* register hypercalls */
virtio_ccw_register_hcalls();
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index aef2003..0d47523 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"
@@ -39,6 +40,8 @@
#include "hw/s390x/s390_flic.h"
#include "hw/s390x/s390-virtio.h"
+#include "cpu-models.h"
+
//#define DEBUG_S390
#ifdef DEBUG_S390
@@ -223,6 +226,105 @@ void s390_create_virtio_net(BusState *bus, const char *name)
}
}
+void s390_set_cpu_model(const char *cpu_model)
+{
+ S390MachineProps mach = {
+ /* base model for TCG */
+ .cpuid = 0xffdecade20640000,
+ .fac_mask[0] = FAC0_CPU_S390_2064_GA1,
+ .hard_fac_list[0] = FAC0_CPU_S390_2064_GA1,
+ };
+ S390CPUClass *cc, *tc;
+ ObjectClass *oc;
+ char *str, *name, *feature;
+#ifdef CONFIG_KVM
+ S390ProcessorProps proc;
+#endif
+
+ /* assume user wants model "host" if non is selected */
+ if (!cpu_model) {
+ cpu_model = "host";
+ }
+
+ s390_cpu_model_mode = true;
+#ifdef CONFIG_KVM
+ /* request host specific properties from kvm */
+ if (kvm_enabled()) {
+ if (kvm_check_extension(kvm_state, KVM_CAP_VM_ATTRIBUTES) == 0) {
+ goto out_legacy_cpu;
+ }
+ if (!kvm_s390_has_cpu_model_call(KVM_S390_VM_CPU_PROCESSOR) ||
+ !kvm_s390_has_cpu_model_call(KVM_S390_VM_CPU_MACHINE)) {
+ goto out_legacy_cpu;
+ }
+ if (kvm_s390_get_machine_props(&mach)) {
+ goto out_legacy_cpu;
+ }
+ }
+#endif
+
+ /* split off cpu model name */
+ str = g_strdup(cpu_model);
+ name = g_strdup(strtok(str, ","));
+
+ /* parse remaining features */
+ for (feature = strtok(NULL, ","); feature; feature = strtok(NULL, ",")) {
+ if (!strcmp(feature, "+sofl")) {
+ /* allow use of soft facilities */
+ s390_use_sofl = true;
+ continue;
+ }
+ }
+ g_free(str);
+
+ /* populate cpu classes with life */
+ if (s390_setup_cpu_classes(&mach) != 0) {
+ goto out_legacy_cpu;
+ }
+
+ /* print help on cpu models if requested */
+ if (is_help_option(name)) {
+ list_cpus(stdout, &fprintf, name);
+ exit(0);
+ }
+
+ /* get handle to cpu model specific cpu class */
+ oc = s390_cpu_class_by_name(name);
+ g_free(name);
+ if (!oc) {
+ goto out_legacy_cpu;
+ }
+ cc = S390_CPU_CLASS(oc);
+ if (!cc) {
+ goto out_legacy_cpu;
+ }
+
+#ifdef CONFIG_KVM
+ /* request kvm to use selected cpu model properties */
+ if (kvm_enabled()) {
+ proc.cpuid = ver_cpuid(cc->proc->ver);
+ proc.cpuid |= id_cpuid(cc->proc->id);
+ proc.cpuid |= type_cpuid(cc->proc->type);
+ proc.ibc = cc->proc->ibc;
+ memcpy(proc.fac_list, cc->fac_list,
+ S390_FAC_LIST_SIZE_BYTE);
+ if (kvm_s390_set_processor_props(&proc) != 0) {
+ goto out_legacy_cpu;
+ }
+ }
+#endif
+
+ /* update central cpu class with cpu model properties */
+ tc = S390_CPU_CLASS(object_class_by_name(TYPE_S390_CPU));
+ s390_update_cpu_class_properties(tc, cc);
+
+ return;
+
+out_legacy_cpu:
+ /* fall back to non cpu model mode */
+ s390_cpu_model_mode = false;
+}
+
/* PC hardware initialisation */
static void s390_init(QEMUMachineInitArgs *args)
{
@@ -252,6 +354,8 @@ static void s390_init(QEMUMachineInitArgs *args)
args->initrd_filename, ZIPL_FILENAME);
s390_flic_init();
+ s390_set_cpu_model(args->cpu_model);
+
/* register hypercalls */
s390_virtio_register_hcalls();
diff --git a/hw/s390x/s390-virtio.h b/hw/s390x/s390-virtio.h
index 5c405e7..17bdddf 100644
--- a/hw/s390x/s390-virtio.h
+++ b/hw/s390x/s390-virtio.h
@@ -26,4 +26,5 @@ void s390_init_ipl_dev(const char *kernel_filename,
const char *initrd_filename,
const char *firmware);
void s390_create_virtio_net(BusState *bus, const char *name);
+void s390_set_cpu_model(const char *cpu_model);
#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH v1 RFC 09/10] QEMU: s390: cpu model QMP query-cpu-model
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 09/10] QEMU: s390: cpu model QMP query-cpu-model Michael Mueller
@ 2014-05-13 15:29 ` Eric Blake
2014-05-14 9:07 ` Michael Mueller
0 siblings, 1 reply; 13+ messages in thread
From: Eric Blake @ 2014-05-13 15:29 UTC (permalink / raw)
To: Michael Mueller, qemu-devel, kvm, linux-s390, linux-kernel
Cc: Gleb Natapov, Alexander Graf, Christian Borntraeger,
Jason J. Herne, Cornelia Huck, Paolo Bonzini, Andreas Faerber,
Richard Henderson
[-- Attachment #1: Type: text/plain, Size: 2039 bytes --]
On 05/13/2014 09:00 AM, Michael Mueller wrote:
> This patch implements a new QMP request named "query-cpu-model". It returns
> the cpu model of cpu 0. eg:
>
> request: '{"execute" : "query-cpu-model" }
> answer: '{"return" : {"name": "2827-ga2"}}
>
> Alias names are resolved to their respective machine type and GA names
> already during cpu instantiation. Thus, also a cpu name like "host",
> which is implemented as alias, will return its normalized cpu model name.
>
> + }
> + cpu_model = g_try_malloc0(sizeof(*cpu_model));
It's simpler to just use g_malloc0 and rely on glibc's exit-on-OOM
behavior than to try and deal with NULL - this isn't user input (so
unlikely to be so huge as to cause OOM), and would be more in line with
what most other QMP code does. But that said...
> + if (!cpu_model) {
> + goto out_no_mem;
> + }
> + cpu_model->name = g_try_malloc0(CPU_MODEL_NAME_LEN);
> + if (!cpu_model->name) {
> + goto out_no_mem;
> + }
> + snprintf(cpu_model->name, CPU_MODEL_NAME_LEN - 1, "%04x-ga%u",
> + cc->proc->type, cc->mach->ga);
...why not just use g_strdup_printf() instead of trying to size a buffer
yourself? In other words, skip the g_try_malloc0 to begin with.
The fact that you are packing two pieces of information into one string
is a bit worrisome - that means that the client of the QMP command has
to parse the string back into two pieces of information if they ever
need either item in isolation. If the user never has a need to split
the name down into parts, you are okay; I don't know S390 well enough to
know whether anyone will care about type separate from ga. But if
someone DOES care, then the QMP command should return the parts already
split, as in { "type": 2827, "ga": 2 }, or even as convenience provide
both split and combined forms: { "name": "2827-ga2", "type": 2827, "ga": 2 }
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH v1 RFC 09/10] QEMU: s390: cpu model QMP query-cpu-model
2014-05-13 15:29 ` Eric Blake
@ 2014-05-14 9:07 ` Michael Mueller
0 siblings, 0 replies; 13+ messages in thread
From: Michael Mueller @ 2014-05-14 9:07 UTC (permalink / raw)
To: Eric Blake
Cc: linux-s390, kvm, Gleb Natapov, linux-kernel, Alexander Graf,
qemu-devel, Christian Borntraeger, Jason J. Herne, Cornelia Huck,
Paolo Bonzini, Andreas Faerber, Richard Henderson
[-- Attachment #1: Type: text/plain, Size: 2551 bytes --]
On Tue, 13 May 2014 09:29:37 -0600
Eric Blake <eblake@redhat.com> wrote:
Hi Eric,
> On 05/13/2014 09:00 AM, Michael Mueller wrote:
> > This patch implements a new QMP request named "query-cpu-model". It returns
> > the cpu model of cpu 0. eg:
> >
> > request: '{"execute" : "query-cpu-model" }
> > answer: '{"return" : {"name": "2827-ga2"}}
> >
> > Alias names are resolved to their respective machine type and GA names
> > already during cpu instantiation. Thus, also a cpu name like "host",
> > which is implemented as alias, will return its normalized cpu model name.
> >
>
> > + }
> > + cpu_model = g_try_malloc0(sizeof(*cpu_model));
>
> It's simpler to just use g_malloc0 and rely on glibc's exit-on-OOM
> behavior than to try and deal with NULL - this isn't user input (so
> unlikely to be so huge as to cause OOM), and would be more in line with
> what most other QMP code does. But that said...
>
> > + if (!cpu_model) {
> > + goto out_no_mem;
> > + }
> > + cpu_model->name = g_try_malloc0(CPU_MODEL_NAME_LEN);
> > + if (!cpu_model->name) {
> > + goto out_no_mem;
> > + }
> > + snprintf(cpu_model->name, CPU_MODEL_NAME_LEN - 1, "%04x-ga%u",
> > + cc->proc->type, cc->mach->ga);
>
> ...why not just use g_strdup_printf() instead of trying to size a buffer
> yourself? In other words, skip the g_try_malloc0 to begin with.
I will use that function and I think I can use it with "query-cpu-definitions"
as well.
>
> The fact that you are packing two pieces of information into one string
> is a bit worrisome - that means that the client of the QMP command has
> to parse the string back into two pieces of information if they ever
> need either item in isolation. If the user never has a need to split
> the name down into parts, you are okay; I don't know S390 well enough to
I see your point, but I consider it as a name only, which needs to be unique
to identify different configurations but has no meaning on the management
interface level.
> know whether anyone will care about type separate from ga. But if
> someone DOES care, then the QMP command should return the parts already
> split, as in { "type": 2827, "ga": 2 }, or even as convenience provide
> both split and combined forms: { "name": "2827-ga2", "type": 2827, "ga": 2 }
>
Offering both options seems to be desirable but I have to talk with libvirt if that
could be done in a transparent form for them.
Thanks a lot for your comments
Michael
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2014-05-14 9:08 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-13 15:00 [Qemu-devel] [PATCH v1 RFC 00/10] QEMU: s390: cpu model implementation Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 01/10] QEMU: introduce function cpudesc_avail Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 02/10] QEMU: s390: cpu model cpu class definition Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 03/10] QEMU: s390: cpu model facilities support Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 04/10] QEMU: s390: cpu model alias support Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 05/10] s390: update linux-headers for kvm VM device attributes Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 06/10] QEMU: s390: cpu model kvm VM attr interface routines Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 07/10] QEMU: s390: cpu model class initialization Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 08/10] QEMU: s390: cpu model QMP query-cpu-definitions Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 09/10] QEMU: s390: cpu model QMP query-cpu-model Michael Mueller
2014-05-13 15:29 ` Eric Blake
2014-05-14 9:07 ` Michael Mueller
2014-05-13 15:00 ` [Qemu-devel] [PATCH v1 RFC 10/10] QEMU: s390: cpu model enablement Michael Mueller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).