163432fd6SDemian Shulhan /* SPDX-License-Identifier: GPL-2.0-only */ 263432fd6SDemian Shulhan /* 363432fd6SDemian Shulhan * CRC64 using ARM64 PMULL instructions 463432fd6SDemian Shulhan */ 563432fd6SDemian Shulhan 663432fd6SDemian Shulhan #include <linux/cpufeature.h> 763432fd6SDemian Shulhan #include <asm/simd.h> 863432fd6SDemian Shulhan #include <linux/minmax.h> 963432fd6SDemian Shulhan #include <linux/sizes.h> 1063432fd6SDemian Shulhan 1163432fd6SDemian Shulhan u64 crc64_nvme_arm64_c(u64 crc, const u8 *p, size_t len); 1263432fd6SDemian Shulhan 1363432fd6SDemian Shulhan #define crc64_be_arch crc64_be_generic 1463432fd6SDemian Shulhan 1563432fd6SDemian Shulhan static inline u64 crc64_nvme_arch(u64 crc, const u8 *p, size_t len) 1663432fd6SDemian Shulhan { 1763432fd6SDemian Shulhan if (len >= 128 && cpu_have_named_feature(PMULL) && 1863432fd6SDemian Shulhan likely(may_use_simd())) { 19*e0718ed6SArd Biesheuvel size_t chunk = len & ~15; 2063432fd6SDemian Shulhan 2163432fd6SDemian Shulhan scoped_ksimd() 2263432fd6SDemian Shulhan crc = crc64_nvme_arm64_c(crc, p, chunk); 2363432fd6SDemian Shulhan 2463432fd6SDemian Shulhan p += chunk; 25*e0718ed6SArd Biesheuvel len &= 15; 2663432fd6SDemian Shulhan } 2763432fd6SDemian Shulhan return crc64_nvme_generic(crc, p, len); 2863432fd6SDemian Shulhan } 29