blake2s-glue.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // SPDX-License-Identifier: GPL-2.0 OR MIT
  2. /*
  3. * Copyright (C) 2015-2019 Jason A. Donenfeld <[email protected]>. All Rights Reserved.
  4. */
  5. #include <crypto/internal/blake2s.h>
  6. #include <linux/types.h>
  7. #include <linux/jump_label.h>
  8. #include <linux/kernel.h>
  9. #include <linux/module.h>
  10. #include <linux/sizes.h>
  11. #include <asm/cpufeature.h>
  12. #include <asm/fpu/api.h>
  13. #include <asm/processor.h>
  14. #include <asm/simd.h>
  15. asmlinkage void blake2s_compress_ssse3(struct blake2s_state *state,
  16. const u8 *block, const size_t nblocks,
  17. const u32 inc);
  18. asmlinkage void blake2s_compress_avx512(struct blake2s_state *state,
  19. const u8 *block, const size_t nblocks,
  20. const u32 inc);
  21. static __ro_after_init DEFINE_STATIC_KEY_FALSE(blake2s_use_ssse3);
  22. static __ro_after_init DEFINE_STATIC_KEY_FALSE(blake2s_use_avx512);
  23. void blake2s_compress(struct blake2s_state *state, const u8 *block,
  24. size_t nblocks, const u32 inc)
  25. {
  26. /* SIMD disables preemption, so relax after processing each page. */
  27. BUILD_BUG_ON(SZ_4K / BLAKE2S_BLOCK_SIZE < 8);
  28. if (!static_branch_likely(&blake2s_use_ssse3) || !may_use_simd()) {
  29. blake2s_compress_generic(state, block, nblocks, inc);
  30. return;
  31. }
  32. do {
  33. const size_t blocks = min_t(size_t, nblocks,
  34. SZ_4K / BLAKE2S_BLOCK_SIZE);
  35. kernel_fpu_begin();
  36. if (IS_ENABLED(CONFIG_AS_AVX512) &&
  37. static_branch_likely(&blake2s_use_avx512))
  38. blake2s_compress_avx512(state, block, blocks, inc);
  39. else
  40. blake2s_compress_ssse3(state, block, blocks, inc);
  41. kernel_fpu_end();
  42. nblocks -= blocks;
  43. block += blocks * BLAKE2S_BLOCK_SIZE;
  44. } while (nblocks);
  45. }
  46. EXPORT_SYMBOL(blake2s_compress);
  47. static int __init blake2s_mod_init(void)
  48. {
  49. if (boot_cpu_has(X86_FEATURE_SSSE3))
  50. static_branch_enable(&blake2s_use_ssse3);
  51. if (IS_ENABLED(CONFIG_AS_AVX512) &&
  52. boot_cpu_has(X86_FEATURE_AVX) &&
  53. boot_cpu_has(X86_FEATURE_AVX2) &&
  54. boot_cpu_has(X86_FEATURE_AVX512F) &&
  55. boot_cpu_has(X86_FEATURE_AVX512VL) &&
  56. cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM |
  57. XFEATURE_MASK_AVX512, NULL))
  58. static_branch_enable(&blake2s_use_avx512);
  59. return 0;
  60. }
  61. module_init(blake2s_mod_init);
  62. MODULE_LICENSE("GPL v2");