summary refs log tree commit diff
path: root/sysdeps/x86
diff options
context:
space:
mode:
authorAndrew Senkevich <andrew.senkevich@intel.com>2016-12-19 13:20:31 +0300
committerAndrew Senkevich <andrew.senkevich@intel.com>2016-12-19 14:15:57 +0300
commit2702856bf45c82cf8e69f2064f5aa15c0ceb6359 (patch)
treee40c77e7ecb5974aedb1ba173bc52d1aa183898f /sysdeps/x86
parent7051390094c124e4b98e6c57a8b47890b212c299 (diff)
downloadglibc-2702856bf45c82cf8e69f2064f5aa15c0ceb6359.tar.gz
glibc-2702856bf45c82cf8e69f2064f5aa15c0ceb6359.tar.xz
glibc-2702856bf45c82cf8e69f2064f5aa15c0ceb6359.zip
Disable TSX on some Haswell processors.
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.
Diffstat (limited to 'sysdeps/x86')
-rw-r--r--sysdeps/x86/cpu-features.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index e228a76c40..0ef98e68ab 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -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.  */