aboutsummaryrefslogtreecommitdiffstats
path: root/arch/metag
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2017-04-04 06:43:26 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-12 06:41:13 -0400
commit4f3f0dd2a75b3a25198492cd815ea82de9cef8a7 (patch)
treee2443e91c2768650e654a9b622c26c806a0a7f2e /arch/metag
parent3dc0fe517a9fb44f6c45cbb787cc4bdf5e9a3d0f (diff)
metag/usercopy: Set flags before ADDZ
commit fd40eee1290ad7add7aa665e3ce6b0f9fe9734b4 upstream. The fixup code for the copy_to_user rapf loops reads TXStatus.LSM_STEP to decide how far to rewind the source pointer. There is a special case for the last execution of an MGETL/MGETD, since it leaves LSM_STEP=0 even though the number of MGETLs/MGETDs attempted was 4. This uses ADDZ which is conditional upon the Z condition flag, but the AND instruction which masked the TXStatus.LSM_STEP field didn't set the condition flags based on the result. Fix that now by using ANDS which does set the flags, and also marking the condition codes as clobbered by the inline assembly. Fixes: 373cd784d0fc ("metag: Memory handling") Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: linux-metag@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/metag')
-rw-r--r--arch/metag/lib/usercopy.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c
index e1d553872fd7..4422928a1746 100644
--- a/arch/metag/lib/usercopy.c
+++ b/arch/metag/lib/usercopy.c
@@ -315,7 +315,7 @@
315 " .previous\n" \ 315 " .previous\n" \
316 : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ 316 : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \
317 : "0" (to), "1" (from), "2" (ret), "3" (n) \ 317 : "0" (to), "1" (from), "2" (ret), "3" (n) \
318 : "D1Ar1", "D0Ar2", "memory") 318 : "D1Ar1", "D0Ar2", "cc", "memory")
319 319
320/* rewind 'to' and 'from' pointers when a fault occurs 320/* rewind 'to' and 'from' pointers when a fault occurs
321 * 321 *
@@ -341,7 +341,7 @@
341#define __asm_copy_to_user_64bit_rapf_loop(to, from, ret, n, id)\ 341#define __asm_copy_to_user_64bit_rapf_loop(to, from, ret, n, id)\
342 __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ 342 __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \
343 "LSR D0Ar2, D0Ar2, #8\n" \ 343 "LSR D0Ar2, D0Ar2, #8\n" \
344 "AND D0Ar2, D0Ar2, #0x7\n" \ 344 "ANDS D0Ar2, D0Ar2, #0x7\n" \
345 "ADDZ D0Ar2, D0Ar2, #4\n" \ 345 "ADDZ D0Ar2, D0Ar2, #4\n" \
346 "SUB D0Ar2, D0Ar2, #1\n" \ 346 "SUB D0Ar2, D0Ar2, #1\n" \
347 "MOV D1Ar1, #4\n" \ 347 "MOV D1Ar1, #4\n" \
@@ -486,7 +486,7 @@
486 " .previous\n" \ 486 " .previous\n" \
487 : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ 487 : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \
488 : "0" (to), "1" (from), "2" (ret), "3" (n) \ 488 : "0" (to), "1" (from), "2" (ret), "3" (n) \
489 : "D1Ar1", "D0Ar2", "memory") 489 : "D1Ar1", "D0Ar2", "cc", "memory")
490 490
491/* rewind 'to' and 'from' pointers when a fault occurs 491/* rewind 'to' and 'from' pointers when a fault occurs
492 * 492 *
@@ -512,7 +512,7 @@
512#define __asm_copy_to_user_32bit_rapf_loop(to, from, ret, n, id)\ 512#define __asm_copy_to_user_32bit_rapf_loop(to, from, ret, n, id)\
513 __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ 513 __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \
514 "LSR D0Ar2, D0Ar2, #8\n" \ 514 "LSR D0Ar2, D0Ar2, #8\n" \
515 "AND D0Ar2, D0Ar2, #0x7\n" \ 515 "ANDS D0Ar2, D0Ar2, #0x7\n" \
516 "ADDZ D0Ar2, D0Ar2, #4\n" \ 516 "ADDZ D0Ar2, D0Ar2, #4\n" \
517 "SUB D0Ar2, D0Ar2, #1\n" \ 517 "SUB D0Ar2, D0Ar2, #1\n" \
518 "MOV D1Ar1, #4\n" \ 518 "MOV D1Ar1, #4\n" \