]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
arm/crc-t10dif: expose CRC-T10DIF function through lib
authorEric Biggers <ebiggers@google.com>
Mon, 2 Dec 2024 01:20:49 +0000 (17:20 -0800)
committerEric Biggers <ebiggers@google.com>
Mon, 2 Dec 2024 01:23:13 +0000 (17:23 -0800)
Move the arm CRC-T10DIF assembly code into the lib directory and wire it
up to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/arm/crypto/crct10dif-ce-glue.c to
arch/arm/lib/crc-t10dif-glue.c, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Link: https://lore.kernel.org/r/20241202012056.209768-6-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
arch/arm/Kconfig
arch/arm/crypto/Kconfig
arch/arm/crypto/Makefile
arch/arm/crypto/crct10dif-ce-glue.c [deleted file]
arch/arm/lib/Makefile
arch/arm/lib/crc-t10dif-core.S [moved from arch/arm/crypto/crct10dif-ce-core.S with 100% similarity]
arch/arm/lib/crc-t10dif-glue.c [new file with mode: 0644]

index f817ca317b02a90b6a903d20f6c03ca5f02bf613..3ad4c3c979180713e91d6b491013e73d3b0f5fe0 100644 (file)
@@ -8,6 +8,7 @@ config ARM
        select ARCH_HAS_CPU_CACHE_ALIASING
        select ARCH_HAS_CPU_FINALIZE_INIT if MMU
        select ARCH_HAS_CRC32 if KERNEL_MODE_NEON
+       select ARCH_HAS_CRC_T10DIF if KERNEL_MODE_NEON
        select ARCH_HAS_CURRENT_STACK_POINTER
        select ARCH_HAS_DEBUG_VIRTUAL if MMU
        select ARCH_HAS_DMA_ALLOC if MMU
index ea0ebf336d0dee98cf36db0426889b8ad0f20da1..32650c8431d988fd5b5f49b118ee93fd2ee9713c 100644 (file)
@@ -222,16 +222,5 @@ config CRYPTO_CHACHA20_NEON
          Architecture: arm using:
          - NEON (Advanced SIMD) extensions
 
-config CRYPTO_CRCT10DIF_ARM_CE
-       tristate "CRCT10DIF"
-       depends on KERNEL_MODE_NEON
-       depends on CRC_T10DIF
-       select CRYPTO_HASH
-       help
-         CRC16 CRC algorithm used for the T10 (SCSI) Data Integrity Field (DIF)
-
-         Architecture: arm using:
-         - PMULL (Polynomial Multiply Long) instructions
-
 endmenu
 
index 38ec5cc1e8442d98cea6ff006a93af5e0975c437..3d0e23ff9e7465391dc9a0065645f16833541f62 100644 (file)
@@ -20,7 +20,6 @@ obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA2_ARM_CE) += sha2-arm-ce.o
 obj-$(CONFIG_CRYPTO_GHASH_ARM_CE) += ghash-arm-ce.o
-obj-$(CONFIG_CRYPTO_CRCT10DIF_ARM_CE) += crct10dif-arm-ce.o
 
 aes-arm-y      := aes-cipher-core.o aes-cipher-glue.o
 aes-arm-bs-y   := aes-neonbs-core.o aes-neonbs-glue.o
@@ -36,7 +35,6 @@ sha1-arm-ce-y := sha1-ce-core.o sha1-ce-glue.o
 sha2-arm-ce-y  := sha2-ce-core.o sha2-ce-glue.o
 aes-arm-ce-y   := aes-ce-core.o aes-ce-glue.o
 ghash-arm-ce-y := ghash-ce-core.o ghash-ce-glue.o
-crct10dif-arm-ce-y     := crct10dif-ce-core.o crct10dif-ce-glue.o
 chacha-neon-y := chacha-scalar-core.o chacha-glue.o
 chacha-neon-$(CONFIG_KERNEL_MODE_NEON) += chacha-neon-core.o
 poly1305-arm-y := poly1305-core.o poly1305-glue.o
