Disable TSX on some Haswell processors.
authorAndrew Senkevich <andrew.senkevich@intel.com>
Mon, 19 Dec 2016 10:20:31 +0000 (13:20 +0300)
committerAndrew Senkevich <andrew.senkevich@intel.com>
Mon, 19 Dec 2016 11:15:57 +0000 (14:15 +0300)
Patch disables Intel TSX on some Haswell processors to avoid TSX
on kernels that weren't updated with the latest microcode package
(which disables broken feature by default).

    * sysdeps/x86/cpu-features.c (get_common_indeces): Add
    stepping identification.
    (init_cpu_features): Add handle of Haswell.

ChangeLog
sysdeps/x86/cpu-features.c

index 8782df9..6a27320 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2016-12-19  Andrew Senkevich  <andrew.senkevich@intel.com>
+
+       * sysdeps/x86/cpu-features.c (get_common_indeces): Add
+       stepping identification.
+       (init_cpu_features): Add handle of Haswell.
+
 2016-11-25  Jim Meyering  <meyering@fb.com>
 
        [BZ #20386]
index e228a76..0ef98e6 100644 (file)
@@ -22,7 +22,7 @@
 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 +34,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;
@@ -116,11 +117,12 @@ init_cpu_features (struct cpu_features *cpu_features)
   /* This spells out "GenuineIntel".  */
   if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)
     {
-      unsigned int extended_model;
+      unsigned int extended_model, stepping;
 
       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)
        {
@@ -201,6 +203,20 @@ init_cpu_features (struct cpu_features *cpu_features)
                    | bit_arch_Fast_Unaligned_Copy
                    | bit_arch_Prefer_PMINUB_for_stringop);
              break;
+
+           case 0x3f:
+             /* Xeon E7 v3 with stepping >= 4 has working TSX.  */
+             if (stepping >= 4)
+               break;
+           case 0x3c:
+           case 0x45:
+           case 0x46:
+             /* Disable Intel TSX on Haswell processors (except Xeon E7 v3
+                with stepping >= 4) to avoid TSX on kernels that weren't
+                updated with the latest microcode package (which disables
+                broken feature by default).  */
+             cpu_features->cpuid[COMMON_CPUID_INDEX_7].ebx &= ~(bit_cpu_RTM);
+             break;
            }
        }
 
@@ -227,11 +243,12 @@ init_cpu_features (struct cpu_features *cpu_features)
   /* This spells out "AuthenticAMD".  */
   else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
     {
-      unsigned int extended_model;
+      unsigned int extended_model, stepping;
 
       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;
 
@@ -268,7 +285,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.  */