Re: [PATCH] riscv, lib: Fix Zbb strncmp

Palmer Dabbelt
2023-02-28T21:55:27Z

On Tue, 28 Feb 2023 13:18:12 PST (-0800), linux@roeck-us.net wrote:
> On 2/28/23 10:42, Björn Töpel wrote:
>> From: Björn Töpel <bjorn@rivosinc.com>
>>
>> The Zbb optimized strncmp has two parts; a fast path that does XLEN/8B
>> per iteration, and a slow that does one byte per iteration.
>>
>> The idea is to compare aligned XLEN chunks for most of strings, and do
>> the remainder tail in the slow path.
>>
>> The Zbb strncmp has two issues in the fast path:
>>
>> Incorrect remainder handling (wrong compare): Assume that the string
>> length is 9. On 64b systems, the fast path should do one iteration,
>> and one iteration in the slow path. Instead, both were done in the
>> fast path, which lead to incorrect results. An example:
>>
>> strncmp("/dev/vda", "/dev/", 5);
>>
>> Correct by changing "bgt" to "bge".
>>
>> Missing NULL checks in the second string: This could lead to incorrect
>> results for:
>>
>> strncmp("/dev/vda", "/dev/vda\0", 8);
>>
>> Correct by adding an additional check.
>>
>> Fixes: b6fcdb191e36 ("RISC-V: add zbb support to string functions")
>> Suggested-by: Heiko Stuebner <heiko.stuebner@vrull.eu>
>> Signed-off-by: Björn Töpel <bjorn@rivosinc.com>
>
> Tested-by: Guenter Roeck <linux@roeck-us.net>

Thanks guys, I'm going to apply this ASAP as it's a pretty concrete
breakage in new code from this merge window. I just stuck it in my
staging branch, it should show up on for-next after the next batch of
tests.

>
>> ---
>> arch/riscv/lib/strncmp.S | 4 +++-
>> 1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/riscv/lib/strncmp.S b/arch/riscv/lib/strncmp.S
>> index ee49595075be..efd3f3150a54 100644
>> --- a/arch/riscv/lib/strncmp.S
>> +++ b/arch/riscv/lib/strncmp.S
>> @@ -78,11 +78,13 @@ strncmp_zbb:
>> /* Main loop for aligned string. */
>> .p2align 3
>> 1:
>> - bgt a0, t6, 3f
>> + 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
>>
>> base-commit: eb9be8310c58c166f9fae3b71c0ad9d6741b4897