xref: /linux/arch/x86/lib/crc64.c (revision 15d90a5e5524532b7456a24f4626cf28c1629c4c)
135984c73SEric Biggers // SPDX-License-Identifier: GPL-2.0-or-later
235984c73SEric Biggers /*
335984c73SEric Biggers  * CRC64 using [V]PCLMULQDQ instructions
435984c73SEric Biggers  *
535984c73SEric Biggers  * Copyright 2025 Google LLC
635984c73SEric Biggers  */
735984c73SEric Biggers 
835984c73SEric Biggers #include <linux/crc64.h>
935984c73SEric Biggers #include <linux/module.h>
1035984c73SEric Biggers #include "crc-pclmul-template.h"
1135984c73SEric Biggers 
1235984c73SEric Biggers static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_pclmulqdq);
1335984c73SEric Biggers 
1435984c73SEric Biggers DECLARE_CRC_PCLMUL_FUNCS(crc64_msb, u64);
1535984c73SEric Biggers DECLARE_CRC_PCLMUL_FUNCS(crc64_lsb, u64);
1635984c73SEric Biggers 
1735984c73SEric Biggers u64 crc64_be_arch(u64 crc, const u8 *p, size_t len)
1835984c73SEric Biggers {
1935984c73SEric Biggers 	CRC_PCLMUL(crc, p, len, crc64_msb, crc64_msb_0x42f0e1eba9ea3693_consts,
2035984c73SEric Biggers 		   have_pclmulqdq);
2135984c73SEric Biggers 	return crc64_be_generic(crc, p, len);
2235984c73SEric Biggers }
2335984c73SEric Biggers EXPORT_SYMBOL_GPL(crc64_be_arch);
2435984c73SEric Biggers 
2535984c73SEric Biggers u64 crc64_nvme_arch(u64 crc, const u8 *p, size_t len)
2635984c73SEric Biggers {
2735984c73SEric Biggers 	CRC_PCLMUL(crc, p, len, crc64_lsb, crc64_lsb_0x9a6c9329ac4bc9b5_consts,
2835984c73SEric Biggers 		   have_pclmulqdq);
2935984c73SEric Biggers 	return crc64_nvme_generic(crc, p, len);
3035984c73SEric Biggers }
3135984c73SEric Biggers EXPORT_SYMBOL_GPL(crc64_nvme_arch);
3235984c73SEric Biggers 
3335984c73SEric Biggers static int __init crc64_x86_init(void)
3435984c73SEric Biggers {
3535984c73SEric Biggers 	if (boot_cpu_has(X86_FEATURE_PCLMULQDQ)) {
3635984c73SEric Biggers 		static_branch_enable(&have_pclmulqdq);
3735984c73SEric Biggers 		INIT_CRC_PCLMUL(crc64_msb);
3835984c73SEric Biggers 		INIT_CRC_PCLMUL(crc64_lsb);
3935984c73SEric Biggers 	}
4035984c73SEric Biggers 	return 0;
4135984c73SEric Biggers }
42*648c7fb1SEric Biggers subsys_initcall(crc64_x86_init);
4335984c73SEric Biggers 
4435984c73SEric Biggers static void __exit crc64_x86_exit(void)
4535984c73SEric Biggers {
4635984c73SEric Biggers }
4735984c73SEric Biggers module_exit(crc64_x86_exit);
4835984c73SEric Biggers 
4935984c73SEric Biggers MODULE_DESCRIPTION("CRC64 using [V]PCLMULQDQ instructions");
5035984c73SEric Biggers MODULE_LICENSE("GPL");
51