diff mbox

[committed] libitm: Disable TSX on processors on which it may be broken.

Message ID CAFULd4bHZrvWwraiAWZ9fSdh5jQ_nY8k7YMEeeXQjb13puhr4g@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Jan. 19, 2017, 5:13 p.m. UTC
On Wed, Jan 18, 2017 at 11:08 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Wed, Jan 18, 2017 at 10:48 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> Hello!
>>
>>> This fix follows the same approach that glibc uses to disable TSX on
>>> processors on which it is broken.  TSX can also be disabled through a
>>> microcode update on these processors, but glibc consensus is that it
>>> cannot be detected reliably whether the microcode update has been
>>> applied.  Thus, we just look for affected models/steppings.
>>>
>>> Tested on x86_64-linux (but I don't have a machine with broken TSX
>>> available).
>>>
>>>        libitm/ChangeLog
>>>
>>>        * config/x86/target.h (htm_available): Add check for some processors
>>>        on which TSX is broken.
>>
>> +      __cpuid (0, a, b, c, d);
>> +      if (b == 0x756e6547 && c == 0x6c65746e && d == 0x49656e69)
>>
>> You can use:
>>
>> #define signature_INTEL_ebx    0x756e6547
>> #define signature_INTEL_ecx    0x6c65746e
>> #define signature_INTEL_edx    0x49656e69
>>
>> defines from cpuid.h here.
>
> Actually, just provide a non-NULL second argument to __get_cpuid_max.
> It will return %ebx from cpuid, which should be enough to detect Intel
> processor.


Attached is the patch I have committed to mainline SVN after a short
off-line discussion with Torvald.

2017-01-19  Uros Bizjak  <ubizjak@gmail.com>

    * config/x86/target.h (htm_available): Determine vendor from
    __get_cpuid_max return.  Use signature_INTEL_ebx.  Cleanup.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

Uros.
diff mbox

Patch

Index: config/x86/target.h
===================================================================
--- config/x86/target.h	(revision 244636)
+++ config/x86/target.h	(working copy)
@@ -75,31 +75,32 @@  static inline bool
 htm_available ()
 {
   const unsigned cpuid_rtm = bit_RTM;
-  if (__get_cpuid_max (0, NULL) >= 7)
+  unsigned vendor;
+
+  if (__get_cpuid_max (0, &vendor) >= 7)
     {
       unsigned a, b, c, d;
-      /* TSX is broken on some processors.  This can be fixed by microcode,
+      unsigned family;
+
+      __cpuid (1, a, b, c, d);
+      family = (a >> 8) & 0x0f;
+      /* TSX is broken on some processors.  TSX can be disabled by microcode,
 	 but we cannot reliably detect whether the microcode has been
 	 updated.  Therefore, do not report availability of TSX on these
 	 processors.  We use the same approach here as in glibc (see
 	 https://sourceware.org/ml/libc-alpha/2016-12/msg00470.html).  */
-      __cpuid (0, a, b, c, d);
-      if (b == 0x756e6547 && c == 0x6c65746e && d == 0x49656e69)
+      if (vendor == signature_INTEL_ebx && family == 0x06)
 	{
-	  __cpuid (1, a, b, c, d);
-	  if (((a >> 8) & 0x0f) == 0x06) // Family.
-	    {
-	      unsigned model = ((a >> 4) & 0x0f) // Model.
-		  + ((a >> 12) & 0xf0); // Extended model.
-	      unsigned stepping = a & 0x0f;
-	      if ((model == 0x3c)
-		  || (model == 0x45)
-		  || (model == 0x46)
-		  /* Xeon E7 v3 has correct TSX if stepping >= 4.  */
-		  || ((model == 0x3f) && (stepping < 4)))
-		return false;
-	    }
+	  unsigned model = ((a >> 4) & 0x0f) + ((a >> 12) & 0xf0);
+	  unsigned stepping = a & 0x0f;
+	  if (model == 0x3c
+	      /* Xeon E7 v3 has correct TSX if stepping >= 4.  */
+	      || (model == 0x3f && stepping < 4)
+	      || model == 0x45
+	      || model == 0x46)
+	    return false;
 	}
+
       __cpuid_count (7, 0, a, b, c, d);
       if (b & cpuid_rtm)
 	return true;