summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/hyperv.txt13
-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
5 files changed, 44 insertions, 0 deletions
diff --git a/docs/hyperv.txt b/docs/hyperv.txt
index 8fdf25c829..6518b716a9 100644
--- a/docs/hyperv.txt
+++ b/docs/hyperv.txt
@@ -184,6 +184,19 @@ enabled.
Requires: hv-vpindex, hv-synic, hv-time, hv-stimer
+3.17. hv-no-nonarch-coresharing=on/off/auto
+===========================================
+This enlightenment tells guest OS that virtual processors will never share a
+physical core unless they are reported as sibling SMT threads. This information
+is required by Windows and Hyper-V guests to properly mitigate SMT related CPU
+vulnerabilities.
+When the option is set to 'auto' QEMU will enable the feature only when KVM
+reports that non-architectural coresharing is impossible, this means that
+hyper-threading is not supported or completely disabled on the host. This
+setting also prevents migration as SMT settings on the destination may differ.
+When the option is set to 'on' QEMU will always enable the feature, regardless
+of host setup. To keep guests secure, this can only be used in conjunction with
+exposing correct vCPU topology and vCPU pinning.
4. Development features
========================
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 47200b40c1..6c87c99487 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 cedb5bc205..c50a9c7257 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 cffac10b45..056a305be3 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 0e3da998d1..49a301190a 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