summaryrefslogtreecommitdiffstats
path: root/arch/s390/lib/uaccess_mvcos.c
diff options
context:
space:
mode:
authorGerald Schaefer <geraldsc@de.ibm.com>2006-12-04 15:40:45 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-12-04 15:40:45 +0100
commit59f35d53fde3987d071ea1c9bf1c9ba29fcb69fe (patch)
tree50853c1bf3ad3af080707fb2e6b3722d3d86db9e /arch/s390/lib/uaccess_mvcos.c
parentd57de5a36791cb1b7285649c62f183b0d3505f7d (diff)
[S390] Add dynamic size check for usercopy functions.
Use a wrapper for copy_to/from_user to chose the best usercopy method. The mvcos instruction is better for sizes greater than 256 bytes, if mvcos is not available a page table walk is better for sizes greater than 1024 bytes. Also removed the redundant copy_to/from_user_std_small functions. Signed-off-by: Gerald Schaefer <geraldsc@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/lib/uaccess_mvcos.c')
-rw-r--r--arch/s390/lib/uaccess_mvcos.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c
index 121b2935a42..f9a23d57eb7 100644
--- a/arch/s390/lib/uaccess_mvcos.c
+++ b/arch/s390/lib/uaccess_mvcos.c
@@ -27,6 +27,9 @@
#define SLR "slgr"
#endif
+extern size_t copy_from_user_std(size_t, const void __user *, void *);
+extern size_t copy_to_user_std(size_t, void __user *, const void *);
+
size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
{
register unsigned long reg0 asm("0") = 0x81UL;
@@ -66,6 +69,13 @@ size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
return size;
}
+size_t copy_from_user_mvcos_check(size_t size, const void __user *ptr, void *x)
+{
+ if (size <= 256)
+ return copy_from_user_std(size, ptr, x);
+ return copy_from_user_mvcos(size, ptr, x);
+}
+
size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x)
{
register unsigned long reg0 asm("0") = 0x810000UL;
@@ -95,6 +105,13 @@ size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x)
return size;
}
+size_t copy_to_user_mvcos_check(size_t size, void __user *ptr, const void *x)
+{
+ if (size <= 256)
+ return copy_to_user_std(size, ptr, x);
+ return copy_to_user_mvcos(size, ptr, x);
+}
+
size_t copy_in_user_mvcos(size_t size, void __user *to, const void __user *from)
{
register unsigned long reg0 asm("0") = 0x810081UL;
@@ -145,18 +162,16 @@ size_t clear_user_mvcos(size_t size, void __user *to)
return size;
}
-extern size_t copy_from_user_std_small(size_t, const void __user *, void *);
-extern size_t copy_to_user_std_small(size_t, void __user *, const void *);
extern size_t strnlen_user_std(size_t, const char __user *);
extern size_t strncpy_from_user_std(size_t, const char __user *, char *);
extern int futex_atomic_op(int, int __user *, int, int *);
extern int futex_atomic_cmpxchg(int __user *, int, int);
struct uaccess_ops uaccess_mvcos = {
- .copy_from_user = copy_from_user_mvcos,
- .copy_from_user_small = copy_from_user_std_small,
- .copy_to_user = copy_to_user_mvcos,
- .copy_to_user_small = copy_to_user_std_small,
+ .copy_from_user = copy_from_user_mvcos_check,
+ .copy_from_user_small = copy_from_user_std,
+ .copy_to_user = copy_to_user_mvcos_check,
+ .copy_to_user_small = copy_to_user_std,
.copy_in_user = copy_in_user_mvcos,
.clear_user = clear_user_mvcos,
.strnlen_user = strnlen_user_std,