diff options
Diffstat (limited to 'arch/s390/lib/uaccess_mvcos.c')
-rw-r--r-- | arch/s390/lib/uaccess_mvcos.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c index 86c96d6c191a..121b2935a422 100644 --- a/arch/s390/lib/uaccess_mvcos.c +++ b/arch/s390/lib/uaccess_mvcos.c | |||
@@ -35,7 +35,7 @@ size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) | |||
35 | tmp1 = -4096UL; | 35 | tmp1 = -4096UL; |
36 | asm volatile( | 36 | asm volatile( |
37 | "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n" | 37 | "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n" |
38 | " jz 4f\n" | 38 | " jz 7f\n" |
39 | "1:"ALR" %0,%3\n" | 39 | "1:"ALR" %0,%3\n" |
40 | " "SLR" %1,%3\n" | 40 | " "SLR" %1,%3\n" |
41 | " "SLR" %2,%3\n" | 41 | " "SLR" %2,%3\n" |
@@ -44,13 +44,23 @@ size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) | |||
44 | " nr %4,%3\n" /* %4 = (ptr + 4095) & -4096 */ | 44 | " nr %4,%3\n" /* %4 = (ptr + 4095) & -4096 */ |
45 | " "SLR" %4,%1\n" | 45 | " "SLR" %4,%1\n" |
46 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ | 46 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
47 | " jnh 5f\n" | 47 | " jnh 4f\n" |
48 | "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n" | 48 | "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n" |
49 | " "SLR" %0,%4\n" | 49 | " "SLR" %0,%4\n" |
50 | " j 5f\n" | 50 | " "ALR" %2,%4\n" |
51 | "4:"SLR" %0,%0\n" | 51 | "4:"LHI" %4,-1\n" |
52 | "5: \n" | 52 | " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ |
53 | EX_TABLE(0b,2b) EX_TABLE(3b,5b) | 53 | " bras %3,6f\n" /* memset loop */ |
54 | " xc 0(1,%2),0(%2)\n" | ||
55 | "5: xc 0(256,%2),0(%2)\n" | ||
56 | " la %2,256(%2)\n" | ||
57 | "6:"AHI" %4,-256\n" | ||
58 | " jnm 5b\n" | ||
59 | " ex %4,0(%3)\n" | ||
60 | " j 8f\n" | ||
61 | "7:"SLR" %0,%0\n" | ||
62 | "8: \n" | ||
63 | EX_TABLE(0b,2b) EX_TABLE(3b,4b) | ||
54 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) | 64 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
55 | : "d" (reg0) : "cc", "memory"); | 65 | : "d" (reg0) : "cc", "memory"); |
56 | return size; | 66 | return size; |