From: Eric Biggers <ebigg...@google.com>

Now that crc_t10dif_update() may be directly optimized for each
architecture, make the shash driver for crct10dif register a
crct10dif-$arch algorithm that uses it, instead of only
crct10dif-generic which uses crc_t10dif_generic().

The result is that architecture-optimized crct10dif will remain
available through the shash API once the architectures implement
crc_t10dif_arch() instead of the shash API.

Signed-off-by: Eric Biggers <ebigg...@google.com>
---
 crypto/Makefile            |  1 +
 crypto/crct10dif_generic.c | 82 +++++++++++++++++++++++++++++---------
 2 files changed, 65 insertions(+), 18 deletions(-)

diff --git a/crypto/Makefile b/crypto/Makefile
index e948a883f151..8361fdb1a27d 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -153,10 +153,11 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
 obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_generic.o
 obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o
 CFLAGS_crc32c_generic.o += -DARCH=$(ARCH)
 CFLAGS_crc32_generic.o += -DARCH=$(ARCH)
 obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_generic.o
+CFLAGS_crct10dif_generic.o += -DARCH=$(ARCH)
 obj-$(CONFIG_CRYPTO_CRC64_ROCKSOFT) += crc64_rocksoft_generic.o
 obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
 obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o
 obj-$(CONFIG_CRYPTO_LZ4) += lz4.o
 obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o
diff --git a/crypto/crct10dif_generic.c b/crypto/crct10dif_generic.c
index e843982073bb..259cb01932cb 100644
--- a/crypto/crct10dif_generic.c
+++ b/crypto/crct10dif_generic.c
@@ -55,10 +55,19 @@ static int chksum_update(struct shash_desc *desc, const u8 
*data,
 
        ctx->crc = crc_t10dif_generic(ctx->crc, data, length);
        return 0;
 }
 
+static int chksum_update_arch(struct shash_desc *desc, const u8 *data,
+                             unsigned int length)
+{
+       struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
+
+       ctx->crc = crc_t10dif_update(ctx->crc, data, length);
+       return 0;
+}
+
 static int chksum_final(struct shash_desc *desc, u8 *out)
 {
        struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
 
        *(__u16 *)out = ctx->crc;
@@ -69,49 +78,86 @@ static int __chksum_finup(__u16 crc, const u8 *data, 
unsigned int len, u8 *out)
 {
        *(__u16 *)out = crc_t10dif_generic(crc, data, len);
        return 0;
 }
 
+static int __chksum_finup_arch(__u16 crc, const u8 *data, unsigned int len,
+                              u8 *out)
+{
+       *(__u16 *)out = crc_t10dif_update(crc, data, len);
+       return 0;
+}
+
 static int chksum_finup(struct shash_desc *desc, const u8 *data,
                        unsigned int len, u8 *out)
 {
        struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
 
        return __chksum_finup(ctx->crc, data, len, out);
 }
 
+static int chksum_finup_arch(struct shash_desc *desc, const u8 *data,
+                            unsigned int len, u8 *out)
+{
+       struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
+
+       return __chksum_finup_arch(ctx->crc, data, len, out);
+}
+
 static int chksum_digest(struct shash_desc *desc, const u8 *data,
                         unsigned int length, u8 *out)
 {
        return __chksum_finup(0, data, length, out);
 }
 
-static struct shash_alg alg = {
-       .digestsize             =       CRC_T10DIF_DIGEST_SIZE,
-       .init           =       chksum_init,
-       .update         =       chksum_update,
-       .final          =       chksum_final,
-       .finup          =       chksum_finup,
-       .digest         =       chksum_digest,
-       .descsize               =       sizeof(struct chksum_desc_ctx),
-       .base                   =       {
-               .cra_name               =       "crct10dif",
-               .cra_driver_name        =       "crct10dif-generic",
-               .cra_priority           =       100,
-               .cra_blocksize          =       CRC_T10DIF_BLOCK_SIZE,
-               .cra_module             =       THIS_MODULE,
-       }
-};
+static int chksum_digest_arch(struct shash_desc *desc, const u8 *data,
+                             unsigned int length, u8 *out)
+{
+       return __chksum_finup_arch(0, data, length, out);
+}
+
+static struct shash_alg algs[] = {{
+       .digestsize             = CRC_T10DIF_DIGEST_SIZE,
+       .init                   = chksum_init,
+       .update                 = chksum_update,
+       .final                  = chksum_final,
+       .finup                  = chksum_finup,
+       .digest                 = chksum_digest,
+       .descsize               = sizeof(struct chksum_desc_ctx),
+       .base.cra_name          = "crct10dif",
+       .base.cra_driver_name   = "crct10dif-generic",
+       .base.cra_priority      = 100,
+       .base.cra_blocksize     = CRC_T10DIF_BLOCK_SIZE,
+       .base.cra_module        = THIS_MODULE,
+}, {
+       .digestsize             = CRC_T10DIF_DIGEST_SIZE,
+       .init                   = chksum_init,
+       .update                 = chksum_update_arch,
+       .final                  = chksum_final,
+       .finup                  = chksum_finup_arch,
+       .digest                 = chksum_digest_arch,
+       .descsize               = sizeof(struct chksum_desc_ctx),
+       .base.cra_name          = "crct10dif",
+       .base.cra_driver_name   = "crct10dif-" __stringify(ARCH),
+       .base.cra_priority      = 150,
+       .base.cra_blocksize     = CRC_T10DIF_BLOCK_SIZE,
+       .base.cra_module        = THIS_MODULE,
+}};
+
+static int num_algs;
 
 static int __init crct10dif_mod_init(void)
 {
-       return crypto_register_shash(&alg);
+       /* register the arch flavor only if it differs from the generic one */
+       num_algs = 1 + crc_t10dif_is_optimized();
+
+       return crypto_register_shashes(algs, num_algs);
 }
 
 static void __exit crct10dif_mod_fini(void)
 {
-       crypto_unregister_shash(&alg);
+       crypto_unregister_shashes(algs, num_algs);
 }
 
 subsys_initcall(crct10dif_mod_init);
 module_exit(crct10dif_mod_fini);
 
-- 
2.47.0


Reply via email to