5835437609
Samuel Holland <samuel.holland@sifive.com> says: This series fixes two areas where uninstrumented assembly routines caused gaps in KASAN coverage on RISC-V, which were caught by KUnit tests. The KASAN KUnit test suite passes after applying this series. This series fixes the following test failures: # kasan_strings: EXPECTATION FAILED at mm/kasan/kasan_test.c:1520 KASAN failure expected in "kasan_int_result = strcmp(ptr, "2")", but none occurred # kasan_strings: EXPECTATION FAILED at mm/kasan/kasan_test.c:1524 KASAN failure expected in "kasan_int_result = strlen(ptr)", but none occurred not ok 60 kasan_strings # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1531 KASAN failure expected in "set_bit(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1533 KASAN failure expected in "clear_bit(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1535 KASAN failure expected in "clear_bit_unlock(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1536 KASAN failure expected in "__clear_bit_unlock(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1537 KASAN failure expected in "change_bit(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1543 KASAN failure expected in "test_and_set_bit(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1545 KASAN failure expected in "test_and_set_bit_lock(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1546 KASAN failure expected in "test_and_clear_bit(nr, addr)", but none occurred # kasan_bitops_generic: EXPECTATION FAILED at mm/kasan/kasan_test.c:1548 KASAN failure expected in "test_and_change_bit(nr, addr)", but none occurred not ok 61 kasan_bitops_generic Samuel Holland (2): riscv: Omit optimized string routines when using KASAN riscv: Enable bitops instrumentation arch/riscv/include/asm/bitops.h | 43 ++++++++++++++++++--------------- arch/riscv/include/asm/string.h | 2 ++ arch/riscv/kernel/riscv_ksyms.c | 3 --- arch/riscv/lib/Makefile | 2 ++ arch/riscv/lib/strcmp.S | 1 + arch/riscv/lib/strlen.S | 1 + arch/riscv/lib/strncmp.S | 1 + arch/riscv/purgatory/Makefile | 2 ++ 8 files changed, 32 insertions(+), 23 deletions(-) * b4-shazam-merge: riscv: Enable bitops instrumentation riscv: Omit optimized string routines when using KASAN Link: https://lore.kernel.org/r/20240801033725.28816-1-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
141 lines
2.2 KiB
ArmAsm
141 lines
2.2 KiB
ArmAsm
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
|
|
#include <linux/linkage.h>
|
|
#include <asm/asm.h>
|
|
#include <asm/alternative-macros.h>
|
|
#include <asm/hwcap.h>
|
|
|
|
/* int strncmp(const char *cs, const char *ct, size_t count) */
|
|
SYM_FUNC_START(strncmp)
|
|
|
|
ALTERNATIVE("nop", "j strncmp_zbb", 0, RISCV_ISA_EXT_ZBB, CONFIG_RISCV_ISA_ZBB)
|
|
|
|
/*
|
|
* Returns
|
|
* a0 - comparison result, value like strncmp
|
|
*
|
|
* Parameters
|
|
* a0 - string1
|
|
* a1 - string2
|
|
* a2 - number of characters to compare
|
|
*
|
|
* Clobbers
|
|
* t0, t1, t2
|
|
*/
|
|
li t2, 0
|
|
1:
|
|
beq a2, t2, 2f
|
|
lbu t0, 0(a0)
|
|
lbu t1, 0(a1)
|
|
addi a0, a0, 1
|
|
addi a1, a1, 1
|
|
bne t0, t1, 3f
|
|
addi t2, t2, 1
|
|
bnez t0, 1b
|
|
2:
|
|
li a0, 0
|
|
ret
|
|
3:
|
|
/*
|
|
* strncmp only needs to return (< 0, 0, > 0) values
|
|
* not necessarily -1, 0, +1
|
|
*/
|
|
sub a0, t0, t1
|
|
ret
|
|
|
|
/*
|
|
* Variant of strncmp using the ZBB extension if available
|
|
*/
|
|
#ifdef CONFIG_RISCV_ISA_ZBB
|
|
strncmp_zbb:
|
|
|
|
.option push
|
|
.option arch,+zbb
|
|
|
|
/*
|
|
* Returns
|
|
* a0 - comparison result, like strncmp
|
|
*
|
|
* Parameters
|
|
* a0 - string1
|
|
* a1 - string2
|
|
* a2 - number of characters to compare
|
|
*
|
|
* Clobbers
|
|
* t0, t1, t2, t3, t4, t5, t6
|
|
*/
|
|
|
|
or t2, a0, a1
|
|
li t5, -1
|
|
and t2, t2, SZREG-1
|
|
add t4, a0, a2
|
|
bnez t2, 3f
|
|
|
|
/* Adjust limit for fast-path. */
|
|
andi t6, t4, -SZREG
|
|
|
|
/* Main loop for aligned string. */
|
|
.p2align 3
|
|
1:
|
|
bge a0, t6, 3f
|
|
REG_L t0, 0(a0)
|
|
REG_L t1, 0(a1)
|
|
orc.b t3, t0
|
|
bne t3, t5, 2f
|
|
orc.b t3, t1
|
|
bne t3, t5, 2f
|
|
addi a0, a0, SZREG
|
|
addi a1, a1, SZREG
|
|
beq t0, t1, 1b
|
|
|
|
/*
|
|
* Words don't match, and no null byte in the first
|
|
* word. Get bytes in big-endian order and compare.
|
|
*/
|
|
#ifndef CONFIG_CPU_BIG_ENDIAN
|
|
rev8 t0, t0
|
|
rev8 t1, t1
|
|
#endif
|
|
|
|
/* Synthesize (t0 >= t1) ? 1 : -1 in a branchless sequence. */
|
|
sltu a0, t0, t1
|
|
neg a0, a0
|
|
ori a0, a0, 1
|
|
ret
|
|
|
|
2:
|
|
/*
|
|
* Found a null byte.
|
|
* If words don't match, fall back to simple loop.
|
|
*/
|
|
bne t0, t1, 3f
|
|
|
|
/* Otherwise, strings are equal. */
|
|
li a0, 0
|
|
ret
|
|
|
|
/* Simple loop for misaligned strings. */
|
|
.p2align 3
|
|
3:
|
|
bge a0, t4, 5f
|
|
lbu t0, 0(a0)
|
|
lbu t1, 0(a1)
|
|
addi a0, a0, 1
|
|
addi a1, a1, 1
|
|
bne t0, t1, 4f
|
|
bnez t0, 3b
|
|
|
|
4:
|
|
sub a0, t0, t1
|
|
ret
|
|
|
|
5:
|
|
li a0, 0
|
|
ret
|
|
|
|
.option pop
|
|
#endif
|
|
SYM_FUNC_END(strncmp)
|
|
SYM_FUNC_ALIAS(__pi_strncmp, strncmp)
|
|
EXPORT_SYMBOL(strncmp)
|