diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-03-13 13:16:35 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-03-13 13:16:35 +0000 |
commit | f962709c69a05183bf314d3d8c69802d1e3f139c (patch) | |
tree | 2a121ac278ccbed5e2624b282572fa0377bf8f94 /target/i386/kvm.c | |
parent | b1616fe0e2a311f5951cc51800a17a920b20a129 (diff) | |
parent | ec56a4a7b07e2943f49da273a31e3195083b1f2e (diff) |
Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging
x86: Haswell TSX blacklist fix for 2.9
# gpg: Signature made Fri 10 Mar 2017 18:45:08 GMT
# gpg: using RSA key 0x2807936F984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF D1AA 2807 936F 984D C5A6
* remotes/ehabkost/tags/x86-pull-request:
i386: Change stepping of Haswell to non-blacklisted value
i386/kvm: Blacklist TSX on known broken hosts
i386: host_vendor_fms() helper function
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/i386/kvm.c')
-rw-r--r-- | target/i386/kvm.c | 17 |
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: |