mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-24 03:59:52 +00:00
x86: Haswell TSX blacklist fix for 2.9
-----BEGIN PGP SIGNATURE----- iQIcBAABCAAGBQJYwvQ0AAoJECgHk2+YTcWm+3IP/jIZI6jPXOK3P/nDI2KoIxiI PiRylMc8JyEVkZLb79RjBBjpuD41eMdXGK/ihPe8j6hTmOrsX1XIVq0MG0zEwZSb 3lY5AWdqA1pjFPO7Zvsxb7xGUgdcmh3T6vRHvOefFZuVQOh/U5Idi7vUyHKdA782 yTYvn1UzRm4YRDnvxVleDDBlKYhH6mNNEpXvT33IANLWBxY0obO047eYn2WOvfNL zPRGgqr7q+YFqSNgh3e7VkANYP1bd+eaL/Jw/Jye4HDotVUsavCte/Lk+6fmhEt0 8O3IYM0lo5gQHQA2PcOj3t3NX1Ri/ECMWCZb/CDTo9g85RgXUk0yVgzVWcKpIbt9 T6DRk5A/olyfskShiTBDG/h0hY+RnJMKCnl1Sr3T+ENKduI+qmk/ahbmXYPaisbx CHRrD/8XDKprzx3Its4ExTN2TvVd1zZixNFvBL9b/niKOaPt8jhlzlf3etbheueR Dh6sd8ICeOeOluBNFv1EAkXPsy91CUvdl05NAvrSTVqPSbY8AeyTC85zZbDhfs9u +2VPhb0Ik2Bnkceizl/6bxSve9th6mCjV453T+P73DwaQirYOourgVEkbCpnxk4d C3znROInWL+SMz2wBPTb6htgzzMVx8QT+81zOsOFTRdJU3emYkm3x9xz3p28Y3dc p2pv8s8AmWGcNstkH/cv =pA6b -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
f962709c69
@ -389,6 +389,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
|
||||
.driver = TYPE_X86_CPU,\
|
||||
.property = "vmware-cpuid-freq",\
|
||||
.value = "off",\
|
||||
},\
|
||||
{\
|
||||
.driver = "Haswell-" TYPE_X86_CPU,\
|
||||
.property = "stepping",\
|
||||
.value = "1",\
|
||||
},
|
||||
|
||||
#define PC_COMPAT_2_7 \
|
||||
|
@ -688,6 +688,25 @@ void host_cpuid(uint32_t function, uint32_t count,
|
||||
*edx = vec[3];
|
||||
}
|
||||
|
||||
void host_vendor_fms(char *vendor, int *family, int *model, int *stepping)
|
||||
{
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
||||
host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
|
||||
x86_cpu_vendor_words2str(vendor, ebx, edx, ecx);
|
||||
|
||||
host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
|
||||
if (family) {
|
||||
*family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
|
||||
}
|
||||
if (model) {
|
||||
*model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
|
||||
}
|
||||
if (stepping) {
|
||||
*stepping = eax & 0x0F;
|
||||
}
|
||||
}
|
||||
|
||||
/* CPU class name definitions: */
|
||||
|
||||
#define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU
|
||||
@ -1177,7 +1196,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
||||
.vendor = CPUID_VENDOR_INTEL,
|
||||
.family = 6,
|
||||
.model = 60,
|
||||
.stepping = 1,
|
||||
.stepping = 4,
|
||||
.features[FEAT_1_EDX] =
|
||||
CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
|
||||
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
|
||||
|
@ -1440,6 +1440,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
void cpu_clear_apic_feature(CPUX86State *env);
|
||||
void host_cpuid(uint32_t function, uint32_t count,
|
||||
uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
|
||||
void host_vendor_fms(char *vendor, int *family, int *model, int *stepping);
|
||||
|
||||
/* helper.c */
|
||||
int x86_cpu_handle_mmu_fault(CPUState *cpu, vaddr addr,
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user