1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * x86-optimized SHA-512 block function 4 * 5 * Copyright 2025 Google LLC 6 */ 7 8 #include <asm/fpu/api.h> 9 #include <crypto/internal/simd.h> 10 #include <linux/static_call.h> 11 12 DEFINE_STATIC_CALL(sha512_blocks_x86, sha512_blocks_generic); 13 14 #define DEFINE_X86_SHA512_FN(c_fn, asm_fn) \ 15 asmlinkage void asm_fn(struct sha512_block_state *state, \ 16 const u8 *data, size_t nblocks); \ 17 static void c_fn(struct sha512_block_state *state, const u8 *data, \ 18 size_t nblocks) \ 19 { \ 20 if (likely(crypto_simd_usable())) { \ 21 kernel_fpu_begin(); \ 22 asm_fn(state, data, nblocks); \ 23 kernel_fpu_end(); \ 24 } else { \ 25 sha512_blocks_generic(state, data, nblocks); \ 26 } \ 27 } 28 29 DEFINE_X86_SHA512_FN(sha512_blocks_ssse3, sha512_transform_ssse3); 30 DEFINE_X86_SHA512_FN(sha512_blocks_avx, sha512_transform_avx); 31 DEFINE_X86_SHA512_FN(sha512_blocks_avx2, sha512_transform_rorx); 32 33 static void sha512_blocks(struct sha512_block_state *state, 34 const u8 *data, size_t nblocks) 35 { 36 static_call(sha512_blocks_x86)(state, data, nblocks); 37 } 38 39 #define sha512_mod_init_arch sha512_mod_init_arch 40 static inline void sha512_mod_init_arch(void) 41 { 42 if (cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL) && 43 boot_cpu_has(X86_FEATURE_AVX)) { 44 if (boot_cpu_has(X86_FEATURE_AVX2) && 45 boot_cpu_has(X86_FEATURE_BMI2)) 46 static_call_update(sha512_blocks_x86, 47 sha512_blocks_avx2); 48 else 49 static_call_update(sha512_blocks_x86, 50 sha512_blocks_avx); 51 } else if (boot_cpu_has(X86_FEATURE_SSSE3)) { 52 static_call_update(sha512_blocks_x86, sha512_blocks_ssse3); 53 } 54 } 55