On Wed, Jan 18, 2017 at 11:08 PM, Uros Bizjak <ubiz...@gmail.com> wrote:
> On Wed, Jan 18, 2017 at 10:48 PM, Uros Bizjak <ubiz...@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  <ubiz...@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.
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;

Reply via email to