From 3b3d3587278a44c3e84cb69548a7c6c30457fe7f Mon Sep 17 00:00:00 2001 From: Eric Vannier Date: Wed, 14 Feb 2018 21:39:51 -0800 Subject: [PATCH] Allow AESNI to be used on AuthenticAMD processors for improved performance/reduced CPU usage. Tests performed: - Ran on Ivy Bridge and Ryzen and verified that AESNI is detected (crypto tests) - Ran on Ryzen, and observed 50% increased speed. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13302 Signed-off-by: Eric Vannier --- lib/crypto/aes.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/lib/crypto/aes.c b/lib/crypto/aes.c index c226ac1b3df..0535c63865e 100644 --- a/lib/crypto/aes.c +++ b/lib/crypto/aes.c @@ -53,6 +53,28 @@ static inline void __cpuid(unsigned int where[4], unsigned int leaf) "=d" (where[3]): "a" (leaf)); } +/* + * is_cpu_vendor() + * Compares vendor retrieved from CPUID with a vendor string. + * The vendor string should be something like "GenuineIntel" + */ +static bool is_cpu_vendor(const unsigned int cpuid_results[4], + const char vendor_string[12]) +{ + /* + * MSB LSB + * EBX = 'u' 'n' 'e' 'G' + * EDX = 'I' 'e' 'n' 'i' + * ECX = 'l' 'e' 't' 'n' + */ + return memcmp((const unsigned char *)&cpuid_results[1], + vendor_string, 4) == 0 && + memcmp((const unsigned char *)&cpuid_results[3], + vendor_string + 4, 4) == 0 && + memcmp((const unsigned char *)&cpuid_results[2], + vendor_string + 8, 4) == 0; +} + /* * has_intel_aes_instructions() * return true if supports AES-NI and false if doesn't @@ -67,21 +89,13 @@ static bool has_intel_aes_instructions(void) } __cpuid(cpuid_results, 0); - /* - * MSB LSB - * EBX = 'u' 'n' 'e' 'G' - * EDX = 'I' 'e' 'n' 'i' - * ECX = 'l' 'e' 't' 'n' - */ - if (memcmp((unsigned char *)&cpuid_results[1], "Genu", 4) != 0 || - memcmp((unsigned char *)&cpuid_results[3], - "ineI", 4) != 0 || - memcmp((unsigned char *)&cpuid_results[2], - "ntel", 4) != 0) { + if (!is_cpu_vendor(cpuid_results, "GenuineIntel") && + !is_cpu_vendor(cpuid_results, "AuthenticAMD")) { has_aes_instructions = 0; return (bool)has_aes_instructions; } + /* Intel and AMD use bit 25 to encode AESNI support. */ __cpuid(cpuid_results, 1); has_aes_instructions = !!(cpuid_results[2] & (1 << 25)); return (bool)has_aes_instructions; -- 2.14.3