]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
riscv/crc-t10dif: add Zbc optimized CRC-T10DIF function
authorEric Biggers <ebiggers@google.com>
Sun, 16 Feb 2025 22:55:29 +0000 (14:55 -0800)
committerEric Biggers <ebiggers@google.com>
Mon, 10 Mar 2025 16:29:25 +0000 (09:29 -0700)
Wire up crc_t10dif_arch() for RISC-V using crc-clmul-template.h.  This
greatly improves CRC-T10DIF performance on Zbc-capable CPUs.

Tested-by: Björn Töpel <bjorn@rivosinc.com>
Acked-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Link: https://lore.kernel.org/r/20250216225530.306980-4-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
arch/riscv/Kconfig
arch/riscv/lib/Makefile
arch/riscv/lib/crc-clmul-consts.h
arch/riscv/lib/crc-clmul.h
arch/riscv/lib/crc-t10dif.c [new file with mode: 0644]
arch/riscv/lib/crc16_msb.c [new file with mode: 0644]

index 7612c52e9b1e35607f1dd4603a596416d3357a71..db1cf9666dfdd17d354f0a29ccb9191b7be88f72 100644 (file)
@@ -25,6 +25,7 @@ config RISCV
        select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
        select ARCH_HAS_BINFMT_FLAT
        select ARCH_HAS_CRC32 if RISCV_ISA_ZBC
+       select ARCH_HAS_CRC_T10DIF if RISCV_ISA_ZBC
        select ARCH_HAS_CURRENT_STACK_POINTER
        select ARCH_HAS_DEBUG_VIRTUAL if MMU
        select ARCH_HAS_DEBUG_VM_PGTABLE
index 7b32d3e88337a70eeb9665c75c5dc55a231c21a4..06d9552b9c8b811058452349c1183e83a1f61d75 100644 (file)
@@ -17,6 +17,8 @@ lib-$(CONFIG_64BIT)   += tishift.o
 lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
 obj-$(CONFIG_CRC32_ARCH)       += crc32-riscv.o
 crc32-riscv-y := crc32.o crc32_msb.o crc32_lsb.o
+obj-$(CONFIG_CRC_T10DIF_ARCH)  += crc-t10dif-riscv.o
+crc-t10dif-riscv-y := crc-t10dif.o crc16_msb.o
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 lib-$(CONFIG_RISCV_ISA_V)      += xor.o
 lib-$(CONFIG_RISCV_ISA_V)      += riscv_v_helpers.o
index 6fdf10648a20750935770c4fb40c1dfc9ed6ea81..b3a02b9096cd150429d9e680f3b89d0c57593384 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * CRC constants generated by:
  *
- *     ./scripts/gen-crc-consts.py riscv_clmul crc32_msb_0x04c11db7,crc32_lsb_0xedb88320,crc32_lsb_0x82f63b78
+ *     ./scripts/gen-crc-consts.py riscv_clmul crc16_msb_0x8bb7,crc32_msb_0x04c11db7,crc32_lsb_0xedb88320,crc32_lsb_0x82f63b78
  *
  * Do not edit manually.
  */
@@ -14,6 +14,24 @@ struct crc_clmul_consts {
        unsigned long barrett_reduction_const_2;
 };
 
+/*
+ * Constants generated for most-significant-bit-first CRC-16 using
+ * G(x) = x^16 + x^15 + x^11 + x^9 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + x^0
+ */
+static const struct crc_clmul_consts crc16_msb_0x8bb7_consts __maybe_unused = {
+#ifdef CONFIG_64BIT
+       .fold_across_2_longs_const_hi = 0x0000000000001faa, /* x^192 mod G */
+       .fold_across_2_longs_const_lo = 0x000000000000a010, /* x^128 mod G */
+       .barrett_reduction_const_1 = 0xfb2d2bfc0e99d245, /* floor(x^79 / G) */
+       .barrett_reduction_const_2 = 0x0000000000008bb7, /* G - x^16 */
+#else
+       .fold_across_2_longs_const_hi = 0x00005890, /* x^96 mod G */
+       .fold_across_2_longs_const_lo = 0x0000f249, /* x^64 mod G */
+       .barrett_reduction_const_1 = 0xfb2d2bfc, /* floor(x^47 / G) */
+       .barrett_reduction_const_2 = 0x00008bb7, /* G - x^16 */
+#endif
+};
+
 /*
  * Constants generated for most-significant-bit-first CRC-32 using
  * G(x) = x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 +
index 62bd410807850896a40a3e25dcbcc9800d8497a4..162c1b12b219a389438dadcd575692eadf01790b 100644 (file)
@@ -7,6 +7,8 @@
 #include <linux/types.h>
 #include "crc-clmul-consts.h"
 
+u16 crc16_msb_clmul(u16 crc, const void *p, size_t len,
+                   const struct crc_clmul_consts *consts);
 u32 crc32_msb_clmul(u32 crc, const void *p, size_t len,
                    const struct crc_clmul_consts *consts);
 u32 crc32_lsb_clmul(u32 crc, const void *p, size_t len,
diff --git a/arch/riscv/lib/crc-t10dif.c b/arch/riscv/lib/crc-t10dif.c
new file mode 100644 (file)
index 0000000..e6b0051
--- /dev/null
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * RISC-V optimized CRC-T10DIF function
+ *
+ * Copyright 2025 Google LLC
+ */
+
+#include <asm/hwcap.h>
+#include <asm/alternative-macros.h>
+#include <linux/crc-t10dif.h>
+#include <linux/module.h>
+
+#include "crc-clmul.h"
+
+u16 crc_t10dif_arch(u16 crc, const u8 *p, size_t len)
+{
+       if (riscv_has_extension_likely(RISCV_ISA_EXT_ZBC))
+               return crc16_msb_clmul(crc, p, len, &crc16_msb_0x8bb7_consts);
+       return crc_t10dif_generic(crc, p, len);
+}
+EXPORT_SYMBOL(crc_t10dif_arch);
+
+MODULE_DESCRIPTION("RISC-V optimized CRC-T10DIF function");
+MODULE_LICENSE("GPL");
diff --git a/arch/riscv/lib/crc16_msb.c b/arch/riscv/lib/crc16_msb.c
new file mode 100644 (file)
index 0000000..554d295
--- /dev/null
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * RISC-V optimized most-significant-bit-first CRC16
+ *
+ * Copyright 2025 Google LLC
+ */
+
+#include "crc-clmul.h"
+
+typedef u16 crc_t;
+#define LSB_CRC 0
+#include "crc-clmul-template.h"
+
+u16 crc16_msb_clmul(u16 crc, const void *p, size_t len,
+                   const struct crc_clmul_consts *consts)
+{
+       return crc_clmul(crc, p, len, consts);
+}