diff options
author | Ulrich Drepper <drepper@gmail.com> | 2011-07-20 21:21:03 -0400 |
---|---|---|
committer | Andreas Schwab <schwab@redhat.com> | 2011-07-25 10:04:42 +0200 |
commit | 722bff7a4ccceeded69ac8c412ff5ee5859964e7 (patch) | |
tree | 30cdca823f4c90ec364a8905a6f57faf0c4a57f3 | |
parent | 63072fc6170f06657800a536c084db5d6e45e80f (diff) | |
download | glibc-722bff7a4ccceeded69ac8c412ff5ee5859964e7.zip glibc-722bff7a4ccceeded69ac8c412ff5ee5859964e7.tar.gz glibc-722bff7a4ccceeded69ac8c412ff5ee5859964e7.tar.bz2 |
Fix check for AVX enablement
The AVX bit is set if the CPU supports AVX. But this doesn't mean the
kernel does. Add checks according to Intel's documentation.
(cherry picked from commit 5644ef5461b5d3ff266206d8ee70d4b575ea6658)
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | elf/tst-audit4.c | 22 | ||||
-rw-r--r-- | elf/tst-audit6.c | 22 | ||||
-rw-r--r-- | sysdeps/x86_64/dl-trampoline.S | 17 |
4 files changed, 57 insertions, 13 deletions
@@ -1,5 +1,14 @@ 2011-07-20 Ulrich Drepper <drepper@gmail.com> + [BZ #13007] + * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): More complete + check for AVX enablement so that we don't crash with old kernels and + new hardware. + * elf/tst-audit4.c: Add same checks here. + * elf/tst-audit6.c: Likewise. + +2011-07-20 Ulrich Drepper <drepper@gmail.com> + [BZ #12852] * posix/glob.c (glob): Check passed in values before using them in expressions to avoid some overflows. diff --git a/elf/tst-audit4.c b/elf/tst-audit4.c index b17d4a6..c4f1d5b 100644 --- a/elf/tst-audit4.c +++ b/elf/tst-audit4.c @@ -6,16 +6,30 @@ #include <cpuid.h> #include <immintrin.h> + +static int +avx_enabled (void) +{ + unsigned int eax, ebx, ecx, edx; + + if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) == 0 + || (ecx & (bit_AVX | bit_OSXSAVE)) != (bit_AVX | bit_OSXSAVE)) + return 0; + + /* Check the OS has AVX and SSE saving enabled. */ + asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); + + return (eax & 6) == 6; +} + + extern __m256i audit_test (__m256i, __m256i, __m256i, __m256i, __m256i, __m256i, __m256i, __m256i); int main (void) { - unsigned int eax, ebx, ecx, edx; - /* Run AVX test only if AVX is supported. */ - if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) - && (ecx & bit_AVX)) + if (avx_enabled ()) { __m256i ymm = _mm256_setzero_si256 (); __m256i ret = audit_test (ymm, ymm, ymm, ymm, ymm, ymm, ymm, ymm); diff --git a/elf/tst-audit6.c b/elf/tst-audit6.c index 1f6dcb1..64209a1 100644 --- a/elf/tst-audit6.c +++ b/elf/tst-audit6.c @@ -8,14 +8,28 @@ extern __m128i audit_test (__m128i, __m128i, __m128i, __m128i, __m128i, __m128i, __m128i, __m128i); -int -main (void) + +static int +avx_enabled (void) { unsigned int eax, ebx, ecx, edx; + if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) == 0 + || (ecx & (bit_AVX | bit_OSXSAVE)) != (bit_AVX | bit_OSXSAVE)) + return 0; + + /* Check the OS has AVX and SSE saving enabled. */ + asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); + + return (eax & 6) == 6; +} + + +int +main (void) +{ /* Run AVX test only if AVX is supported. */ - if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) - && (ecx & bit_AVX)) + if (avx_enabled ()) { __m128i xmm = _mm_setzero_si128 (); __m128i ret = audit_test (xmm, xmm, xmm, xmm, xmm, xmm, xmm, xmm); diff --git a/sysdeps/x86_64/dl-trampoline.S b/sysdeps/x86_64/dl-trampoline.S index 5564a11..1b97929 100644 --- a/sysdeps/x86_64/dl-trampoline.S +++ b/sysdeps/x86_64/dl-trampoline.S @@ -1,5 +1,5 @@ /* PLT trampolines. x86-64 version. - Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2007, 2009, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -139,10 +139,17 @@ L(have_avx): movl $1, %eax cpuid movq %r11,%rbx # Restore rbx - movl $1, %eax - testl $(1 << 28), %ecx - jne 2f - negl %eax + xorl %eax, %eax + // AVX and XSAVE supported? + testl $((1 << 28) | (1 << 27)), %ecx + je 2f + xorl %ecx, %ecx + // Get XFEATURE_ENABLED_MASK + xgetbv + andl $0x6, %eax + cmpl $0x6, %eax + // Nonzero if SSE and AVX state saving is enabled. + sete %al 2: movl %eax, L(have_avx)(%rip) cmpl $0, %eax |