aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorVitaly Kuznetsov <vkuznets@redhat.com>2019-10-18 18:39:08 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2019-10-22 09:38:42 +0200
commit30d6ff662d0411fcb98a577e58582690fc2c513c (patch)
tree4a13f942c1e50fcccac5f0066c67e7bb3e222d66 /target
parentf1733749709b2f6935493e8183afe1ce6c80d52d (diff)
downloadqemu-30d6ff662d0411fcb98a577e58582690fc2c513c.zip
qemu-30d6ff662d0411fcb98a577e58582690fc2c513c.tar.gz
qemu-30d6ff662d0411fcb98a577e58582690fc2c513c.tar.bz2
i386/kvm: add NoNonArchitecturalCoreSharing Hyper-V enlightenment
Hyper-V TLFS specifies this enlightenment as: "NoNonArchitecturalCoreSharing - Indicates that a virtual processor will never share a physical core with another virtual processor, except for virtual processors that are reported as sibling SMT threads. This can be used as an optimization to avoid the performance overhead of STIBP". However, STIBP is not the only implication. It was found that Hyper-V on KVM doesn't pass MD_CLEAR bit to its guests if it doesn't see NoNonArchitecturalCoreSharing bit. KVM reports NoNonArchitecturalCoreSharing in KVM_GET_SUPPORTED_HV_CPUID to indicate that SMT on the host is impossible (not supported of forcefully disabled). Implement NoNonArchitecturalCoreSharing support in QEMU as tristate: 'off' - the feature is disabled (default) 'on' - the feature is enabled. This is only safe if vCPUS are properly pinned and correct topology is exposed. As CPU pinning is done outside of QEMU the enablement decision will be made on a higher level. 'auto' - copy KVM setting. As during live migration SMT settings on the source and destination host may differ this requires us to add a migration blocker. Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> Message-Id: <20191018163908.10246-1-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target')
-rw-r--r--target/i386/cpu.c2
-rw-r--r--target/i386/cpu.h2
-rw-r--r--target/i386/hyperv-proto.h1
-rw-r--r--target/i386/kvm.c26
4 files changed, 31 insertions, 0 deletions
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 47200b4..6c87c99 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6174,6 +6174,8 @@ static Property x86_cpu_properties[] = {
HYPERV_FEAT_IPI, 0),
DEFINE_PROP_BIT64("hv-stimer-direct", X86CPU, hyperv_features,
HYPERV_FEAT_STIMER_DIRECT, 0),
+ DEFINE_PROP_ON_OFF_AUTO("hv-no-nonarch-coresharing", X86CPU,
+ hyperv_no_nonarch_cs, ON_OFF_AUTO_OFF),
DEFINE_PROP_BOOL("hv-passthrough", X86CPU, hyperv_passthrough, false),
DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index cedb5bc..c50a9c7 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -24,6 +24,7 @@
#include "cpu-qom.h"
#include "hyperv-proto.h"
#include "exec/cpu-defs.h"
+#include "qapi/qapi-types-common.h"
/* The x86 has a strong memory model with some store-after-load re-ordering */
#define TCG_GUEST_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD)
@@ -1614,6 +1615,7 @@ struct X86CPU {
bool hyperv_synic_kvm_only;
uint64_t hyperv_features;
bool hyperv_passthrough;
+ OnOffAuto hyperv_no_nonarch_cs;
bool check_cpuid;
bool enforce_cpuid;
diff --git a/target/i386/hyperv-proto.h b/target/i386/hyperv-proto.h
index cffac10..056a305 100644
--- a/target/i386/hyperv-proto.h
+++ b/target/i386/hyperv-proto.h
@@ -63,6 +63,7 @@
#define HV_CLUSTER_IPI_RECOMMENDED (1u << 10)
#define HV_EX_PROCESSOR_MASKS_RECOMMENDED (1u << 11)
#define HV_ENLIGHTENED_VMCS_RECOMMENDED (1u << 14)
+#define HV_NO_NONARCH_CORESHARING (1u << 18)
/*
* Basic virtualized MSRs
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 0e3da99..49a3011 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -1227,6 +1227,16 @@ static int hyperv_handle_properties(CPUState *cs,
}
}
+ if (cpu->hyperv_no_nonarch_cs == ON_OFF_AUTO_ON) {
+ env->features[FEAT_HV_RECOMM_EAX] |= HV_NO_NONARCH_CORESHARING;
+ } else if (cpu->hyperv_no_nonarch_cs == ON_OFF_AUTO_AUTO) {
+ c = cpuid_find_entry(cpuid, HV_CPUID_ENLIGHTMENT_INFO, 0);
+ if (c) {
+ env->features[FEAT_HV_RECOMM_EAX] |=
+ c->eax & HV_NO_NONARCH_CORESHARING;
+ }
+ }
+
/* Features */
r = hv_cpuid_check_and_set(cs, cpuid, HYPERV_FEAT_RELAXED);
r |= hv_cpuid_check_and_set(cs, cpuid, HYPERV_FEAT_VAPIC);
@@ -1340,6 +1350,7 @@ free:
}
static Error *hv_passthrough_mig_blocker;
+static Error *hv_no_nonarch_cs_mig_blocker;
static int hyperv_init_vcpu(X86CPU *cpu)
{
@@ -1359,6 +1370,21 @@ static int hyperv_init_vcpu(X86CPU *cpu)
}
}
+ if (cpu->hyperv_no_nonarch_cs == ON_OFF_AUTO_AUTO &&
+ hv_no_nonarch_cs_mig_blocker == NULL) {
+ error_setg(&hv_no_nonarch_cs_mig_blocker,
+ "'hv-no-nonarch-coresharing=auto' CPU flag prevents migration"
+ " use explicit 'hv-no-nonarch-coresharing=on' instead (but"
+ " make sure SMT is disabled and/or that vCPUs are properly"
+ " pinned)");
+ ret = migrate_add_blocker(hv_no_nonarch_cs_mig_blocker, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ error_free(hv_no_nonarch_cs_mig_blocker);
+ return ret;
+ }
+ }
+
if (hyperv_feat_enabled(cpu, HYPERV_FEAT_VPINDEX) && !hv_vpindex_settable) {
/*
* the kernel doesn't support setting vp_index; assert that its value