|
7 | 7 | */ |
8 | 8 |
|
9 | 9 | #include <linux/crc-t10dif.h> |
10 | | -#include <crypto/internal/hash.h> |
11 | 10 | #include <crypto/internal/simd.h> |
12 | 11 | #include <linux/init.h> |
13 | 12 | #include <linux/module.h> |
|
22 | 21 |
|
23 | 22 | #define VECTOR_BREAKPOINT 64 |
24 | 23 |
|
| 24 | +static DEFINE_STATIC_KEY_FALSE(have_vec_crypto); |
| 25 | + |
25 | 26 | u32 __crct10dif_vpmsum(u32 crc, unsigned char const *p, size_t len); |
26 | 27 |
|
27 | | -static u16 crct10dif_vpmsum(u16 crci, unsigned char const *p, size_t len) |
| 28 | +u16 crc_t10dif_arch(u16 crci, const u8 *p, size_t len) |
28 | 29 | { |
29 | 30 | unsigned int prealign; |
30 | 31 | unsigned int tail; |
31 | 32 | u32 crc = crci; |
32 | 33 |
|
33 | | - if (len < (VECTOR_BREAKPOINT + VMX_ALIGN) || !crypto_simd_usable()) |
| 34 | + if (len < (VECTOR_BREAKPOINT + VMX_ALIGN) || |
| 35 | + !static_branch_likely(&have_vec_crypto) || !crypto_simd_usable()) |
34 | 36 | return crc_t10dif_generic(crc, p, len); |
35 | 37 |
|
36 | 38 | if ((unsigned long)p & VMX_ALIGN_MASK) { |
@@ -60,67 +62,28 @@ static u16 crct10dif_vpmsum(u16 crci, unsigned char const *p, size_t len) |
60 | 62 |
|
61 | 63 | return crc & 0xffff; |
62 | 64 | } |
| 65 | +EXPORT_SYMBOL(crc_t10dif_arch); |
63 | 66 |
|
64 | | -static int crct10dif_vpmsum_init(struct shash_desc *desc) |
65 | | -{ |
66 | | - u16 *crc = shash_desc_ctx(desc); |
67 | | - |
68 | | - *crc = 0; |
69 | | - return 0; |
70 | | -} |
71 | | - |
72 | | -static int crct10dif_vpmsum_update(struct shash_desc *desc, const u8 *data, |
73 | | - unsigned int length) |
74 | | -{ |
75 | | - u16 *crc = shash_desc_ctx(desc); |
76 | | - |
77 | | - *crc = crct10dif_vpmsum(*crc, data, length); |
78 | | - |
79 | | - return 0; |
80 | | -} |
81 | | - |
82 | | - |
83 | | -static int crct10dif_vpmsum_final(struct shash_desc *desc, u8 *out) |
| 67 | +static int __init crc_t10dif_powerpc_init(void) |
84 | 68 | { |
85 | | - u16 *crcp = shash_desc_ctx(desc); |
86 | | - |
87 | | - *(u16 *)out = *crcp; |
| 69 | + if (cpu_has_feature(CPU_FTR_ARCH_207S) && |
| 70 | + (cur_cpu_spec->cpu_user_features2 & PPC_FEATURE2_VEC_CRYPTO)) |
| 71 | + static_branch_enable(&have_vec_crypto); |
88 | 72 | return 0; |
89 | 73 | } |
| 74 | +arch_initcall(crc_t10dif_powerpc_init); |
90 | 75 |
|
91 | | -static struct shash_alg alg = { |
92 | | - .init = crct10dif_vpmsum_init, |
93 | | - .update = crct10dif_vpmsum_update, |
94 | | - .final = crct10dif_vpmsum_final, |
95 | | - .descsize = CRC_T10DIF_DIGEST_SIZE, |
96 | | - .digestsize = CRC_T10DIF_DIGEST_SIZE, |
97 | | - .base = { |
98 | | - .cra_name = "crct10dif", |
99 | | - .cra_driver_name = "crct10dif-vpmsum", |
100 | | - .cra_priority = 200, |
101 | | - .cra_blocksize = CRC_T10DIF_BLOCK_SIZE, |
102 | | - .cra_module = THIS_MODULE, |
103 | | - } |
104 | | -}; |
105 | | - |
106 | | -static int __init crct10dif_vpmsum_mod_init(void) |
| 76 | +static void __exit crc_t10dif_powerpc_exit(void) |
107 | 77 | { |
108 | | - if (!cpu_has_feature(CPU_FTR_ARCH_207S)) |
109 | | - return -ENODEV; |
110 | | - |
111 | | - return crypto_register_shash(&alg); |
112 | 78 | } |
| 79 | +module_exit(crc_t10dif_powerpc_exit); |
113 | 80 |
|
114 | | -static void __exit crct10dif_vpmsum_mod_fini(void) |
| 81 | +bool crc_t10dif_is_optimized(void) |
115 | 82 | { |
116 | | - crypto_unregister_shash(&alg); |
| 83 | + return static_key_enabled(&have_vec_crypto); |
117 | 84 | } |
118 | | - |
119 | | -module_cpu_feature_match(PPC_MODULE_FEATURE_VEC_CRYPTO, crct10dif_vpmsum_mod_init); |
120 | | -module_exit(crct10dif_vpmsum_mod_fini); |
| 85 | +EXPORT_SYMBOL(crc_t10dif_is_optimized); |
121 | 86 |
|
122 | 87 | MODULE_AUTHOR("Daniel Axtens <dja@axtens.net>"); |
123 | 88 | MODULE_DESCRIPTION("CRCT10DIF using vector polynomial multiply-sum instructions"); |
124 | 89 | MODULE_LICENSE("GPL"); |
125 | | -MODULE_ALIAS_CRYPTO("crct10dif"); |
126 | | -MODULE_ALIAS_CRYPTO("crct10dif-vpmsum"); |
0 commit comments