The KVM capability, KVM_CAP_S390_CPU_TOPOLOGY is used to activate the S390_FEAT_CONFIGURATION_TOPOLOGY feature and the topology facility for the guest in the case the topology is available in QEMU and in KVM. The feature is fenced for SE (secure execution). To allow smooth migration with old QEMU the feature is disabled by default using the CPU flag -disable-topology. Making the S390_FEAT_CONFIGURATION_TOPOLOGY belonging to the default features makes the -ctop CPU flag is no more necessary, turning the topology feature on is done with -disable-topology only. Signed-off-by: Pierre Morel <pmorel@xxxxxxxxxxxxx> --- include/hw/s390x/cpu-topology.h | 5 +---- target/s390x/cpu_features_def.h.inc | 1 + target/s390x/cpu_models.c | 17 +++++++++++++++++ target/s390x/cpu_topology.c | 5 +++++ target/s390x/gen-features.c | 3 +++ target/s390x/kvm/kvm.c | 14 ++++++++++++++ 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/include/hw/s390x/cpu-topology.h b/include/hw/s390x/cpu-topology.h index e88059ccec..b2fa24ba93 100644 --- a/include/hw/s390x/cpu-topology.h +++ b/include/hw/s390x/cpu-topology.h @@ -36,9 +36,6 @@ struct S390Topology { #define TYPE_S390_CPU_TOPOLOGY "s390-topology" OBJECT_DECLARE_SIMPLE_TYPE(S390Topology, S390_CPU_TOPOLOGY) -static inline bool s390_has_topology(void) -{ - return false; -} +bool s390_has_topology(void); #endif diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc index e3cfe63735..016a720e38 100644 --- a/target/s390x/cpu_features_def.h.inc +++ b/target/s390x/cpu_features_def.h.inc @@ -147,6 +147,7 @@ DEF_FEAT(SIE_CEI, "cei", SCLP_CPU, 43, "SIE: Conditional-external-interception f DEF_FEAT(DAT_ENH_2, "dateh2", MISC, 0, "DAT-enhancement facility 2") DEF_FEAT(CMM, "cmm", MISC, 0, "Collaborative-memory-management facility") DEF_FEAT(AP, "ap", MISC, 0, "AP instructions installed") +DEF_FEAT(DISABLE_CPU_TOPOLOGY, "disable-topology", MISC, 0, "Disable CPU Topology") /* Features exposed via the PLO instruction. */ DEF_FEAT(PLO_CL, "plo-cl", PLO, 0, "PLO Compare and load (32 bit in general registers)") diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c index c3a4f80633..1f5348d6a3 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -253,6 +253,7 @@ bool s390_has_feat(S390Feat feat) case S390_FEAT_SIE_CMMA: case S390_FEAT_SIE_PFMFI: case S390_FEAT_SIE_IBS: + case S390_FEAT_CONFIGURATION_TOPOLOGY: return false; break; default: @@ -422,6 +423,21 @@ void s390_cpu_list(void) } } +static void check_incompatibility(S390CPUModel *model, Error **errp) +{ + static int dep[][2] = { + { S390_FEAT_CONFIGURATION_TOPOLOGY, S390_FEAT_DISABLE_CPU_TOPOLOGY }, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(dep); i++) { + if (test_bit(dep[i][0], model->features) && + test_bit(dep[i][1], model->features)) { + clear_bit(dep[i][0], model->features); + } + } +} + static void check_consistency(const S390CPUModel *model) { static int dep[][2] = { @@ -592,6 +608,7 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp) cpu->model->cpu_id_format = max_model->cpu_id_format; cpu->model->cpu_ver = max_model->cpu_ver; + check_incompatibility(cpu->model, &err); check_consistency(cpu->model); check_compatibility(max_model, cpu->model, &err); if (err) { diff --git a/target/s390x/cpu_topology.c b/target/s390x/cpu_topology.c index b81f016ba1..8123e6ddf0 100644 --- a/target/s390x/cpu_topology.c +++ b/target/s390x/cpu_topology.c @@ -15,6 +15,11 @@ #include "hw/s390x/cpu-topology.h" #include "hw/s390x/sclp.h" +bool s390_has_topology(void) +{ + return s390_has_feat(S390_FEAT_CONFIGURATION_TOPOLOGY); +} + /* * s390_topology_add_cpu: * @topo: pointer to the topology diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 1e3b7c0dc9..f3acfdd9a5 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -488,6 +488,7 @@ static uint16_t full_GEN9_GA3[] = { static uint16_t full_GEN10_GA1[] = { S390_FEAT_EDAT, S390_FEAT_CONFIGURATION_TOPOLOGY, + S390_FEAT_DISABLE_CPU_TOPOLOGY, S390_FEAT_GROUP_MSA_EXT_2, S390_FEAT_ESOP, S390_FEAT_SIE_PFMFI, @@ -605,6 +606,8 @@ static uint16_t default_GEN9_GA1[] = { static uint16_t default_GEN10_GA1[] = { S390_FEAT_EDAT, S390_FEAT_GROUP_MSA_EXT_2, + S390_FEAT_DISABLE_CPU_TOPOLOGY, + S390_FEAT_CONFIGURATION_TOPOLOGY, }; #define default_GEN10_GA2 EmptyFeat diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c index a79fdf1c79..ec2c9fd8fa 100644 --- a/target/s390x/kvm/kvm.c +++ b/target/s390x/kvm/kvm.c @@ -2471,6 +2471,20 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp) set_bit(S390_FEAT_UNPACK, model->features); } + /* + * If we have support for CPU Topology prevent overrule + * S390_FEAT_CONFIGURATION_TOPOLOGY with S390_FEAT_DISABLE_CPU_TOPOLOGY + * implemented in KVM, activate the CPU TOPOLOGY feature. + */ + if (kvm_check_extension(kvm_state, KVM_CAP_S390_CPU_TOPOLOGY)) { + if (kvm_vm_enable_cap(kvm_state, KVM_CAP_S390_CPU_TOPOLOGY, 0) < 0) { + error_setg(errp, "KVM: Error enabling KVM_CAP_S390_CPU_TOPOLOGY"); + return; + } + set_bit(S390_FEAT_CONFIGURATION_TOPOLOGY, model->features); + set_bit(S390_FEAT_DISABLE_CPU_TOPOLOGY, model->features); + } + /* We emulate a zPCI bus and AEN, therefore we don't need HW support */ set_bit(S390_FEAT_ZPCI, model->features); set_bit(S390_FEAT_ADAPTER_EVENT_NOTIFICATION, model->features); -- 2.31.1