arm64/lib: Handle CRC-32 alternative in C code

In preparation for adding another code path for performing CRC-32, move
the alternative patching for ARM64_HAS_CRC32 into C code. The logic for
deciding whether to use this new code path will be implemented in C too.

Reviewed-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20241018075347.2821102-6-ardb+git@google.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
Ard Biesheuvel 2024-10-18 09:53:49 +02:00 committed by Catalin Marinas
parent 9852d85ec9
commit fc7454107d
3 changed files with 41 additions and 17 deletions

View File

@ -13,7 +13,7 @@ endif
lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
obj-$(CONFIG_CRC32) += crc32.o
obj-$(CONFIG_CRC32) += crc32.o crc32-glue.o
obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o

View File

@ -0,0 +1,34 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/crc32.h>
#include <linux/linkage.h>
#include <asm/alternative.h>
asmlinkage u32 crc32_le_arm64(u32 crc, unsigned char const *p, size_t len);
asmlinkage u32 crc32c_le_arm64(u32 crc, unsigned char const *p, size_t len);
asmlinkage u32 crc32_be_arm64(u32 crc, unsigned char const *p, size_t len);
u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
{
if (!alternative_has_cap_likely(ARM64_HAS_CRC32))
return crc32_le_base(crc, p, len);
return crc32_le_arm64(crc, p, len);
}
u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
{
if (!alternative_has_cap_likely(ARM64_HAS_CRC32))
return __crc32c_le_base(crc, p, len);
return crc32c_le_arm64(crc, p, len);
}
u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
{
if (!alternative_has_cap_likely(ARM64_HAS_CRC32))
return crc32_be_base(crc, p, len);
return crc32_be_arm64(crc, p, len);
}

View File

@ -6,7 +6,6 @@
*/
#include <linux/linkage.h>
#include <asm/alternative.h>
#include <asm/assembler.h>
.arch armv8-a+crc
@ -136,25 +135,16 @@ CPU_BE( rev16 \reg, \reg )
.endm
.align 5
SYM_FUNC_START(crc32_le)
alternative_if_not ARM64_HAS_CRC32
b crc32_le_base
alternative_else_nop_endif
SYM_FUNC_START(crc32_le_arm64)
__crc32
SYM_FUNC_END(crc32_le)
SYM_FUNC_END(crc32_le_arm64)
.align 5
SYM_FUNC_START(__crc32c_le)
alternative_if_not ARM64_HAS_CRC32
b __crc32c_le_base
alternative_else_nop_endif
SYM_FUNC_START(crc32c_le_arm64)
__crc32 c
SYM_FUNC_END(__crc32c_le)
SYM_FUNC_END(crc32c_le_arm64)
.align 5
SYM_FUNC_START(crc32_be)
alternative_if_not ARM64_HAS_CRC32
b crc32_be_base
alternative_else_nop_endif
SYM_FUNC_START(crc32_be_arm64)
__crc32 be=1
SYM_FUNC_END(crc32_be)
SYM_FUNC_END(crc32_be_arm64)