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;