Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lib/crc: Switch ARM and arm64 to 'ksimd' scoped guard API

Before modifying the prototypes of kernel_neon_begin() and
kernel_neon_end() to accommodate kernel mode FP/SIMD state buffers
allocated on the stack, move arm64 to the new 'ksimd' scoped guard API,
which encapsulates the calls to those functions.

For symmetry, do the same for 32-bit ARM too.

Reviewed-by: Eric Biggers <ebiggers@kernel.org>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>

+22 -43
+6 -13
lib/crc/arm/crc-t10dif.h
··· 5 5 * Copyright (C) 2016 Linaro Ltd <ard.biesheuvel@linaro.org> 6 6 */ 7 7 8 - #include <asm/neon.h> 9 8 #include <asm/simd.h> 10 9 11 10 static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_neon); ··· 18 19 19 20 static inline u16 crc_t10dif_arch(u16 crc, const u8 *data, size_t length) 20 21 { 21 - if (length >= CRC_T10DIF_PMULL_CHUNK_SIZE) { 22 + if (length >= CRC_T10DIF_PMULL_CHUNK_SIZE && likely(may_use_simd())) { 22 23 if (static_branch_likely(&have_pmull)) { 23 - if (likely(may_use_simd())) { 24 - kernel_neon_begin(); 25 - crc = crc_t10dif_pmull64(crc, data, length); 26 - kernel_neon_end(); 27 - return crc; 28 - } 24 + scoped_ksimd() 25 + return crc_t10dif_pmull64(crc, data, length); 29 26 } else if (length > CRC_T10DIF_PMULL_CHUNK_SIZE && 30 - static_branch_likely(&have_neon) && 31 - likely(may_use_simd())) { 27 + static_branch_likely(&have_neon)) { 32 28 u8 buf[16] __aligned(16); 33 29 34 - kernel_neon_begin(); 35 - crc_t10dif_pmull8(crc, data, length, buf); 36 - kernel_neon_end(); 30 + scoped_ksimd() 31 + crc_t10dif_pmull8(crc, data, length, buf); 37 32 38 33 return crc_t10dif_generic(0, buf, sizeof(buf)); 39 34 }
+4 -7
lib/crc/arm/crc32.h
··· 8 8 #include <linux/cpufeature.h> 9 9 10 10 #include <asm/hwcap.h> 11 - #include <asm/neon.h> 12 11 #include <asm/simd.h> 13 12 14 13 static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_crc32); ··· 41 42 len -= n; 42 43 } 43 44 n = round_down(len, 16); 44 - kernel_neon_begin(); 45 - crc = crc32_pmull_le(p, n, crc); 46 - kernel_neon_end(); 45 + scoped_ksimd() 46 + crc = crc32_pmull_le(p, n, crc); 47 47 p += n; 48 48 len -= n; 49 49 } ··· 69 71 len -= n; 70 72 } 71 73 n = round_down(len, 16); 72 - kernel_neon_begin(); 73 - crc = crc32c_pmull_le(p, n, crc); 74 - kernel_neon_end(); 74 + scoped_ksimd() 75 + crc = crc32c_pmull_le(p, n, crc); 75 76 p += n; 76 77 len -= n; 77 78 }
+6 -13
lib/crc/arm64/crc-t10dif.h
··· 7 7 8 8 #include <linux/cpufeature.h> 9 9 10 - #include <asm/neon.h> 11 10 #include <asm/simd.h> 12 11 13 12 static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_asimd); ··· 20 21 21 22 static inline u16 crc_t10dif_arch(u16 crc, const u8 *data, size_t length) 22 23 { 23 - if (length >= CRC_T10DIF_PMULL_CHUNK_SIZE) { 24 + if (length >= CRC_T10DIF_PMULL_CHUNK_SIZE && likely(may_use_simd())) { 24 25 if (static_branch_likely(&have_pmull)) { 25 - if (likely(may_use_simd())) { 26 - kernel_neon_begin(); 27 - crc = crc_t10dif_pmull_p64(crc, data, length); 28 - kernel_neon_end(); 29 - return crc; 30 - } 26 + scoped_ksimd() 27 + return crc_t10dif_pmull_p64(crc, data, length); 31 28 } else if (length > CRC_T10DIF_PMULL_CHUNK_SIZE && 32 - static_branch_likely(&have_asimd) && 33 - likely(may_use_simd())) { 29 + static_branch_likely(&have_asimd)) { 34 30 u8 buf[16]; 35 31 36 - kernel_neon_begin(); 37 - crc_t10dif_pmull_p8(crc, data, length, buf); 38 - kernel_neon_end(); 32 + scoped_ksimd() 33 + crc_t10dif_pmull_p8(crc, data, length, buf); 39 34 40 35 return crc_t10dif_generic(0, buf, sizeof(buf)); 41 36 }
+6 -10
lib/crc/arm64/crc32.h
··· 2 2 3 3 #include <asm/alternative.h> 4 4 #include <asm/cpufeature.h> 5 - #include <asm/neon.h> 6 5 #include <asm/simd.h> 7 6 8 7 // The minimum input length to consider the 4-way interleaved code path ··· 22 23 23 24 if (len >= min_len && cpu_have_named_feature(PMULL) && 24 25 likely(may_use_simd())) { 25 - kernel_neon_begin(); 26 - crc = crc32_le_arm64_4way(crc, p, len); 27 - kernel_neon_end(); 26 + scoped_ksimd() 27 + crc = crc32_le_arm64_4way(crc, p, len); 28 28 29 29 p += round_down(len, 64); 30 30 len %= 64; ··· 42 44 43 45 if (len >= min_len && cpu_have_named_feature(PMULL) && 44 46 likely(may_use_simd())) { 45 - kernel_neon_begin(); 46 - crc = crc32c_le_arm64_4way(crc, p, len); 47 - kernel_neon_end(); 47 + scoped_ksimd() 48 + crc = crc32c_le_arm64_4way(crc, p, len); 48 49 49 50 p += round_down(len, 64); 50 51 len %= 64; ··· 62 65 63 66 if (len >= min_len && cpu_have_named_feature(PMULL) && 64 67 likely(may_use_simd())) { 65 - kernel_neon_begin(); 66 - crc = crc32_be_arm64_4way(crc, p, len); 67 - kernel_neon_end(); 68 + scoped_ksimd() 69 + crc = crc32_be_arm64_4way(crc, p, len); 68 70 69 71 p += round_down(len, 64); 70 72 len %= 64;