summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-03-16 10:00:17 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-03-17 10:46:34 +0100
commit3a4ee5951643ad1da28c8d36e89106f9c8c26309 (patch)
tree5ca0ea27d6fda9c815cfd0773ffbc0f248cdf199
parent811155a269b476262848672ac9e85d2fdce066a8 (diff)
downloadgnutls-3a4ee5951643ad1da28c8d36e89106f9c8c26309.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.c66
1 files changed, 56 insertions, 10 deletions
diff --git a/lib/accelerated/x86/x86-common.c b/lib/accelerated/x86/x86-common.c
index 18e3710362..6c0e7b66a2 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];
}