[x86_64] Disable TSX on some Haswell processors

Message ID CAMXFM3snRTk_NCz=4-xJS0gScWKBRNxANwmrpqu+EwPY+apoGw@mail.gmail.com
State New, archived
Headers

Commit Message

Andrew Senkevich Dec. 15, 2016, 3:37 p.m. UTC
  2016-12-14 22:13 GMT+03:00 Carlos O'Donell <carlos@redhat.com>:
. . . . .
>
> Case 0x3f needs a comment explaining why we break out early.
>
>> +    case 0x3f:
>> +      if (stepping >= 4)
>> + break;

Here is version with added comment and ChangeLog. Ok for commit?



--
WBR,
Andrew
  

Comments

Mike Frysinger Dec. 16, 2016, 7:05 p.m. UTC | #1
On 15 Dec 2016 18:37, Andrew Senkevich wrote:
> 2016-12-14 22:13 GMT+03:00 Carlos O'Donell <carlos@redhat.com>:
> . . . . .
> >
> > Case 0x3f needs a comment explaining why we break out early.
> >
> >> +    case 0x3f:
> >> +      if (stepping >= 4)
> >> + break;
> 
> Here is version with added comment and ChangeLog. Ok for commit?

looks fine
-mike
  
Carlos O'Donell Dec. 16, 2016, 9 p.m. UTC | #2
On 12/15/2016 10:37 AM, Andrew Senkevich wrote:
> 2016-12-14 22:13 GMT+03:00 Carlos O'Donell <carlos@redhat.com>:
> . . . . .
>>
>> Case 0x3f needs a comment explaining why we break out early.
>>
>>> +    case 0x3f:
>>> +      if (stepping >= 4)
>>> + break;
> 
> Here is version with added comment and ChangeLog. Ok for commit?

So long as your tabs are fixed in the final commit, then yes,
this looks good to me.

Thank you very much for the background research and verification
to get this blacklist in place which will allow us to move forward
more aggressively in allowing applications to use RTM with glibc.
  

Patch

diff --git a/ChangeLog b/ChangeLog
index cf798fb..ef4c3b4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@ 
+2016-12-15  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-12-15  Joseph Myers  <joseph@codesourcery.com>

  [BZ #20947]
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index e228a76..d158402 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)
+ 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.  */