diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-03-16 10:00:17 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-03-18 08:52:55 +0100 |
commit | bf083b6582b92f2967d528eb70acddc0d1516313 (patch) | |
tree | 21ad9f2206ffc5cb0d757d0a473badc851ade793 | |
parent | 1e23f5795b23002af9dd66926ff254e094f3e661 (diff) | |
download | gnutls-bf083b6582b92f2967d528eb70acddc0d1516313.tar.gz |
x86-common: CPUID override will only work if CPU has already the capability present
This resolves test suite failure on CPUs with limited capabilities.
Reported by Andreas Metzler.
-rw-r--r-- | lib/accelerated/x86/x86-common.c | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/lib/accelerated/x86/x86-common.c b/lib/accelerated/x86/x86-common.c index 0f355cc411..5dc5cdd77b 100644 --- a/lib/accelerated/x86/x86-common.c +++ b/lib/accelerated/x86/x86-common.c @@ -76,18 +76,40 @@ unsigned int _gnutls_x86_cpuid_s[3]; static void capabilities_to_intel_cpuid(unsigned capabilities) { + unsigned a,b,c,t; + memset(_gnutls_x86_cpuid_s, 0, sizeof(_gnutls_x86_cpuid_s)); + if (capabilities & EMPTY_SET) { return; } + + gnutls_cpuid(1, &t, &a, &b, &c); + if (capabilities & INTEL_AES_NI) { - _gnutls_x86_cpuid_s[1] |= bit_AES; + if (b & bit_AES) { + _gnutls_x86_cpuid_s[1] |= bit_AES; + } else { + _gnutls_debug_log + ("AESNI acceleration requested but not available\n"); + } } + if (capabilities & INTEL_SSSE3) { - _gnutls_x86_cpuid_s[1] |= bit_SSSE3; + if (b & bit_SSSE3) { + _gnutls_x86_cpuid_s[1] |= bit_SSSE3; + } else { + _gnutls_debug_log + ("SSSE3 acceleration requested but not available\n"); + } } - if (capabilities & INTEL_PCLMUL) { /* ecx */ - _gnutls_x86_cpuid_s[1] |= bit_PCLMUL; + if (capabilities & INTEL_PCLMUL) { + if (b & bit_PCLMUL) { + _gnutls_x86_cpuid_s[1] |= bit_PCLMUL; + } else { + _gnutls_debug_log + ("PCLMUL acceleration requested but not available\n"); + } } } @@ -111,19 +133,43 @@ static unsigned check_pclmul(void) #ifdef ENABLE_PADLOCK static unsigned capabilities_to_via_edx(unsigned capabilities) { + unsigned a,b,c,t; + memset(_gnutls_x86_cpuid_s, 0, sizeof(_gnutls_x86_cpuid_s)); + if (capabilities & EMPTY_SET) { return 0; } - if (capabilities & VIA_PADLOCK) { /* edx */ - _gnutls_x86_cpuid_s[2] |= via_bit_PADLOCK; + + gnutls_cpuid(1, &t, &a, &b, &c); + + if (capabilities & VIA_PADLOCK) { + if (c & via_bit_PADLOCK) { + _gnutls_x86_cpuid_s[2] |= via_bit_PADLOCK; + } else { + _gnutls_debug_log + ("Padlock acceleration requested but not available\n"); + } } - if (capabilities & VIA_PADLOCK_PHE) { /* edx */ - _gnutls_x86_cpuid_s[2] |= via_bit_PADLOCK_PHE; + + if (capabilities & VIA_PADLOCK_PHE) { + if (c & via_bit_PADLOCK_PHE) { + _gnutls_x86_cpuid_s[2] |= via_bit_PADLOCK_PHE; + } else { + _gnutls_debug_log + ("Padlock-PHE acceleration requested but not available\n"); + } } - if (capabilities & VIA_PADLOCK_PHE_SHA512) { /* edx */ - _gnutls_x86_cpuid_s[2] |= via_bit_PADLOCK_PHE_SHA512; + + if (capabilities & VIA_PADLOCK_PHE_SHA512) { + if (c & via_bit_PADLOCK_PHE_SHA512) { + _gnutls_x86_cpuid_s[2] |= via_bit_PADLOCK_PHE_SHA512; + } else { + _gnutls_debug_log + ("Padlock-PHE-SHA512 acceleration requested but not available\n"); + } } + return _gnutls_x86_cpuid_s[2]; } |