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