summaryrefslogtreecommitdiff
path: root/target/i386
diff options
context:
space:
mode:
authorEduardo Habkost <ehabkost@redhat.com>2017-03-09 15:12:11 -0300
committerEduardo Habkost <ehabkost@redhat.com>2017-03-10 15:01:08 -0300
commit40e80ee4113ad957b633cbdddb7423952bb76974 (patch)
tree54df8544831856ced94977110910f38849288a0d /target/i386
parent20271d484069f154fb262507e63adc3a37e885d2 (diff)
downloadqemu-40e80ee4113ad957b633cbdddb7423952bb76974.tar.gz
i386/kvm: Blacklist TSX on known broken hosts
Some Intel CPUs are known to have a broken TSX implementation. A microcode update from Intel disabled TSX on those CPUs, but GET_SUPPORTED_CPUID might be reporting it as supported if the hosts were not updated yet. Manually fixup the GET_SUPPORTED_CPUID data to ensure we will never enable TSX when running on those hosts. Reference: * glibc commit 2702856bf45c82cf8e69f2064f5aa15c0ceb6359: https://sourceware.org/git/?p=glibc.git;a=commit;h=2702856bf45c82cf8e69f2064f5aa15c0ceb6359 Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Message-Id: <20170309181212.18864-3-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Diffstat (limited to 'target/i386')
-rw-r--r--target/i386/kvm.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 887a81268f..472399fb2c 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -266,6 +266,19 @@ static int get_para_features(KVMState *s)
return features;
}
+static bool host_tsx_blacklisted(void)
+{
+ int family, model, stepping;\
+ char vendor[CPUID_VENDOR_SZ + 1];
+
+ host_vendor_fms(vendor, &family, &model, &stepping);
+
+ /* Check if we are running on a Haswell host known to have broken TSX */
+ return !strcmp(vendor, CPUID_VENDOR_INTEL) &&
+ (family == 6) &&
+ ((model == 63 && stepping < 4) ||
+ model == 60 || model == 69 || model == 70);
+}
/* Returns the value for a specific register on the cpuid entry
*/
@@ -349,6 +362,10 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
}
} else if (function == 6 && reg == R_EAX) {
ret |= CPUID_6_EAX_ARAT; /* safe to allow because of emulated APIC */
+ } else if (function == 7 && index == 0 && reg == R_EBX) {
+ if (host_tsx_blacklisted()) {
+ ret &= ~(CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_HLE);
+ }
} else if (function == 0x80000001 && reg == R_EDX) {
/* On Intel, kvm returns cpuid according to the Intel spec,
* so add missing bits according to the AMD spec: