forked from analogdevicesinc/linux
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
crypto: arm64/crct10dif - implement non-Crypto Extensions alternative
The arm64 implementation of the CRC-T10DIF algorithm uses the 64x64 bit polynomial multiplication instructions, which are optional in the architecture, and if these instructions are not available, we fall back to the C routine which is slow and inefficient. So let's reuse the 64x64 bit PMULL alternative from the GHASH driver that uses a sequence of ~40 instructions involving 8x8 bit PMULL and some shifting and masking. This is a lot slower than the original, but it is still twice as fast as the current [unoptimized] C code on Cortex-A53, and it is time invariant and much easier on the D-cache. Signed-off-by: Ard Biesheuvel <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
- Loading branch information
Showing
2 changed files
with
162 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ | |
#define CRC_T10DIF_PMULL_CHUNK_SIZE 16U | ||
|
||
asmlinkage u16 crc_t10dif_pmull_p64(u16 init_crc, const u8 buf[], u64 len); | ||
asmlinkage u16 crc_t10dif_pmull_p8(u16 init_crc, const u8 buf[], u64 len); | ||
|
||
static u16 (*crc_t10dif_pmull)(u16 init_crc, const u8 buf[], u64 len); | ||
|
||
|
@@ -87,7 +88,10 @@ static struct shash_alg crc_t10dif_alg = { | |
|
||
static int __init crc_t10dif_mod_init(void) | ||
{ | ||
crc_t10dif_pmull = crc_t10dif_pmull_p64; | ||
if (elf_hwcap & HWCAP_PMULL) | ||
crc_t10dif_pmull = crc_t10dif_pmull_p64; | ||
else | ||
crc_t10dif_pmull = crc_t10dif_pmull_p8; | ||
|
||
return crypto_register_shash(&crc_t10dif_alg); | ||
} | ||
|
@@ -97,8 +101,10 @@ static void __exit crc_t10dif_mod_exit(void) | |
crypto_unregister_shash(&crc_t10dif_alg); | ||
} | ||
|
||
module_cpu_feature_match(PMULL, crc_t10dif_mod_init); | ||
module_cpu_feature_match(ASIMD, crc_t10dif_mod_init); | ||
module_exit(crc_t10dif_mod_exit); | ||
|
||
MODULE_AUTHOR("Ard Biesheuvel <[email protected]>"); | ||
MODULE_LICENSE("GPL v2"); | ||
MODULE_ALIAS_CRYPTO("crct10dif"); | ||
MODULE_ALIAS_CRYPTO("crct10dif-arm64-ce"); |