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