Skip to content

Commit bc75552

Browse files
Chunyan Zhangpalmer-dabbelt
authored andcommitted
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: 6093faa ("raid6: Add RISC-V SIMD syndrome and recovery calculations") Signed-off-by: Chunyan Zhang <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 19272b3 commit bc75552

File tree

1 file changed

+28
-20
lines changed

1 file changed

+28
-20
lines changed

lib/raid6/rvv.c

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,19 @@ static int rvv_has_vector(void)
2626
static void raid6_rvv1_gen_syndrome_real(int disks, unsigned long bytes, void **ptrs)
2727
{
2828
u8 **dptr = (u8 **)ptrs;
29-
unsigned long d;
30-
int z, z0;
3129
u8 *p, *q;
30+
unsigned long vl, d;
31+
int z, z0;
3232

3333
z0 = disks - 3; /* Highest data disk */
3434
p = dptr[z0 + 1]; /* XOR parity */
3535
q = dptr[z0 + 2]; /* RS syndrome */
3636

3737
asm volatile (".option push\n"
3838
".option arch,+v\n"
39-
"vsetvli t0, x0, e8, m1, ta, ma\n"
39+
"vsetvli %0, x0, e8, m1, ta, ma\n"
4040
".option pop\n"
41+
: "=&r" (vl)
4142
);
4243

4344
/* 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,
99100
{
100101
u8 **dptr = (u8 **)ptrs;
101102
u8 *p, *q;
102-
unsigned long d;
103+
unsigned long vl, d;
103104
int z, z0;
104105

105106
z0 = stop; /* P/Q right side optimization */
@@ -108,8 +109,9 @@ static void raid6_rvv1_xor_syndrome_real(int disks, int start, int stop,
108109

109110
asm volatile (".option push\n"
110111
".option arch,+v\n"
111-
"vsetvli t0, x0, e8, m1, ta, ma\n"
112+
"vsetvli %0, x0, e8, m1, ta, ma\n"
112113
".option pop\n"
114+
: "=&r" (vl)
113115
);
114116

115117
/* v0:wp0, v1:wq0, v2:wd0/w20, v3:w10 */
@@ -195,18 +197,19 @@ static void raid6_rvv1_xor_syndrome_real(int disks, int start, int stop,
195197
static void raid6_rvv2_gen_syndrome_real(int disks, unsigned long bytes, void **ptrs)
196198
{
197199
u8 **dptr = (u8 **)ptrs;
198-
unsigned long d;
199-
int z, z0;
200200
u8 *p, *q;
201+
unsigned long vl, d;
202+
int z, z0;
201203

202204
z0 = disks - 3; /* Highest data disk */
203205
p = dptr[z0 + 1]; /* XOR parity */
204206
q = dptr[z0 + 2]; /* RS syndrome */
205207

206208
asm volatile (".option push\n"
207209
".option arch,+v\n"
208-
"vsetvli t0, x0, e8, m1, ta, ma\n"
210+
"vsetvli %0, x0, e8, m1, ta, ma\n"
209211
".option pop\n"
212+
: "=&r" (vl)
210213
);
211214

212215
/*
@@ -287,7 +290,7 @@ static void raid6_rvv2_xor_syndrome_real(int disks, int start, int stop,
287290
{
288291
u8 **dptr = (u8 **)ptrs;
289292
u8 *p, *q;
290-
unsigned long d;
293+
unsigned long vl, d;
291294
int z, z0;
292295

293296
z0 = stop; /* P/Q right side optimization */
@@ -296,8 +299,9 @@ static void raid6_rvv2_xor_syndrome_real(int disks, int start, int stop,
296299

297300
asm volatile (".option push\n"
298301
".option arch,+v\n"
299-
"vsetvli t0, x0, e8, m1, ta, ma\n"
302+
"vsetvli %0, x0, e8, m1, ta, ma\n"
300303
".option pop\n"
304+
: "=&r" (vl)
301305
);
302306

303307
/*
@@ -413,18 +417,19 @@ static void raid6_rvv2_xor_syndrome_real(int disks, int start, int stop,
413417
static void raid6_rvv4_gen_syndrome_real(int disks, unsigned long bytes, void **ptrs)
414418
{
415419
u8 **dptr = (u8 **)ptrs;
416-
unsigned long d;
417-
int z, z0;
418420
u8 *p, *q;
421+
unsigned long vl, d;
422+
int z, z0;
419423

420424
z0 = disks - 3; /* Highest data disk */
421425
p = dptr[z0 + 1]; /* XOR parity */
422426
q = dptr[z0 + 2]; /* RS syndrome */
423427

424428
asm volatile (".option push\n"
425429
".option arch,+v\n"
426-
"vsetvli t0, x0, e8, m1, ta, ma\n"
430+
"vsetvli %0, x0, e8, m1, ta, ma\n"
427431
".option pop\n"
432+
: "=&r" (vl)
428433
);
429434

430435
/*
@@ -539,7 +544,7 @@ static void raid6_rvv4_xor_syndrome_real(int disks, int start, int stop,
539544
{
540545
u8 **dptr = (u8 **)ptrs;
541546
u8 *p, *q;
542-
unsigned long d;
547+
unsigned long vl, d;
543548
int z, z0;
544549

545550
z0 = stop; /* P/Q right side optimization */
@@ -548,8 +553,9 @@ static void raid6_rvv4_xor_syndrome_real(int disks, int start, int stop,
548553

549554
asm volatile (".option push\n"
550555
".option arch,+v\n"
551-
"vsetvli t0, x0, e8, m1, ta, ma\n"
556+
"vsetvli %0, x0, e8, m1, ta, ma\n"
552557
".option pop\n"
558+
: "=&r" (vl)
553559
);
554560

555561
/*
@@ -721,18 +727,19 @@ static void raid6_rvv4_xor_syndrome_real(int disks, int start, int stop,
721727
static void raid6_rvv8_gen_syndrome_real(int disks, unsigned long bytes, void **ptrs)
722728
{
723729
u8 **dptr = (u8 **)ptrs;
724-
unsigned long d;
725-
int z, z0;
726730
u8 *p, *q;
731+
unsigned long vl, d;
732+
int z, z0;
727733

728734
z0 = disks - 3; /* Highest data disk */
729735
p = dptr[z0 + 1]; /* XOR parity */
730736
q = dptr[z0 + 2]; /* RS syndrome */
731737

732738
asm volatile (".option push\n"
733739
".option arch,+v\n"
734-
"vsetvli t0, x0, e8, m1, ta, ma\n"
740+
"vsetvli %0, x0, e8, m1, ta, ma\n"
735741
".option pop\n"
742+
: "=&r" (vl)
736743
);
737744

738745
/*
@@ -915,7 +922,7 @@ static void raid6_rvv8_xor_syndrome_real(int disks, int start, int stop,
915922
{
916923
u8 **dptr = (u8 **)ptrs;
917924
u8 *p, *q;
918-
unsigned long d;
925+
unsigned long vl, d;
919926
int z, z0;
920927

921928
z0 = stop; /* P/Q right side optimization */
@@ -924,8 +931,9 @@ static void raid6_rvv8_xor_syndrome_real(int disks, int start, int stop,
924931

925932
asm volatile (".option push\n"
926933
".option arch,+v\n"
927-
"vsetvli t0, x0, e8, m1, ta, ma\n"
934+
"vsetvli %0, x0, e8, m1, ta, ma\n"
928935
".option pop\n"
936+
: "=&r" (vl)
929937
);
930938

931939
/*

0 commit comments

Comments
 (0)