diff options
author | John David Anglin <dave.anglin@bell.net> | 2017-09-30 17:24:23 -0400 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2017-10-19 02:48:44 -0400 |
commit | 374b3bf8e8b519f61eb9775888074c6e46b3bf0c (patch) | |
tree | f3bf23769e2de1a8e6c8e3b9486a7221e6fc56cf | |
parent | 73d3393ada4f70fa3df5639c8d438f2f034c0ecb (diff) |
parisc: Fix double-word compare and exchange in LWS code on 32-bit kernels
As discussed on the debian-hppa list, double-wordcompare and exchange
operations fail on 32-bit kernels. Looking at the code, I realized that
the ",ma" completer does the wrong thing in the "ldw,ma 4(%r26), %r29"
instruction. This increments %r26 and causes the following store to
write to the wrong location.
Note by Helge Deller:
The patch applies cleanly to stable kernel series if this upstream
commit is merged in advance:
f4125cfdb300 ("parisc: Avoid trashing sr2 and sr3 in LWS code").
Signed-off-by: John David Anglin <dave.anglin@bell.net>
Tested-by: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
Fixes: 89206491201c ("parisc: Implement new LWS CAS supporting 64 bit operations.")
Cc: stable@vger.kernel.org # 3.13+
Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r-- | arch/parisc/kernel/syscall.S | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 23de307c3052..41e60a9c7db2 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S | |||
@@ -742,7 +742,7 @@ lws_compare_and_swap_2: | |||
742 | 10: ldd 0(%r25), %r25 | 742 | 10: ldd 0(%r25), %r25 |
743 | 11: ldd 0(%r24), %r24 | 743 | 11: ldd 0(%r24), %r24 |
744 | #else | 744 | #else |
745 | /* Load new value into r22/r23 - high/low */ | 745 | /* Load old value into r22/r23 - high/low */ |
746 | 10: ldw 0(%r25), %r22 | 746 | 10: ldw 0(%r25), %r22 |
747 | 11: ldw 4(%r25), %r23 | 747 | 11: ldw 4(%r25), %r23 |
748 | /* Load new value into fr4 for atomic store later */ | 748 | /* Load new value into fr4 for atomic store later */ |
@@ -834,11 +834,11 @@ cas2_action: | |||
834 | copy %r0, %r28 | 834 | copy %r0, %r28 |
835 | #else | 835 | #else |
836 | /* Compare first word */ | 836 | /* Compare first word */ |
837 | 19: ldw,ma 0(%r26), %r29 | 837 | 19: ldw 0(%r26), %r29 |
838 | sub,= %r29, %r22, %r0 | 838 | sub,= %r29, %r22, %r0 |
839 | b,n cas2_end | 839 | b,n cas2_end |
840 | /* Compare second word */ | 840 | /* Compare second word */ |
841 | 20: ldw,ma 4(%r26), %r29 | 841 | 20: ldw 4(%r26), %r29 |
842 | sub,= %r29, %r23, %r0 | 842 | sub,= %r29, %r23, %r0 |
843 | b,n cas2_end | 843 | b,n cas2_end |
844 | /* Perform the store */ | 844 | /* Perform the store */ |