aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/lib/uaccess_std.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/lib/uaccess_std.c')
-rw-r--r--arch/s390/lib/uaccess_std.c73
1 files changed, 18 insertions, 55 deletions
diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c
index f44f0078b354..bbaca66fa293 100644
--- a/arch/s390/lib/uaccess_std.c
+++ b/arch/s390/lib/uaccess_std.c
@@ -11,7 +11,7 @@
11 11
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/mm.h> 13#include <linux/mm.h>
14#include <asm/uaccess.h> 14#include <linux/uaccess.h>
15#include <asm/futex.h> 15#include <asm/futex.h>
16 16
17#ifndef __s390x__ 17#ifndef __s390x__
@@ -28,6 +28,9 @@
28#define SLR "slgr" 28#define SLR "slgr"
29#endif 29#endif
30 30
31extern size_t copy_from_user_pt(size_t n, const void __user *from, void *to);
32extern size_t copy_to_user_pt(size_t n, void __user *to, const void *from);
33
31size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) 34size_t copy_from_user_std(size_t size, const void __user *ptr, void *x)
32{ 35{
33 unsigned long tmp1, tmp2; 36 unsigned long tmp1, tmp2;
@@ -69,34 +72,11 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x)
69 return size; 72 return size;
70} 73}
71 74
72size_t copy_from_user_std_small(size_t size, const void __user *ptr, void *x) 75size_t copy_from_user_std_check(size_t size, const void __user *ptr, void *x)
73{ 76{
74 unsigned long tmp1, tmp2; 77 if (size <= 1024)
75 78 return copy_from_user_std(size, ptr, x);
76 tmp1 = 0UL; 79 return copy_from_user_pt(size, ptr, x);
77 asm volatile(
78 "0: mvcp 0(%0,%2),0(%1),%3\n"
79 " "SLR" %0,%0\n"
80 " j 5f\n"
81 "1: la %4,255(%1)\n" /* %4 = ptr + 255 */
82 " "LHI" %3,-4096\n"
83 " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */
84 " "SLR" %4,%1\n"
85 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
86 " jnh 5f\n"
87 "2: mvcp 0(%4,%2),0(%1),%3\n"
88 " "SLR" %0,%4\n"
89 " "ALR" %2,%4\n"
90 "3:"LHI" %4,-1\n"
91 " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */
92 " bras %3,4f\n"
93 " xc 0(1,%2),0(%2)\n"
94 "4: ex %4,0(%3)\n"
95 "5:\n"
96 EX_TABLE(0b,1b) EX_TABLE(2b,3b)
97 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
98 : : "cc", "memory");
99 return size;
100} 80}
101 81
102size_t copy_to_user_std(size_t size, void __user *ptr, const void *x) 82size_t copy_to_user_std(size_t size, void __user *ptr, const void *x)
@@ -130,28 +110,11 @@ size_t copy_to_user_std(size_t size, void __user *ptr, const void *x)
130 return size; 110 return size;
131} 111}
132 112
133size_t copy_to_user_std_small(size_t size, void __user *ptr, const void *x) 113size_t copy_to_user_std_check(size_t size, void __user *ptr, const void *x)
134{ 114{
135 unsigned long tmp1, tmp2; 115 if (size <= 1024)
136 116 return copy_to_user_std(size, ptr, x);
137 tmp1 = 0UL; 117 return copy_to_user_pt(size, ptr, x);
138 asm volatile(
139 "0: mvcs 0(%0,%1),0(%2),%3\n"
140 " "SLR" %0,%0\n"
141 " j 3f\n"
142 "1: la %4,255(%1)\n" /* ptr + 255 */
143 " "LHI" %3,-4096\n"
144 " nr %4,%3\n" /* (ptr + 255) & -4096UL */
145 " "SLR" %4,%1\n"
146 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
147 " jnh 3f\n"
148 "2: mvcs 0(%4,%1),0(%2),%3\n"
149 " "SLR" %0,%4\n"
150 "3:\n"
151 EX_TABLE(0b,1b) EX_TABLE(2b,3b)
152 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
153 : : "cc", "memory");
154 return size;
155} 118}
156 119
157size_t copy_in_user_std(size_t size, void __user *to, const void __user *from) 120size_t copy_in_user_std(size_t size, void __user *to, const void __user *from)
@@ -295,7 +258,7 @@ int futex_atomic_op(int op, int __user *uaddr, int oparg, int *old)
295{ 258{
296 int oldval = 0, newval, ret; 259 int oldval = 0, newval, ret;
297 260
298 inc_preempt_count(); 261 pagefault_disable();
299 262
300 switch (op) { 263 switch (op) {
301 case FUTEX_OP_SET: 264 case FUTEX_OP_SET:
@@ -321,7 +284,7 @@ int futex_atomic_op(int op, int __user *uaddr, int oparg, int *old)
321 default: 284 default:
322 ret = -ENOSYS; 285 ret = -ENOSYS;
323 } 286 }
324 dec_preempt_count(); 287 pagefault_enable();
325 *old = oldval; 288 *old = oldval;
326 return ret; 289 return ret;
327} 290}
@@ -343,10 +306,10 @@ int futex_atomic_cmpxchg(int __user *uaddr, int oldval, int newval)
343} 306}
344 307
345struct uaccess_ops uaccess_std = { 308struct uaccess_ops uaccess_std = {
346 .copy_from_user = copy_from_user_std, 309 .copy_from_user = copy_from_user_std_check,
347 .copy_from_user_small = copy_from_user_std_small, 310 .copy_from_user_small = copy_from_user_std,
348 .copy_to_user = copy_to_user_std, 311 .copy_to_user = copy_to_user_std_check,
349 .copy_to_user_small = copy_to_user_std_small, 312 .copy_to_user_small = copy_to_user_std,
350 .copy_in_user = copy_in_user_std, 313 .copy_in_user = copy_in_user_std,
351 .clear_user = clear_user_std, 314 .clear_user = clear_user_std,
352 .strnlen_user = strnlen_user_std, 315 .strnlen_user = strnlen_user_std,