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.
This commit is contained in:
Ulrich Drepper 2011-07-20 21:21:03 -04:00
parent 6986b98a18
commit 5644ef5461
5 changed files with 58 additions and 16 deletions

View File

@ -1,6 +1,13 @@
2011-07-20 Ulrich Drepper <drepper@gmail.com> 2011-07-20 Ulrich Drepper <drepper@gmail.com>
* sysdeps/x86_64/bits/link.h (La_x86_64_ymm): Force 16-byt alignment. [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.
* sysdeps/x86_64/bits/link.h (La_x86_64_ymm): Force 16-byte alignment.
2011-07-09 Andreas Schwab <schwab@linux-m68k.org> 2011-07-09 Andreas Schwab <schwab@linux-m68k.org>

4
NEWS
View File

@ -1,4 +1,4 @@
GNU C Library NEWS -- history of user-visible changes. 2011-7-19 GNU C Library NEWS -- history of user-visible changes. 2011-7-20
Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc. Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc.
See the end for copying conditions. See the end for copying conditions.
@ -9,7 +9,7 @@ Version 2.15
* The following bugs are resolved with this release: * The following bugs are resolved with this release:
9696, 12868, 12874, 12885, 12907, 12922, 12935 9696, 12868, 12874, 12885, 12907, 12922, 12935, 13007
* New program pldd to list loaded object of a process * New program pldd to list loaded object of a process
Implemented by Ulrich Drepper. Implemented by Ulrich Drepper.

View File

@ -6,16 +6,30 @@
#include <cpuid.h> #include <cpuid.h>
#include <immintrin.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, extern __m256i audit_test (__m256i, __m256i, __m256i, __m256i,
__m256i, __m256i, __m256i, __m256i); __m256i, __m256i, __m256i, __m256i);
int int
main (void) main (void)
{ {
unsigned int eax, ebx, ecx, edx;
/* Run AVX test only if AVX is supported. */ /* Run AVX test only if AVX is supported. */
if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) if (avx_enabled ())
&& (ecx & bit_AVX))
{ {
__m256i ymm = _mm256_setzero_si256 (); __m256i ymm = _mm256_setzero_si256 ();
__m256i ret = audit_test (ymm, ymm, ymm, ymm, ymm, ymm, ymm, ymm); __m256i ret = audit_test (ymm, ymm, ymm, ymm, ymm, ymm, ymm, ymm);

View File

@ -8,14 +8,28 @@
extern __m128i audit_test (__m128i, __m128i, __m128i, __m128i, extern __m128i audit_test (__m128i, __m128i, __m128i, __m128i,
__m128i, __m128i, __m128i, __m128i); __m128i, __m128i, __m128i, __m128i);
int
main (void) static int
avx_enabled (void)
{ {
unsigned int eax, ebx, ecx, edx; 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. */ /* Run AVX test only if AVX is supported. */
if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) if (avx_enabled ())
&& (ecx & bit_AVX))
{ {
__m128i xmm = _mm_setzero_si128 (); __m128i xmm = _mm_setzero_si128 ();
__m128i ret = audit_test (xmm, xmm, xmm, xmm, xmm, xmm, xmm, xmm); __m128i ret = audit_test (xmm, xmm, xmm, xmm, xmm, xmm, xmm, xmm);

View File

@ -1,5 +1,5 @@
/* PLT trampolines. x86-64 version. /* 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -139,10 +139,17 @@ L(have_avx):
movl $1, %eax movl $1, %eax
cpuid cpuid
movq %r11,%rbx # Restore rbx movq %r11,%rbx # Restore rbx
movl $1, %eax xorl %eax, %eax
testl $(1 << 28), %ecx // AVX and XSAVE supported?
jne 2f testl $((1 << 28) | (1 << 27)), %ecx
negl %eax 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) 2: movl %eax, L(have_avx)(%rip)
cmpl $0, %eax cmpl $0, %eax