]>
Commit | Line | Data |
---|---|---|
f71f4658 GKH |
1 | From 05f016d2ca7a4fab99d5d5472168506ddf95e74f Mon Sep 17 00:00:00 2001 |
2 | From: John David Anglin <dave.anglin@bell.net> | |
3 | Date: Sat, 11 Nov 2017 17:11:16 -0500 | |
4 | Subject: parisc: Fix validity check of pointer size argument in new CAS implementation | |
5 | ||
6 | From: John David Anglin <dave.anglin@bell.net> | |
7 | ||
8 | commit 05f016d2ca7a4fab99d5d5472168506ddf95e74f upstream. | |
9 | ||
10 | As noted by Christoph Biedl, passing a pointer size of 4 in the new CAS | |
11 | implementation causes a kernel crash. The attached patch corrects the | |
12 | off by one error in the argument validity check. | |
13 | ||
14 | In reviewing the code, I noticed that we only perform word operations | |
15 | with the pointer size argument. The subi instruction intentionally uses | |
16 | a word condition on 64-bit kernels. Nullification was used instead of a | |
17 | cmpib instruction as the branch should never be taken. The shlw | |
18 | pseudo-operation generates a depw,z instruction and it clears the target | |
19 | before doing a shift left word deposit. Thus, we don't need to clip the | |
20 | upper 32 bits of this argument on 64-bit kernels. | |
21 | ||
22 | Tested with a gcc testsuite run with a 64-bit kernel. The gcc atomic | |
23 | code in libgcc is the only direct user of the new CAS implementation | |
24 | that I am aware of. | |
25 | ||
26 | Signed-off-by: John David Anglin <dave.anglin@bell.net> | |
27 | Signed-off-by: Helge Deller <deller@gmx.de> | |
28 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
29 | ||
30 | --- | |
31 | arch/parisc/kernel/syscall.S | 6 +++--- | |
32 | 1 file changed, 3 insertions(+), 3 deletions(-) | |
33 | ||
34 | --- a/arch/parisc/kernel/syscall.S | |
35 | +++ b/arch/parisc/kernel/syscall.S | |
36 | @@ -688,15 +688,15 @@ cas_action: | |
37 | /* ELF32 Process entry path */ | |
38 | lws_compare_and_swap_2: | |
39 | #ifdef CONFIG_64BIT | |
40 | - /* Clip the input registers */ | |
41 | + /* Clip the input registers. We don't need to clip %r23 as we | |
42 | + only use it for word operations */ | |
43 | depdi 0, 31, 32, %r26 | |
44 | depdi 0, 31, 32, %r25 | |
45 | depdi 0, 31, 32, %r24 | |
46 | - depdi 0, 31, 32, %r23 | |
47 | #endif | |
48 | ||
49 | /* Check the validity of the size pointer */ | |
50 | - subi,>>= 4, %r23, %r0 | |
51 | + subi,>>= 3, %r23, %r0 | |
52 | b,n lws_exit_nosys | |
53 | ||
54 | /* Jump to the functions which will load the old and new values into |