From fc4b84b1c68a0dc2905d379f0f6a5305e4ebe0b3 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 5 Sep 2016 10:52:15 +0200 Subject: qmp: details about CPU definitions in query-cpu-definitions It might be of interest for tooling whether a CPU definition can be safely used when migrating, or if e.g. CPU features might get lost during migration when migrationg from/to a different QEMU version or host, even if the same compatibility machine is used. Also, we want to know if a CPU definition is static and will never change. Beause these definitions can then be used independantly of a compatibility machine and will always have the same feature set, they can e.g. be used to indicate the "host" model in libvirt later on. Let's add two return values to query-cpu-definitions, stating for each returned CPU definition, if it is migration-safe and if it is static. While "migration-safe" is optional, "static" will be set to "false" automatically by all implementing architectures. If a model really was static all the time and will be in the future, this can simply be changed later. Reviewed-by: Eric Blake Signed-off-by: David Hildenbrand Message-Id: <20160905085244.99980-2-dahi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck --- qapi-schema.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'qapi-schema.json') diff --git a/qapi-schema.json b/qapi-schema.json index 5658723b37..1c3533caac 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3038,10 +3038,22 @@ # # @name: the name of the CPU definition # +# @migration-safe: #optional whether a CPU definition can be safely used for +# migration in combination with a QEMU compatibility machine +# when migrating between different QMU versions and between +# hosts with different sets of (hardware or software) +# capabilities. If not provided, information is not available +# and callers should not assume the CPU definition to be +# migration-safe. (since 2.8) +# +# @static: whether a CPU definition is static and will not change depending on +# QEMU version, machine type, machine options and accelerator options. +# A static model is always migration-safe. (since 2.8) +# # Since: 1.2.0 ## { 'struct': 'CpuDefinitionInfo', - 'data': { 'name': 'str' } } + 'data': { 'name': 'str', '*migration-safe': 'bool', 'static': 'bool' } } ## # @query-cpu-definitions: -- cgit v1.2.3-55-g7522 From e09484efbc9db8c4554293cdc8aed7a8db378d97 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 5 Sep 2016 10:52:39 +0200 Subject: qmp: add QMP interface "query-cpu-model-expansion" Let's provide a standardized interface to expand CPU models. This interface can be used by tooling to get details about a specific CPU model in a certain configuration, e.g. about the "host" model. To take care of all architectures, two detail levels for an expansion are introduced. Certain architectures might not support all detail levels. While "full" will expand and indicate all relevant properties/features of a CPU model, "static" expands to a static base CPU model, that will never change between QEMU versions and therefore have the same features when used under different compatibility machines. Acked-by: Cornelia Huck Reviewed-by: Eduardo Habkost Signed-off-by: David Hildenbrand Message-Id: <20160905085244.99980-26-dahi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck --- include/sysemu/arch_init.h | 3 ++ qapi-schema.json | 92 ++++++++++++++++++++++++++++++++++ qmp-commands.hx | 6 +++ qmp.c | 7 +++ stubs/Makefile.objs | 1 + stubs/arch-query-cpu-model-expansion.c | 12 +++++ 6 files changed, 121 insertions(+) create mode 100644 stubs/arch-query-cpu-model-expansion.c (limited to 'qapi-schema.json') diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h index d690dfabdf..37b2e8675e 100644 --- a/include/sysemu/arch_init.h +++ b/include/sysemu/arch_init.h @@ -35,5 +35,8 @@ int kvm_available(void); int xen_available(void); CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp); +CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type, + CpuModelInfo *mode, + Error **errp); #endif diff --git a/qapi-schema.json b/qapi-schema.json index 1c3533caac..1c2daad087 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3066,6 +3066,98 @@ ## { 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] } +## +# @CpuModelInfo: +# +# Virtual CPU model. +# +# A CPU model consists of the name of a CPU definition, to which +# delta changes are applied (e.g. features added/removed). Most magic values +# that an architecture might require should be hidden behind the name. +# However, if required, architectures can expose relevant properties. +# +# @name: the name of the CPU definition the model is based on +# @props: #optional a dictionary of QOM properties to be applied +# +# Since: 2.8.0 +## +{ 'struct': 'CpuModelInfo', + 'data': { 'name': 'str', + '*props': 'any' } } + +## +# @CpuModelExpansionType +# +# An enumeration of CPU model expansion types. +# +# @static: Expand to a static CPU model, a combination of a static base +# model name and property delta changes. As the static base model will +# never change, the expanded CPU model will be the same, independant of +# independent of QEMU version, machine type, machine options, and +# accelerator options. Therefore, the resulting model can be used by +# tooling without having to specify a compatibility machine - e.g. when +# displaying the "host" model. static CPU models are migration-safe. +# +# @full: Expand all properties. The produced model is not guaranteed to be +# migration-safe, but allows tooling to get an insight and work with +# model details. +# +# Since: 2.8.0 +## +{ 'enum': 'CpuModelExpansionType', + 'data': [ 'static', 'full' ] } + + +## +# @CpuModelExpansionInfo +# +# The result of a cpu model expansion. +# +# @model: the expanded CpuModelInfo. +# +# Since: 2.8.0 +## +{ 'struct': 'CpuModelExpansionInfo', + 'data': { 'model': 'CpuModelInfo' } } + + +## +# @query-cpu-model-expansion: +# +# Expands a given CPU model (or a combination of CPU model + additional options) +# to different granularities, allowing tooling to get an understanding what a +# specific CPU model looks like in QEMU under a certain configuration. +# +# This interface can be used to query the "host" CPU model. +# +# The data returned by this command may be affected by: +# +# * QEMU version: CPU models may look different depending on the QEMU version. +# (Except for CPU models reported as "static" in query-cpu-definitions.) +# * machine-type: CPU model may look different depending on the machine-type. +# (Except for CPU models reported as "static" in query-cpu-definitions.) +# * machine options (including accelerator): in some architectures, CPU models +# may look different depending on machine and accelerator options. (Except for +# CPU models reported as "static" in query-cpu-definitions.) +# * "-cpu" arguments and global properties: arguments to the -cpu option and +# global properties may affect expansion of CPU models. Using +# query-cpu-model-expansion while using these is not advised. +# +# Some architectures may not support all expansion types. +# +# Returns: a CpuModelExpansionInfo. Returns an error if expanding CPU models is +# not supported, if the model cannot be expanded, if the model contains +# an unknown CPU definition name, unknown properties or properties +# with a wrong type. Also returns an error if an expansion type is +# not supported. +# +# Since: 2.8.0 +## +{ 'command': 'query-cpu-model-expansion', + 'data': { 'type': 'CpuModelExpansionType', + 'model': 'CpuModelInfo' }, + 'returns': 'CpuModelExpansionInfo' } + # @AddfdInfo: # # Information about a file descriptor that was added to an fd set. diff --git a/qmp-commands.hx b/qmp-commands.hx index 6866264e64..26b91e41d2 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -3941,6 +3941,12 @@ EQMP .mhandler.cmd_new = qmp_marshal_query_cpu_definitions, }, + { + .name = "query-cpu-model-expansion", + .args_type = "type:s,model:q", + .mhandler.cmd_new = qmp_marshal_query_cpu_model_expansion, + }, + { .name = "query-target", .args_type = "", diff --git a/qmp.c b/qmp.c index b6d531ebe2..29fbfb811c 100644 --- a/qmp.c +++ b/qmp.c @@ -607,6 +607,13 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) return arch_query_cpu_definitions(errp); } +CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, + CpuModelInfo *model, + Error **errp) +{ + return arch_query_cpu_model_expansion(type, model, errp); +} + void qmp_add_client(const char *protocol, const char *fdname, bool has_skipauth, bool skipauth, bool has_tls, bool tls, Error **errp) diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 55edd15d71..4929842d0b 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -1,4 +1,5 @@ stub-obj-y += arch-query-cpu-def.o +stub-obj-y += arch-query-cpu-model-expansion.o stub-obj-y += bdrv-next-monitor-owned.o stub-obj-y += blk-commit-all.o stub-obj-y += blockdev-close-all-bdrv-states.o diff --git a/stubs/arch-query-cpu-model-expansion.c b/stubs/arch-query-cpu-model-expansion.c new file mode 100644 index 0000000000..ae7cf554d1 --- /dev/null +++ b/stubs/arch-query-cpu-model-expansion.c @@ -0,0 +1,12 @@ +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "sysemu/arch_init.h" +#include "qapi/qmp/qerror.h" + +CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type, + CpuModelInfo *mode, + Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); + return NULL; +} -- cgit v1.2.3-55-g7522 From 0031e0d68339e7a919cf927119807ed882da6e4f Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 5 Sep 2016 10:52:40 +0200 Subject: qmp: add QMP interface "query-cpu-model-comparison" Let's provide a standardized interface to compare two CPU models. "query-cpu-model-compare" takes two models and returns how they compare in a specific configuration. The result will give guarantees about runnability. E.g. if a CPU model A is a subset of CPU model B, model A is guaranteed to run in configurations where model B runs, but not the other way around (might or might not run). Usually, CPU features or CPU generations are used to calculate the result. If a model is not guaranteed to run in a certain environment (e.g. incompatible), a compatible one can be created by "baselining" both models (follow up patch). Acked-by: Cornelia Huck Reviewed-by: Eduardo Habkost Signed-off-by: David Hildenbrand Message-Id: <20160905085244.99980-27-dahi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck --- include/sysemu/arch_init.h | 3 ++ qapi-schema.json | 86 +++++++++++++++++++++++++++++++++ qmp-commands.hx | 6 +++ qmp.c | 7 +++ stubs/Makefile.objs | 1 + stubs/arch-query-cpu-model-comparison.c | 12 +++++ 6 files changed, 115 insertions(+) create mode 100644 stubs/arch-query-cpu-model-comparison.c (limited to 'qapi-schema.json') diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h index 37b2e8675e..96d47c0dc8 100644 --- a/include/sysemu/arch_init.h +++ b/include/sysemu/arch_init.h @@ -38,5 +38,8 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp); CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type, CpuModelInfo *mode, Error **errp); +CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *modela, + CpuModelInfo *modelb, + Error **errp); #endif diff --git a/qapi-schema.json b/qapi-schema.json index 1c2daad087..8ab2ae9b78 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3158,6 +3158,92 @@ 'model': 'CpuModelInfo' }, 'returns': 'CpuModelExpansionInfo' } +## +# @CpuModelCompareResult: +# +# An enumeration of CPU model comparation results. The result is usually +# calcualted using e.g. CPU features or CPU generations. +# +# @incompatible: If model A is incompatible to model B, model A is not +# guaranteed to run where model B runs and the other way around. +# +# @identical: If model A is identical to model B, model A is guaranteed to run +# where model B runs and the other way around. +# +# @superset: If model A is a superset of model B, model B is guaranteed to run +# where model A runs. There are no guarantees about the other way. +# +# @subset: If model A is a subset of model B, model A is guaranteed to run +# where model B runs. There are no guarantees about the other way. +# +# Since: 2.8.0 +## +{ 'enum': 'CpuModelCompareResult', + 'data': [ 'incompatible', 'identical', 'superset', 'subset' ] } + +## +# @CpuModelCompareInfo +# +# The result of a CPU model comparison. +# +# @result: The result of the compare operation. +# @responsible-properties: List of properties that led to the comparison result +# not being identical. +# +# @responsible-properties is a list of QOM property names that led to +# both CPUs not being detected as identical. For identical models, this +# list is empty. +# If a QOM property is read-only, that means there's no known way to make the +# CPU models identical. If the special property name "type" is included, the +# models are by definition not identical and cannot be made identical. +# +# Since: 2.8.0 +## +{ 'struct': 'CpuModelCompareInfo', + 'data': {'result': 'CpuModelCompareResult', + 'responsible-properties': ['str'] + } +} + +## +# @query-cpu-model-comparison: +# +# Compares two CPU models, returning how they compare in a specific +# configuration. The results indicates how both models compare regarding +# runnability. This result can be used by tooling to make decisions if a +# certain CPU model will run in a certain configuration or if a compatible +# CPU model has to be created by baselining. +# +# Usually, a CPU model is compared against the maximum possible CPU model +# of a ceratin configuration (e.g. the "host" model for KVM). If that CPU +# model is identical or a subset, it will run in that configuration. +# +# The result returned by this command may be affected by: +# +# * QEMU version: CPU models may look different depending on the QEMU version. +# (Except for CPU models reported as "static" in query-cpu-definitions.) +# * machine-type: CPU model may look different depending on the machine-type. +# (Except for CPU models reported as "static" in query-cpu-definitions.) +# * machine options (including accelerator): in some architectures, CPU models +# may look different depending on machine and accelerator options. (Except for +# CPU models reported as "static" in query-cpu-definitions.) +# * "-cpu" arguments and global properties: arguments to the -cpu option and +# global properties may affect expansion of CPU models. Using +# query-cpu-model-expansion while using these is not advised. +# +# Some architectures may not support comparing CPU models. +# +# Returns: a CpuModelBaselineInfo. Returns an error if comparing CPU models is +# not supported, if a model cannot be used, if a model contains +# an unknown cpu definition name, unknown properties or properties +# with wrong types. +# +# Since: 2.8.0 +## +{ 'command': 'query-cpu-model-comparison', + 'data': { 'modela': 'CpuModelInfo', 'modelb': 'CpuModelInfo' }, + 'returns': 'CpuModelCompareInfo' } + # @AddfdInfo: # # Information about a file descriptor that was added to an fd set. diff --git a/qmp-commands.hx b/qmp-commands.hx index 26b91e41d2..70ad681aff 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -3947,6 +3947,12 @@ EQMP .mhandler.cmd_new = qmp_marshal_query_cpu_model_expansion, }, + { + .name = "query-cpu-model-comparison", + .args_type = "modela:q,modelb:q", + .mhandler.cmd_new = qmp_marshal_query_cpu_model_comparison, + }, + { .name = "query-target", .args_type = "", diff --git a/qmp.c b/qmp.c index 29fbfb811c..f55101969f 100644 --- a/qmp.c +++ b/qmp.c @@ -614,6 +614,13 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, return arch_query_cpu_model_expansion(type, model, errp); } +CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *modela, + CpuModelInfo *modelb, + Error **errp) +{ + return arch_query_cpu_model_comparison(modela, modelb, errp); +} + void qmp_add_client(const char *protocol, const char *fdname, bool has_skipauth, bool skipauth, bool has_tls, bool tls, Error **errp) diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 4929842d0b..da768f0149 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -1,5 +1,6 @@ stub-obj-y += arch-query-cpu-def.o stub-obj-y += arch-query-cpu-model-expansion.o +stub-obj-y += arch-query-cpu-model-comparison.o stub-obj-y += bdrv-next-monitor-owned.o stub-obj-y += blk-commit-all.o stub-obj-y += blockdev-close-all-bdrv-states.o diff --git a/stubs/arch-query-cpu-model-comparison.c b/stubs/arch-query-cpu-model-comparison.c new file mode 100644 index 0000000000..d5486ae980 --- /dev/null +++ b/stubs/arch-query-cpu-model-comparison.c @@ -0,0 +1,12 @@ +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "sysemu/arch_init.h" +#include "qapi/qmp/qerror.h" + +CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *modela, + CpuModelInfo *modelb, + Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); + return NULL; +} -- cgit v1.2.3-55-g7522 From b18b6043341dfad46cbda7804424a1604cea065b Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 5 Sep 2016 10:52:41 +0200 Subject: qmp: add QMP interface "query-cpu-model-baseline" Let's provide a standardized interface to baseline two CPU models, to create a third, compatible one. This is especially helpful when two CPU models are not identical, but a CPU model is required that is guaranteed to run under both configurations, where the original models run. "query-cpu-model-baseline" takes two CPU models and returns a third, compatible model. The result will always be a static CPU model. Acked-by: Cornelia Huck Reviewed-by: Eduardo Habkost Signed-off-by: David Hildenbrand Message-Id: <20160905085244.99980-28-dahi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck --- include/sysemu/arch_init.h | 3 +++ qapi-schema.json | 51 +++++++++++++++++++++++++++++++++++ qmp-commands.hx | 6 +++++ qmp.c | 7 +++++ stubs/Makefile.objs | 1 + stubs/arch-query-cpu-model-baseline.c | 12 +++++++++ 6 files changed, 80 insertions(+) create mode 100644 stubs/arch-query-cpu-model-baseline.c (limited to 'qapi-schema.json') diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h index 96d47c0dc8..1c9dad1b72 100644 --- a/include/sysemu/arch_init.h +++ b/include/sysemu/arch_init.h @@ -41,5 +41,8 @@ CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *modela, CpuModelInfo *modelb, Error **errp); +CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelInfo *modela, + CpuModelInfo *modelb, + Error **errp); #endif diff --git a/qapi-schema.json b/qapi-schema.json index 8ab2ae9b78..44cc71eb16 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3244,6 +3244,57 @@ 'data': { 'modela': 'CpuModelInfo', 'modelb': 'CpuModelInfo' }, 'returns': 'CpuModelCompareInfo' } +## +# @CpuModelBaselineInfo +# +# The result of a CPU model baseline. +# +# @model: the baselined CpuModelInfo. +# +# Since: 2.8.0 +## +{ 'struct': 'CpuModelBaselineInfo', + 'data': { 'model': 'CpuModelInfo' } } + +## +# @query-cpu-model-baseline: +# +# Baseline two CPU models, creating a compatible third model. The created +# model will always be a static, migration-safe CPU model (see "static" +# CPU model expansion for details). +# +# This interface can be used by tooling to create a compatible CPU model out +# two CPU models. The created CPU model will be identical to or a subset of +# both CPU models when comparing them. Therefore, the created CPU model is +# guaranteed to run where the given CPU models run. +# +# The result returned by this command may be affected by: +# +# * QEMU version: CPU models may look different depending on the QEMU version. +# (Except for CPU models reported as "static" in query-cpu-definitions.) +# * machine-type: CPU model may look different depending on the machine-type. +# (Except for CPU models reported as "static" in query-cpu-definitions.) +# * machine options (including accelerator): in some architectures, CPU models +# may look different depending on machine and accelerator options. (Except for +# CPU models reported as "static" in query-cpu-definitions.) +# * "-cpu" arguments and global properties: arguments to the -cpu option and +# global properties may affect expansion of CPU models. Using +# query-cpu-model-expansion while using these is not advised. +# +# Some architectures may not support baselining CPU models. +# +# Returns: a CpuModelBaselineInfo. Returns an error if baselining CPU models is +# not supported, if a model cannot be used, if a model contains +# an unknown cpu definition name, unknown properties or properties +# with wrong types. +# +# Since: 2.8.0 +## +{ 'command': 'query-cpu-model-baseline', + 'data': { 'modela': 'CpuModelInfo', + 'modelb': 'CpuModelInfo' }, + 'returns': 'CpuModelBaselineInfo' } + # @AddfdInfo: # # Information about a file descriptor that was added to an fd set. diff --git a/qmp-commands.hx b/qmp-commands.hx index 70ad681aff..5c8d1d5e9f 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -3953,6 +3953,12 @@ EQMP .mhandler.cmd_new = qmp_marshal_query_cpu_model_comparison, }, + { + .name = "query-cpu-model-baseline", + .args_type = "modela:q,modelb:q", + .mhandler.cmd_new = qmp_marshal_query_cpu_model_baseline, + }, + { .name = "query-target", .args_type = "", diff --git a/qmp.c b/qmp.c index f55101969f..dea8f81345 100644 --- a/qmp.c +++ b/qmp.c @@ -621,6 +621,13 @@ CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *modela, return arch_query_cpu_model_comparison(modela, modelb, errp); } +CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelInfo *modela, + CpuModelInfo *modelb, + Error **errp) +{ + return arch_query_cpu_model_baseline(modela, modelb, errp); +} + void qmp_add_client(const char *protocol, const char *fdname, bool has_skipauth, bool skipauth, bool has_tls, bool tls, Error **errp) diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index da768f0149..c5850e858e 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -1,6 +1,7 @@ stub-obj-y += arch-query-cpu-def.o stub-obj-y += arch-query-cpu-model-expansion.o stub-obj-y += arch-query-cpu-model-comparison.o +stub-obj-y += arch-query-cpu-model-baseline.o stub-obj-y += bdrv-next-monitor-owned.o stub-obj-y += blk-commit-all.o stub-obj-y += blockdev-close-all-bdrv-states.o diff --git a/stubs/arch-query-cpu-model-baseline.c b/stubs/arch-query-cpu-model-baseline.c new file mode 100644 index 0000000000..094ec13c2c --- /dev/null +++ b/stubs/arch-query-cpu-model-baseline.c @@ -0,0 +1,12 @@ +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "sysemu/arch_init.h" +#include "qapi/qmp/qerror.h" + +CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelInfo *modela, + CpuModelInfo *modelb, + Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); + return NULL; +} -- cgit v1.2.3-55-g7522 From 137974cea30120a80fc8e41c7a64afb0d4d6c2f6 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 5 Sep 2016 10:52:42 +0200 Subject: s390x/cpumodel: implement QMP interface "query-cpu-model-expansion" In order to expand CPU models, we create temporary cpus that handle the feature/group parsing. Only CPU feature properties are expanded. When converting the data structure back, we always fall back to the static base CPU model, which is by definition migration-safe. Acked-by: Cornelia Huck Signed-off-by: David Hildenbrand Message-Id: <20160905085244.99980-29-dahi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck --- qapi-schema.json | 3 +- target-s390x/cpu_models.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 1 deletion(-) (limited to 'qapi-schema.json') diff --git a/qapi-schema.json b/qapi-schema.json index 44cc71eb16..b06135c4ab 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3143,7 +3143,8 @@ # global properties may affect expansion of CPU models. Using # query-cpu-model-expansion while using these is not advised. # -# Some architectures may not support all expansion types. +# Some architectures may not support all expansion types. s390x supports +# "full" and "static". # # Returns: a CpuModelExpansionInfo. Returns an error if expanding CPU models is # not supported, if the model cannot be expanded, if the model contains diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c index d1e1a5f7c0..527a2b3ff2 100644 --- a/target-s390x/cpu_models.c +++ b/target-s390x/cpu_models.c @@ -16,6 +16,9 @@ #include "qapi/error.h" #include "qapi/visitor.h" #include "qemu/error-report.h" +#include "qapi/qmp/qerror.h" +#include "qapi/qmp-input-visitor.h" +#include "qapi/qmp/qbool.h" #ifndef CONFIG_USER_ONLY #include "sysemu/arch_init.h" #endif @@ -303,6 +306,150 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) return list; } + +static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info, + Error **errp) +{ + const QDict *qdict = NULL; + const QDictEntry *e; + Visitor *visitor; + ObjectClass *oc; + S390CPU *cpu; + Object *obj; + + if (info->props) { + qdict = qobject_to_qdict(info->props); + if (!qdict) { + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict"); + return; + } + } + + oc = cpu_class_by_name(TYPE_S390_CPU, info->name); + if (!oc) { + error_setg(errp, "The CPU definition \'%s\' is unknown.", info->name); + return; + } + if (S390_CPU_CLASS(oc)->kvm_required && !kvm_enabled()) { + error_setg(errp, "The CPU definition '%s' requires KVM", info->name); + return; + } + obj = object_new(object_class_get_name(oc)); + cpu = S390_CPU(obj); + + if (!cpu->model) { + error_setg(errp, "Details about the host CPU model are not available, " + "it cannot be used."); + object_unref(obj); + return; + } + + if (qdict) { + visitor = qmp_input_visitor_new(info->props, true); + visit_start_struct(visitor, NULL, NULL, 0, errp); + if (*errp) { + object_unref(obj); + return; + } + for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) { + object_property_set(obj, visitor, e->key, errp); + if (*errp) { + break; + } + } + if (!*errp) { + visit_check_struct(visitor, errp); + } + visit_end_struct(visitor, NULL); + visit_free(visitor); + if (*errp) { + object_unref(obj); + return; + } + } + + /* copy the model and throw the cpu away */ + memcpy(model, cpu->model, sizeof(*model)); + object_unref(obj); +} + +static void qdict_add_disabled_feat(const char *name, void *opaque) +{ + qdict_put((QDict *) opaque, name, qbool_from_bool(false)); +} + +static void qdict_add_enabled_feat(const char *name, void *opaque) +{ + qdict_put((QDict *) opaque, name, qbool_from_bool(true)); +} + +/* convert S390CPUDef into a static CpuModelInfo */ +static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model, + bool delta_changes) +{ + QDict *qdict = qdict_new(); + S390FeatBitmap bitmap; + + /* always fallback to the static base model */ + info->name = g_strdup_printf("%s-base", model->def->name); + + if (delta_changes) { + /* features deleted from the base feature set */ + bitmap_andnot(bitmap, model->def->base_feat, model->features, + S390_FEAT_MAX); + if (!bitmap_empty(bitmap, S390_FEAT_MAX)) { + s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat); + } + + /* features added to the base feature set */ + bitmap_andnot(bitmap, model->features, model->def->base_feat, + S390_FEAT_MAX); + if (!bitmap_empty(bitmap, S390_FEAT_MAX)) { + s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_enabled_feat); + } + } else { + /* expand all features */ + s390_feat_bitmap_to_ascii(model->features, qdict, + qdict_add_enabled_feat); + bitmap_complement(bitmap, model->features, S390_FEAT_MAX); + s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat); + } + + if (!qdict_size(qdict)) { + QDECREF(qdict); + } else { + info->props = QOBJECT(qdict); + info->has_props = true; + } +} + +CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type, + CpuModelInfo *model, + Error **errp) +{ + CpuModelExpansionInfo *expansion_info = NULL; + S390CPUModel s390_model; + bool delta_changes = false; + + /* convert it to our internal representation */ + cpu_model_from_info(&s390_model, model, errp); + if (*errp) { + return NULL; + } + + if (type == CPU_MODEL_EXPANSION_TYPE_STATIC) { + delta_changes = true; + } else if (type != CPU_MODEL_EXPANSION_TYPE_FULL) { + error_setg(errp, "The requested expansion type is not supported."); + return NULL; + } + + /* convert it back to a static representation */ + expansion_info = g_malloc0(sizeof(*expansion_info)); + expansion_info->model = g_malloc0(sizeof(*expansion_info->model)); + cpu_info_from_model(expansion_info->model, &s390_model, delta_changes); + return expansion_info; +} #endif static void check_consistency(const S390CPUModel *model) -- cgit v1.2.3-55-g7522 From 4e82ef05029f27a39c6259bd967e4f46988d176c Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 5 Sep 2016 10:52:43 +0200 Subject: s390x/cpumodel: implement QMP interface "query-cpu-model-comparison" Let's implement that interface by reusing our convertion code implemented for expansion. We use CPU generations and CPU features to calculate the result. This means, that a zEC12 cannot simply be converted into a z13 by stripping of features. This is required, as other magic values (e.g. maximum address sizes) belong to a CPU generation and cannot simply be emulated by an older generation. Acked-by: Cornelia Huck Signed-off-by: David Hildenbrand Message-Id: <20160905085244.99980-30-dahi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck --- qapi-schema.json | 3 +- target-s390x/cpu_models.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) (limited to 'qapi-schema.json') diff --git a/qapi-schema.json b/qapi-schema.json index b06135c4ab..955a2b9452 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3232,7 +3232,8 @@ # global properties may affect expansion of CPU models. Using # query-cpu-model-expansion while using these is not advised. # -# Some architectures may not support comparing CPU models. +# Some architectures may not support comparing CPU models. s390x supports +# comparing CPU models. # # Returns: a CpuModelBaselineInfo. Returns an error if comparing CPU models is # not supported, if a model cannot be used, if a model contains diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c index 527a2b3ff2..20c251cd87 100644 --- a/target-s390x/cpu_models.c +++ b/target-s390x/cpu_models.c @@ -450,6 +450,90 @@ CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type cpu_info_from_model(expansion_info->model, &s390_model, delta_changes); return expansion_info; } + +static void list_add_feat(const char *name, void *opaque) +{ + strList **last = (strList **) opaque; + strList *entry; + + entry = g_malloc0(sizeof(*entry)); + entry->value = g_strdup(name); + entry->next = *last; + *last = entry; +} + +CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *infoa, + CpuModelInfo *infob, + Error **errp) +{ + CpuModelCompareResult feat_result, gen_result; + CpuModelCompareInfo *compare_info; + S390FeatBitmap missing, added; + S390CPUModel modela, modelb; + + /* convert both models to our internal representation */ + cpu_model_from_info(&modela, infoa, errp); + if (*errp) { + return NULL; + } + cpu_model_from_info(&modelb, infob, errp); + if (*errp) { + return NULL; + } + compare_info = g_malloc0(sizeof(*compare_info)); + + /* check the cpu generation and ga level */ + if (modela.def->gen == modelb.def->gen) { + if (modela.def->ec_ga == modelb.def->ec_ga) { + /* ec and corresponding bc are identical */ + gen_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL; + } else if (modela.def->ec_ga < modelb.def->ec_ga) { + gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET; + } else { + gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; + } + } else if (modela.def->gen < modelb.def->gen) { + gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET; + } else { + gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; + } + if (gen_result != CPU_MODEL_COMPARE_RESULT_IDENTICAL) { + /* both models cannot be made identical */ + list_add_feat("type", &compare_info->responsible_properties); + } + + /* check the feature set */ + if (bitmap_equal(modela.features, modelb.features, S390_FEAT_MAX)) { + feat_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL; + } else { + bitmap_andnot(missing, modela.features, modelb.features, S390_FEAT_MAX); + s390_feat_bitmap_to_ascii(missing, + &compare_info->responsible_properties, + list_add_feat); + bitmap_andnot(added, modelb.features, modela.features, S390_FEAT_MAX); + s390_feat_bitmap_to_ascii(added, &compare_info->responsible_properties, + list_add_feat); + if (bitmap_empty(missing, S390_FEAT_MAX)) { + feat_result = CPU_MODEL_COMPARE_RESULT_SUBSET; + } else if (bitmap_empty(added, S390_FEAT_MAX)) { + feat_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; + } else { + feat_result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE; + } + } + + /* combine the results */ + if (gen_result == feat_result) { + compare_info->result = gen_result; + } else if (feat_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) { + compare_info->result = gen_result; + } else if (gen_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) { + compare_info->result = feat_result; + } else { + compare_info->result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE; + } + return compare_info; +} #endif static void check_consistency(const S390CPUModel *model) -- cgit v1.2.3-55-g7522 From f1a47d08effc4f2a33c667942e394c6f32a4f7d6 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 5 Sep 2016 10:52:44 +0200 Subject: s390x/cpumodel: implement QMP interface "query-cpu-model-baseline" Let's implement that interface by reusing our conversion code and lookup code for CPU definitions. In order to find a compatible CPU model, we first detect the maximum possible CPU generation and then try to find a maximum model, satisfying all base features (not exceeding the maximum generation). Acked-by: Cornelia Huck Signed-off-by: David Hildenbrand Message-Id: <20160905085244.99980-31-dahi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck --- qapi-schema.json | 3 ++- target-s390x/cpu_models.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) (limited to 'qapi-schema.json') diff --git a/qapi-schema.json b/qapi-schema.json index 955a2b9452..c4f3674d08 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3283,7 +3283,8 @@ # global properties may affect expansion of CPU models. Using # query-cpu-model-expansion while using these is not advised. # -# Some architectures may not support baselining CPU models. +# Some architectures may not support baselining CPU models. s390x supports +# baselining CPU models. # # Returns: a CpuModelBaselineInfo. Returns an error if baselining CPU models is # not supported, if a model cannot be used, if a model contains diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c index 20c251cd87..3ff6a702f9 100644 --- a/target-s390x/cpu_models.c +++ b/target-s390x/cpu_models.c @@ -534,6 +534,61 @@ CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *infoa, } return compare_info; } + +CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelInfo *infoa, + CpuModelInfo *infob, + Error **errp) +{ + CpuModelBaselineInfo *baseline_info; + S390CPUModel modela, modelb, model; + uint16_t cpu_type; + uint8_t max_gen_ga; + uint8_t max_gen; + + /* convert both models to our internal representation */ + cpu_model_from_info(&modela, infoa, errp); + if (*errp) { + return NULL; + } + + cpu_model_from_info(&modelb, infob, errp); + if (*errp) { + return NULL; + } + + /* features both models support */ + bitmap_and(model.features, modela.features, modelb.features, S390_FEAT_MAX); + + /* detect the maximum model not regarding features */ + if (modela.def->gen == modelb.def->gen) { + if (modela.def->type == modelb.def->type) { + cpu_type = modela.def->type; + } else { + cpu_type = 0; + } + max_gen = modela.def->gen; + max_gen_ga = MIN(modela.def->ec_ga, modelb.def->ec_ga); + } else if (modela.def->gen > modelb.def->gen) { + cpu_type = modelb.def->type; + max_gen = modelb.def->gen; + max_gen_ga = modelb.def->ec_ga; + } else { + cpu_type = modela.def->type; + max_gen = modela.def->gen; + max_gen_ga = modela.def->ec_ga; + } + + model.def = s390_find_cpu_def(cpu_type, max_gen, max_gen_ga, + model.features); + /* strip off features not part of the max model */ + bitmap_and(model.features, model.features, model.def->full_feat, + S390_FEAT_MAX); + + baseline_info = g_malloc0(sizeof(*baseline_info)); + baseline_info->model = g_malloc0(sizeof(*baseline_info->model)); + cpu_info_from_model(baseline_info->model, &model, true); + return baseline_info; +} #endif static void check_consistency(const S390CPUModel *model) -- cgit v1.2.3-55-g7522