diff --git a/arch/arm/crypto/crct10dif-ce-glue.c b/arch/arm/crypto/crct10dif-ce-glue.c
deleted file mode 100644 (file)
index a8b7452..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Accelerated CRC-T10DIF using ARM NEON and Crypto Extensions instructions
- *
- * Copyright (C) 2016 Linaro Ltd <ard.biesheuvel@linaro.org>
- */
-
-#include <linux/crc-t10dif.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-
-#include <crypto/internal/hash.h>
-#include <crypto/internal/simd.h>
-
-#include <asm/neon.h>
-#include <asm/simd.h>
-
-#define CRC_T10DIF_PMULL_CHUNK_SIZE    16U
-
-asmlinkage u16 crc_t10dif_pmull64(u16 init_crc, const u8 *buf, size_t len);
-asmlinkage void crc_t10dif_pmull8(u16 init_crc, const u8 *buf, size_t len,
-                                 u8 out[16]);
-
-static int crct10dif_init(struct shash_desc *desc)
-{
-       u16 *crc = shash_desc_ctx(desc);
-
-       *crc = 0;
-       return 0;
-}
-
-static int crct10dif_update_ce(struct shash_desc *desc, const u8 *data,
-                              unsigned int length)
-{
-       u16 *crc = shash_desc_ctx(desc);
-
-       if (length >= CRC_T10DIF_PMULL_CHUNK_SIZE && crypto_simd_usable()) {
-               kernel_neon_begin();
-               *crc = crc_t10dif_pmull64(*crc, data, length);
-               kernel_neon_end();
-       } else {
-               *crc = crc_t10dif_generic(*crc, data, length);
-       }
-
-       return 0;
-}
-
-static int crct10dif_update_neon(struct shash_desc *desc, const u8 *data,
-                                unsigned int length)
-{
-       u16 *crcp = shash_desc_ctx(desc);
-       u8 buf[16] __aligned(16);
-       u16 crc = *crcp;
-
-       if (length > CRC_T10DIF_PMULL_CHUNK_SIZE && crypto_simd_usable()) {
-               kernel_neon_begin();
-               crc_t10dif_pmull8(crc, data, length, buf);
-               kernel_neon_end();
-
-               crc = 0;
-               data = buf;
-               length = sizeof(buf);
-       }
-
-       *crcp = crc_t10dif_generic(crc, data, length);
-       return 0;
-}
-
-static int crct10dif_final(struct shash_desc *desc, u8 *out)
-{
-       u16 *crc = shash_desc_ctx(desc);
-
-       *(u16 *)out = *crc;
-       return 0;
-}
-
-static struct shash_alg algs[] = {{
-       .digestsize             = CRC_T10DIF_DIGEST_SIZE,
-       .init                   = crct10dif_init,
-       .update                 = crct10dif_update_neon,
-       .final                  = crct10dif_final,
-       .descsize               = CRC_T10DIF_DIGEST_SIZE,
-
-       .base.cra_name          = "crct10dif",
-       .base.cra_driver_name   = "crct10dif-arm-neon",
-       .base.cra_priority      = 150,
-       .base.cra_blocksize     = CRC_T10DIF_BLOCK_SIZE,
-       .base.cra_module        = THIS_MODULE,
-}, {
-       .digestsize             = CRC_T10DIF_DIGEST_SIZE,
-       .init                   = crct10dif_init,
-       .update                 = crct10dif_update_ce,
-       .final                  = crct10dif_final,
-       .descsize               = CRC_T10DIF_DIGEST_SIZE,
-
-       .base.cra_name          = "crct10dif",
-       .base.cra_driver_name   = "crct10dif-arm-ce",
-       .base.cra_priority      = 200,
-       .base.cra_blocksize     = CRC_T10DIF_BLOCK_SIZE,
-       .base.cra_module        = THIS_MODULE,
-}};
-
-static int __init crc_t10dif_mod_init(void)
-{
-       if (!(elf_hwcap & HWCAP_NEON))
-               return -ENODEV;
-
-       return crypto_register_shashes(algs, 1 + !!(elf_hwcap2 & HWCAP2_PMULL));
-}
-
-static void __exit crc_t10dif_mod_exit(void)
-{
-       crypto_unregister_shashes(algs, 1 + !!(elf_hwcap2 & HWCAP2_PMULL));
-}
-
-module_init(crc_t10dif_mod_init);
-module_exit(crc_t10dif_mod_exit);
-
-MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
-MODULE_DESCRIPTION("Accelerated CRC-T10DIF using ARM NEON and Crypto Extensions");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS_CRYPTO("crct10dif");
index 01cd4db2ed472bf3aadb2a0a3b1f3f7d3d48b905..007874320937d840e0552a0f1e4184b7afece07b 100644 (file)
@@ -48,3 +48,6 @@ obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 
 obj-$(CONFIG_CRC32_ARCH) += crc32-arm.o
 crc32-arm-y := crc32-glue.o crc32-core.o
