From: GNU Libc Maintainers Date: Mon, 16 Jan 2017 17:43:37 +0000 (+0000) Subject: local-blacklist-for-Intel-TSX X-Git-Tag: archive/raspbian/2.25-3+rpi1~1^2^2^2^2^2^2^2~166 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=1866d6a9433c1e00fa5d3888af5a289505fe8e79;p=glibc.git local-blacklist-for-Intel-TSX Intel TSX is broken on Haswell based processors (erratum HSD136/HSW136) and a microcode update is available to simply disable the corresponding instructions. A live microcode update will disable the TSX instructions causing already started binaries to segfault. This patch simply disable Intel TSX (HLE and RTM) on processors which might receive a microcode update, so that it doesn't happen. We might expect newer steppings to fix the issue (e.g. as Haswell-EX did). Intel TSX-NI is also broken on Broadwell systems, and documented as being unavailable in their specification updates errata list. However, some end-user systems were shipped with old microcode that left Intel TSX-NI still enabled in CPUID on these processors. We must not allow RTM to be used by glibc on these systems, due to runtime system misbehavior and live-update of microcode hazards. Author: Henrique de Moraes Holschuh Gbp-Pq: Topic amd64 Gbp-Pq: Name local-blacklist-for-Intel-TSX.diff --- diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c index 11b9af223..a248c4c78 100644 --- a/sysdeps/x86/cpu-features.c +++ b/sysdeps/x86/cpu-features.c @@ -22,7 +22,8 @@ static void get_common_indeces (struct cpu_features *cpu_features, unsigned int *family, unsigned int *model, - unsigned int *extended_model) + unsigned int *extended_model, + unsigned int *stepping) { if (family) { @@ -34,6 +35,7 @@ get_common_indeces (struct cpu_features *cpu_features, *family = (eax >> 8) & 0x0f; *model = (eax >> 4) & 0x0f; *extended_model = (eax >> 12) & 0xf0; + *stepping = eax & 0x0f; if (*family == 0x0f) { *family += (eax >> 20) & 0xff; @@ -97,6 +99,7 @@ init_cpu_features (struct cpu_features *cpu_features) unsigned int ebx, ecx, edx; unsigned int family = 0; unsigned int model = 0; + unsigned int stepping = 0; enum cpu_features_kind kind; #if !HAS_CPUID @@ -116,7 +119,8 @@ init_cpu_features (struct cpu_features *cpu_features) kind = arch_kind_intel; - get_common_indeces (cpu_features, &family, &model, &extended_model); + get_common_indeces (cpu_features, &family, &model, + &extended_model, &stepping); if (family == 0x06) { @@ -227,7 +231,8 @@ init_cpu_features (struct cpu_features *cpu_features) kind = arch_kind_amd; - get_common_indeces (cpu_features, &family, &model, &extended_model); + get_common_indeces (cpu_features, &family, &model, + &extended_model, &stepping); ecx = cpu_features->cpuid[COMMON_CPUID_INDEX_1].ecx; @@ -264,7 +269,7 @@ init_cpu_features (struct cpu_features *cpu_features) else { kind = arch_kind_other; - get_common_indeces (cpu_features, NULL, NULL, NULL); + get_common_indeces (cpu_features, NULL, NULL, NULL, NULL); } /* Support i586 if CX8 is available. */ @@ -275,6 +280,24 @@ init_cpu_features (struct cpu_features *cpu_features) if (CPU_FEATURES_CPU_P (cpu_features, CMOV)) cpu_features->feature[index_arch_I686] |= bit_arch_I686; + /* Disable Intel TSX (HLE and RTM) due to erratum HSD136/HSW136 + on all Haswell processors, except Haswell-EX/Xeon E7-v3 (306F4), + to work around outdated microcode that doesn't disable the + broken feature by default. + + Disable TSX on Broadwell, due to errata BDM53/BDW51/BDD51/ + BDE42. The errata documentation states that RTM is unusable, + and that it should not be advertised by CPUID at all on any + such processors. Unfortunately, it _is_ advertised in some + (older) microcode versions. Exceptions: Broadwell-E (406Fx), + likely already fixed at launch */ + if (kind == arch_kind_intel && family == 6 && + ((model == 63 && stepping <= 2) || (model == 60 && stepping <= 3) || + (model == 69 && stepping <= 1) || (model == 70 && stepping <= 1) || + (model == 61 && stepping <= 4) || (model == 71 && stepping <= 1) || + (model == 86 && stepping <= 2) )) + cpu_features->cpuid[COMMON_CPUID_INDEX_7].ebx &= ~(bit_cpu_RTM | bit_cpu_HLE); + #if !HAS_CPUID no_cpuid: #endif diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/cpu-features.h index a8b5a734b..29eaededd 100644 --- a/sysdeps/x86/cpu-features.h +++ b/sysdeps/x86/cpu-features.h @@ -57,6 +57,7 @@ #define bit_cpu_HTT (1 << 28) /* COMMON_CPUID_INDEX_7. */ +#define bit_cpu_HLE (1 << 4) #define bit_cpu_ERMS (1 << 9) #define bit_cpu_RTM (1 << 11) #define bit_cpu_AVX2 (1 << 5)