1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
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 <hmh@debian.org>
--- 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 @@
*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 @@
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 @@
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)
{
@@ -213,7 +217,8 @@
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;
@@ -250,7 +255,7 @@
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. */
@@ -261,6 +266,24 @@
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
--- a/sysdeps/x86/cpu-features.h
+++ b/sysdeps/x86/cpu-features.h
@@ -55,6 +55,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)
|