+
+obj-$(CONFIG_CRC_T10DIF_ARCH) += crc-t10dif-arm.o
+crc-t10dif-arm-y := crc-t10dif-glue.o crc-t10dif-core.o
diff --git a/arch/arm/lib/crc-t10dif-glue.c b/arch/arm/lib/crc-t10dif-glue.c
new file mode 100644 (file)
index 0000000..d24dee6
--- /dev/null
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Accelerated CRC-T10DIF using ARM NEON and Crypto Extensions instructions
+ *
+ * Copyright (C) 2016 Linaro Ltd <ard.biesheuvel@linaro.org>
+ */
+
+#include <linux/crc-t10dif.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include <crypto/internal/simd.h>
+
+#include <asm/neon.h>
+#include <asm/simd.h>
+
+static DEFINE_STATIC_KEY_FALSE(have_neon);
+static DEFINE_STATIC_KEY_FALSE(have_pmull);
+
+#define CRC_T10DIF_PMULL_CHUNK_SIZE    16U
+
+asmlinkage u16 crc_t10dif_pmull64(u16 init_crc, const u8 *buf, size_t len);
+asmlinkage void crc_t10dif_pmull8(u16 init_crc, const u8 *buf, size_t len,
+                                 u8 out[16]);
+
+u16 crc_t10dif_arch(u16 crc, const u8 *data, size_t length)
+{
+       if (length >= CRC_T10DIF_PMULL_CHUNK_SIZE) {
+               if (static_branch_likely(&have_pmull)) {
+                       if (crypto_simd_usable()) {
+                               kernel_neon_begin();
+                               crc = crc_t10dif_pmull64(crc, data, length);
+                               kernel_neon_end();
+                               return crc;
+                       }
+               } else if (length > CRC_T10DIF_PMULL_CHUNK_SIZE &&
+                          static_branch_likely(&have_neon) &&
+                          crypto_simd_usable()) {
+                       u8 buf[16] __aligned(16);
+
+                       kernel_neon_begin();
+                       crc_t10dif_pmull8(crc, data, length, buf);
+                       kernel_neon_end();
+
+                       crc = 0;
+                       data = buf;
+                       length = sizeof(buf);
+               }
+       }
+       return crc_t10dif_generic(crc, data, length);
+}
+EXPORT_SYMBOL(crc_t10dif_arch);
+
+static int __init crc_t10dif_arm_init(void)
+{
+       if (elf_hwcap & HWCAP_NEON) {
+               static_branch_enable(&have_neon);
+               if (elf_hwcap2 & HWCAP2_PMULL)
+                       static_branch_enable(&have_pmull);
+       }
+       return 0;
+}
+arch_initcall(crc_t10dif_arm_init);
+
+static void __exit crc_t10dif_arm_exit(void)
+{
+}
+module_exit(crc_t10dif_arm_exit);
+
+bool crc_t10dif_is_optimized(void)
+{
+       return static_key_enabled(&have_neon);
+}
+EXPORT_SYMBOL(crc_t10dif_is_optimized);
+
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_DESCRIPTION("Accelerated CRC-T10DIF using ARM NEON and Crypto Extensions");
+MODULE_LICENSE("GPL v2");