mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git
synced 2025-09-14 11:19:08 +10:00
raid6: riscv: Fix NULL pointer dereference caused by a missing clobber
When running the raid6 user-space test program on RISC-V QEMU, there's a
segmentation fault which seems caused by accessing a NULL pointer,
which is the pointer variable p/q in raid6_rvv*_gen/xor_syndrome_real(),
p/q should have been equal to dptr[x], but when I use GDB command to
see its value, which was 0x10 like below:
"
Program received signal SIGSEGV, Segmentation fault.
0x0000000000011062 in raid6_rvv2_xor_syndrome_real (disks=<optimized out>, start=0, stop=<optimized out>, bytes=4096, ptrs=<optimized out>) at rvv.c:386
(gdb) p p
$1 = (u8 *) 0x10 <error: Cannot access memory at address 0x10>
"
The issue was found to be related with:
1) Compile optimization
There's no segmentation fault if compiling the raid6test program with
the optimization flag -O0.
2) The RISC-V vector command vsetvli
If not used t0 as the first parameter in vsetvli, there's no
segmentation fault either.
This patch selects the 2nd solution to fix the issue.
[Palmer: The actual issue here is a missing clobber in the vsetvli code.
It's a little tricky: we've already probed for VLENB so we don't need to
look at the output register, we just need to have an X register in the
instruction as that's the form required to actually set VL. Thus we
clobber a register, and without describing that we end up breaking
compilers.]
Fixes: 6093faaf95
("raid6: Add RISC-V SIMD syndrome and recovery calculations")
Signed-off-by: Chunyan Zhang <zhangchunyan@iscas.ac.cn>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20250610101234.1100660-3-zhangchunyan@iscas.ac.cn
Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
This commit is contained in:
parent
19272b37aa
commit
bc75552b80
@ -26,9 +26,9 @@ static int rvv_has_vector(void)
|
||||
static void raid6_rvv1_gen_syndrome_real(int disks, unsigned long bytes, void **ptrs)
|
||||
{
|
||||
u8 **dptr = (u8 **)ptrs;
|
||||
unsigned long d;
|
||||
int z, z0;
|
||||
u8 *p, *q;
|
||||
unsigned long vl, d;
|
||||
int z, z0;
|
||||
|
||||
z0 = disks - 3; /* Highest data disk */
|
||||
p = dptr[z0 + 1]; /* XOR parity */
|
||||
@ -36,8 +36,9 @@ static void raid6_rvv1_gen_syndrome_real(int disks, unsigned long bytes, void **
|
||||
|
||||
asm volatile (".option push\n"
|
||||
".option arch,+v\n"
|
||||
"vsetvli t0, x0, e8, m1, ta, ma\n"
|
||||
"vsetvli %0, x0, e8, m1, ta, ma\n"
|
||||
".option pop\n"
|
||||
: "=&r" (vl)
|
||||
);
|
||||
|
||||
/* v0:wp0, v1:wq0, v2:wd0/w20, v3:w10 */
|
||||
@ -99,7 +100,7 @@ static void raid6_rvv1_xor_syndrome_real(int disks, int start, int stop,
|
||||
{
|
||||
u8 **dptr = (u8 **)ptrs;
|
||||
u8 *p, *q;
|
||||
unsigned long d;
|
||||
unsigned long vl, d;
|
||||
int z, z0;
|
||||
|
||||
z0 = stop; /* P/Q right side optimization */
|
||||
@ -108,8 +109,9 @@ static void raid6_rvv1_xor_syndrome_real(int disks, int start, int stop,
|
||||
|
||||
asm volatile (".option push\n"
|
||||
".option arch,+v\n"
|
||||
"vsetvli t0, x0, e8, m1, ta, ma\n"
|
||||
"vsetvli %0, x0, e8, m1, ta, ma\n"
|
||||
".option pop\n"
|
||||
: "=&r" (vl)
|
||||
);
|
||||
|
||||
/* v0:wp0, v1:wq0, v2:wd0/w20, v3:w10 */
|
||||
@ -195,9 +197,9 @@ static void raid6_rvv1_xor_syndrome_real(int disks, int start, int stop,
|
||||
static void raid6_rvv2_gen_syndrome_real(int disks, unsigned long bytes, void **ptrs)
|
||||
{
|
||||
u8 **dptr = (u8 **)ptrs;
|
||||
unsigned long d;
|
||||
int z, z0;
|
||||
u8 *p, *q;
|
||||
unsigned long vl, d;
|
||||
int z, z0;
|
||||
|
||||
z0 = disks - 3; /* Highest data disk */
|
||||
p = dptr[z0 + 1]; /* XOR parity */
|
||||
@ -205,8 +207,9 @@ static void raid6_rvv2_gen_syndrome_real(int disks, unsigned long bytes, void **
|
||||
|
||||
asm volatile (".option push\n"
|
||||
".option arch,+v\n"
|
||||
"vsetvli t0, x0, e8, m1, ta, ma\n"
|
||||
"vsetvli %0, x0, e8, m1, ta, ma\n"
|
||||
".option pop\n"
|
||||
: "=&r" (vl)
|
||||
);
|
||||
|
||||
/*
|
||||
@ -287,7 +290,7 @@ static void raid6_rvv2_xor_syndrome_real(int disks, int start, int stop,
|
||||
{
|
||||
u8 **dptr = (u8 **)ptrs;
|
||||
u8 *p, *q;
|
||||
unsigned long d;
|
||||
unsigned long vl, d;
|
||||
int z, z0;
|
||||
|
||||
z0 = stop; /* P/Q right side optimization */
|
||||
@ -296,8 +299,9 @@ static void raid6_rvv2_xor_syndrome_real(int disks, int start, int stop,
|
||||
|
||||
asm volatile (".option push\n"
|
||||
".option arch,+v\n"
|
||||
"vsetvli t0, x0, e8, m1, ta, ma\n"
|
||||
"vsetvli %0, x0, e8, m1, ta, ma\n"
|
||||
".option pop\n"
|
||||
: "=&r" (vl)
|
||||
);
|
||||
|
||||
/*
|
||||
@ -413,9 +417,9 @@ static void raid6_rvv2_xor_syndrome_real(int disks, int start, int stop,
|
||||
static void raid6_rvv4_gen_syndrome_real(int disks, unsigned long bytes, void **ptrs)
|
||||
{
|
||||
u8 **dptr = (u8 **)ptrs;
|
||||
unsigned long d;
|
||||
int z, z0;
|
||||
u8 *p, *q;
|
||||
unsigned long vl, d;
|
||||
int z, z0;
|
||||
|
||||
z0 = disks - 3; /* Highest data disk */
|
||||
p = dptr[z0 + 1]; /* XOR parity */
|
||||
@ -423,8 +427,9 @@ static void raid6_rvv4_gen_syndrome_real(int disks, unsigned long bytes, void **
|
||||
|
||||
asm volatile (".option push\n"
|
||||
".option arch,+v\n"
|
||||
"vsetvli t0, x0, e8, m1, ta, ma\n"
|
||||
"vsetvli %0, x0, e8, m1, ta, ma\n"
|
||||
".option pop\n"
|
||||
: "=&r" (vl)
|
||||
);
|
||||
|
||||
/*
|
||||
@ -539,7 +544,7 @@ static void raid6_rvv4_xor_syndrome_real(int disks, int start, int stop,
|
||||
{
|
||||
u8 **dptr = (u8 **)ptrs;
|
||||
u8 *p, *q;
|
||||
unsigned long d;
|
||||
unsigned long vl, d;
|
||||
int z, z0;
|
||||
|
||||
z0 = stop; /* P/Q right side optimization */
|
||||
@ -548,8 +553,9 @@ static void raid6_rvv4_xor_syndrome_real(int disks, int start, int stop,
|
||||
|
||||
asm volatile (".option push\n"
|
||||
".option arch,+v\n"
|
||||
"vsetvli t0, x0, e8, m1, ta, ma\n"
|
||||
"vsetvli %0, x0, e8, m1, ta, ma\n"
|
||||
".option pop\n"
|
||||
: "=&r" (vl)
|
||||
);
|
||||
|
||||
/*
|
||||
@ -721,9 +727,9 @@ static void raid6_rvv4_xor_syndrome_real(int disks, int start, int stop,
|
||||
static void raid6_rvv8_gen_syndrome_real(int disks, unsigned long bytes, void **ptrs)
|
||||
{
|
||||
u8 **dptr = (u8 **)ptrs;
|
||||
unsigned long d;
|
||||
int z, z0;
|
||||
u8 *p, *q;
|
||||
unsigned long vl, d;
|
||||
int z, z0;
|
||||
|
||||
z0 = disks - 3; /* Highest data disk */
|
||||
p = dptr[z0 + 1]; /* XOR parity */
|
||||
@ -731,8 +737,9 @@ static void raid6_rvv8_gen_syndrome_real(int disks, unsigned long bytes, void **
|
||||
|
||||
asm volatile (".option push\n"
|
||||
".option arch,+v\n"
|
||||
"vsetvli t0, x0, e8, m1, ta, ma\n"
|
||||
"vsetvli %0, x0, e8, m1, ta, ma\n"
|
||||
".option pop\n"
|
||||
: "=&r" (vl)
|
||||
);
|
||||
|
||||
/*
|
||||
@ -915,7 +922,7 @@ static void raid6_rvv8_xor_syndrome_real(int disks, int start, int stop,
|
||||
{
|
||||
u8 **dptr = (u8 **)ptrs;
|
||||
u8 *p, *q;
|
||||
unsigned long d;
|
||||
unsigned long vl, d;
|
||||
int z, z0;
|
||||
|
||||
z0 = stop; /* P/Q right side optimization */
|
||||
@ -924,8 +931,9 @@ static void raid6_rvv8_xor_syndrome_real(int disks, int start, int stop,
|
||||
|
||||
asm volatile (".option push\n"
|
||||
".option arch,+v\n"
|
||||
"vsetvli t0, x0, e8, m1, ta, ma\n"
|
||||
"vsetvli %0, x0, e8, m1, ta, ma\n"
|
||||
".option pop\n"
|
||||
: "=&r" (vl)
|
||||
);
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user