Skip to content

Commit 8bf3e17

Browse files
committed
riscv/crc-t10dif: add Zbc optimized CRC-T10DIF function
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 <[email protected]> Acked-by: Alexandre Ghiti <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Eric Biggers <[email protected]>
1 parent 72acff5 commit 8bf3e17

File tree

6 files changed

+66
-1
lines changed

6 files changed

+66
-1
lines changed

arch/riscv/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ config RISCV
2525
select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
2626
select ARCH_HAS_BINFMT_FLAT
2727
select ARCH_HAS_CRC32 if RISCV_ISA_ZBC
28+
select ARCH_HAS_CRC_T10DIF if RISCV_ISA_ZBC
2829
select ARCH_HAS_CURRENT_STACK_POINTER
2930
select ARCH_HAS_DEBUG_VIRTUAL if MMU
3031
select ARCH_HAS_DEBUG_VM_PGTABLE

arch/riscv/lib/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ lib-$(CONFIG_64BIT) += tishift.o
1717
lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
1818
obj-$(CONFIG_CRC32_ARCH) += crc32-riscv.o
1919
crc32-riscv-y := crc32.o crc32_msb.o crc32_lsb.o
20+
obj-$(CONFIG_CRC_T10DIF_ARCH) += crc-t10dif-riscv.o
21+
crc-t10dif-riscv-y := crc-t10dif.o crc16_msb.o
2022
obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
2123
lib-$(CONFIG_RISCV_ISA_V) += xor.o
2224
lib-$(CONFIG_RISCV_ISA_V) += riscv_v_helpers.o

arch/riscv/lib/crc-clmul-consts.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/*
33
* CRC constants generated by:
44
*
5-
* ./scripts/gen-crc-consts.py riscv_clmul crc32_msb_0x04c11db7,crc32_lsb_0xedb88320,crc32_lsb_0x82f63b78
5+
* ./scripts/gen-crc-consts.py riscv_clmul crc16_msb_0x8bb7,crc32_msb_0x04c11db7,crc32_lsb_0xedb88320,crc32_lsb_0x82f63b78
66
*
77
* Do not edit manually.
88
*/
@@ -14,6 +14,24 @@ struct crc_clmul_consts {
1414
unsigned long barrett_reduction_const_2;
1515
};
1616

17+
/*
18+
* Constants generated for most-significant-bit-first CRC-16 using
19+
* G(x) = x^16 + x^15 + x^11 + x^9 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + x^0
20+
*/
21+
static const struct crc_clmul_consts crc16_msb_0x8bb7_consts __maybe_unused = {
22+
#ifdef CONFIG_64BIT
23+
.fold_across_2_longs_const_hi = 0x0000000000001faa, /* x^192 mod G */
24+
.fold_across_2_longs_const_lo = 0x000000000000a010, /* x^128 mod G */
25+
.barrett_reduction_const_1 = 0xfb2d2bfc0e99d245, /* floor(x^79 / G) */
26+
.barrett_reduction_const_2 = 0x0000000000008bb7, /* G - x^16 */
27+
#else
28+
.fold_across_2_longs_const_hi = 0x00005890, /* x^96 mod G */
29+
.fold_across_2_longs_const_lo = 0x0000f249, /* x^64 mod G */
30+
.barrett_reduction_const_1 = 0xfb2d2bfc, /* floor(x^47 / G) */
31+
.barrett_reduction_const_2 = 0x00008bb7, /* G - x^16 */
32+
#endif
33+
};
34+
1735
/*
1836
* Constants generated for most-significant-bit-first CRC-32 using
1937
* G(x) = x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 +

arch/riscv/lib/crc-clmul.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <linux/types.h>
88
#include "crc-clmul-consts.h"
99

10+
u16 crc16_msb_clmul(u16 crc, const void *p, size_t len,
11+
const struct crc_clmul_consts *consts);
1012
u32 crc32_msb_clmul(u32 crc, const void *p, size_t len,
1113
const struct crc_clmul_consts *consts);
1214
u32 crc32_lsb_clmul(u32 crc, const void *p, size_t len,

arch/riscv/lib/crc-t10dif.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* RISC-V optimized CRC-T10DIF function
4+
*
5+
* Copyright 2025 Google LLC
6+
*/
7+
8+
#include <asm/hwcap.h>
9+
#include <asm/alternative-macros.h>
10+
#include <linux/crc-t10dif.h>
11+
#include <linux/module.h>
12+
13+
#include "crc-clmul.h"
14+
15+
u16 crc_t10dif_arch(u16 crc, const u8 *p, size_t len)
16+
{
17+
if (riscv_has_extension_likely(RISCV_ISA_EXT_ZBC))
18+
return crc16_msb_clmul(crc, p, len, &crc16_msb_0x8bb7_consts);
19+
return crc_t10dif_generic(crc, p, len);
20+
}
21+
EXPORT_SYMBOL(crc_t10dif_arch);
22+
23+
MODULE_DESCRIPTION("RISC-V optimized CRC-T10DIF function");
24+
MODULE_LICENSE("GPL");

arch/riscv/lib/crc16_msb.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* RISC-V optimized most-significant-bit-first CRC16
4+
*
5+
* Copyright 2025 Google LLC
6+
*/
7+
8+
#include "crc-clmul.h"
9+
10+
typedef u16 crc_t;
11+
#define LSB_CRC 0
12+
#include "crc-clmul-template.h"
13+
14+
u16 crc16_msb_clmul(u16 crc, const void *p, size_t len,
15+
const struct crc_clmul_consts *consts)
16+
{
17+
return crc_clmul(crc, p, len, consts);
18+
}

0 commit comments

Comments
 (0)