From 8a60fde969ce30d14afd12aededf2f00ebc5d82d Mon Sep 17 00:00:00 2001 From: David Sterba Date: Thu, 16 Feb 2023 04:36:20 +0100 Subject: [PATCH] btrfs-progs: crypto: use common CPU feature detection for crc32c The crc32c selection has been already using the pointer-based approach so drop the cpuid detection and use our common code for that. Signed-off-by: David Sterba --- crypto/crc32c.c | 45 +++++++++------------------------------------ crypto/crc32c.h | 2 +- crypto/hash.c | 7 ++++++- crypto/hash.h | 1 + 4 files changed, 17 insertions(+), 38 deletions(-) diff --git a/crypto/crc32c.c b/crypto/crc32c.c index 3afa2ad6..dc948e08 100644 --- a/crypto/crc32c.c +++ b/crypto/crc32c.c @@ -10,6 +10,7 @@ #include #include "crypto/crc32c.h" +#include "common/cpu-utils.h" uint32_t __crc32c_le(uint32_t crc, unsigned char const *data, uint32_t length); static uint32_t (*crc_function)(uint32_t crc, unsigned char const *data, uint32_t length) = __crc32c_le; @@ -34,9 +35,6 @@ static uint32_t (*crc_function)(uint32_t crc, unsigned char const *data, uint32_ #define SCALE_F 4 #endif -static int crc32c_probed = 0; -static int crc32c_intel_available = 0; - static uint32_t crc32c_intel_le_hw_byte(uint32_t crc, unsigned char const *data, uint32_t length) { @@ -78,45 +76,20 @@ static uint32_t crc32c_intel(uint32_t crc, unsigned char const *data, uint32_t l return crc; } -static void do_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, - unsigned int *edx) +void crc32c_init_accel(void) { - int id = *eax; - - asm("movl %4, %%eax;" - "cpuid;" - "movl %%eax, %0;" - "movl %%ebx, %1;" - "movl %%ecx, %2;" - "movl %%edx, %3;" - : "=r" (*eax), "=r" (*ebx), "=r" (*ecx), "=r" (*edx) - : "r" (id) - : "eax", "ebx", "ecx", "edx"); -} - -static void crc32c_intel_probe(void) -{ - if (!crc32c_probed) { - unsigned int eax, ebx, ecx, edx; - - eax = 1; - - do_cpuid(&eax, &ebx, &ecx, &edx); - crc32c_intel_available = (ecx & (1 << 20)) != 0; - crc32c_probed = 1; - } -} - -void crc32c_optimization_init(void) -{ - crc32c_intel_probe(); - if (crc32c_intel_available) + /* CRC32 is in SSE4.2 */ + if (cpu_has_feature(CPU_FLAG_SSE42)) crc_function = crc32c_intel; + else + crc_function = __crc32c_le; } + #else -void crc32c_optimization_init(void) +void crc32c_init_accel(void) { + crc_function = __crc32c_le; } #endif /* __x86_64__ */ diff --git a/crypto/crc32c.h b/crypto/crc32c.h index 261624ea..f9901771 100644 --- a/crypto/crc32c.h +++ b/crypto/crc32c.h @@ -22,7 +22,7 @@ #include uint32_t crc32c_le(uint32_t seed, unsigned char const *data, uint32_t length); -void crc32c_optimization_init(void); +void crc32c_init_accel(void); #define crc32c(seed, data, length) crc32c_le(seed, (unsigned char const *)data, length) diff --git a/crypto/hash.c b/crypto/hash.c index ee47a7d1..e8ca18c9 100644 --- a/crypto/hash.c +++ b/crypto/hash.c @@ -22,11 +22,16 @@ void hash_init_accel(void) { - crc32c_optimization_init(); + crc32c_init_accel(); blake2_init_accel(); sha256_init_accel(); } +void hash_init_crc32c(void) +{ + crc32c_init_accel(); +} + void hash_init_blake2(void) { blake2_init_accel(); diff --git a/crypto/hash.h b/crypto/hash.h index 7aafc3df..b3aab2c8 100644 --- a/crypto/hash.h +++ b/crypto/hash.h @@ -27,6 +27,7 @@ int hash_sha256(const u8 *buf, size_t length, u8 *out); int hash_blake2b(const u8 *buf, size_t length, u8 *out); void hash_init_accel(void); +void hash_init_crc32c(void); void hash_init_blake2(void); void hash_init_sha256(void);