diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2014-04-17 08:16:03 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-05-20 02:58:50 -0400 |
commit | c9ca78415ac1cbb0e9846111d5f01376266cf6f3 (patch) | |
tree | e664bb4d8bdabcc0dd65732b6741d21260760dba | |
parent | ac4995b9d5705f10a69ea74d440e3943db41f2ca (diff) |
s390/uaccess: provide inline variants of get_user/put_user
This shortens the code by ~17k (performace_defconfig, march=z196).
The number of exception table entries however increases from 164
entries to 2500 entries (+~18k).
However the executed code is shorter and also faster since we save
the branches to the out-of-line copy_to/from_user implementations.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/include/asm/uaccess.h | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 1be64a1506d0..cd4c68e0398d 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h | |||
@@ -132,6 +132,34 @@ unsigned long __must_check __copy_to_user(void __user *to, const void *from, | |||
132 | #define __copy_to_user_inatomic __copy_to_user | 132 | #define __copy_to_user_inatomic __copy_to_user |
133 | #define __copy_from_user_inatomic __copy_from_user | 133 | #define __copy_from_user_inatomic __copy_from_user |
134 | 134 | ||
135 | #ifdef CONFIG_HAVE_MARCH_Z10_FEATURES | ||
136 | |||
137 | #define __put_get_user_asm(to, from, size, spec) \ | ||
138 | ({ \ | ||
139 | register unsigned long __reg0 asm("0") = spec; \ | ||
140 | int __rc; \ | ||
141 | \ | ||
142 | asm volatile( \ | ||
143 | "0: mvcos %1,%3,%2\n" \ | ||
144 | "1: xr %0,%0\n" \ | ||
145 | "2:\n" \ | ||
146 | ".pushsection .fixup, \"ax\"\n" \ | ||
147 | "3: lhi %0,%5\n" \ | ||
148 | " jg 2b\n" \ | ||
149 | ".popsection\n" \ | ||
150 | EX_TABLE(0b,3b) EX_TABLE(1b,3b) \ | ||
151 | : "=d" (__rc), "=Q" (*(to)) \ | ||
152 | : "d" (size), "Q" (*(from)), \ | ||
153 | "d" (__reg0), "K" (-EFAULT) \ | ||
154 | : "cc"); \ | ||
155 | __rc; \ | ||
156 | }) | ||
157 | |||
158 | #define __put_user_fn(x, ptr, size) __put_get_user_asm(ptr, x, size, 0x810000UL) | ||
159 | #define __get_user_fn(x, ptr, size) __put_get_user_asm(x, ptr, size, 0x81UL) | ||
160 | |||
161 | #else /* CONFIG_HAVE_MARCH_Z10_FEATURES */ | ||
162 | |||
135 | static inline int __put_user_fn(void *x, void __user *ptr, unsigned long size) | 163 | static inline int __put_user_fn(void *x, void __user *ptr, unsigned long size) |
136 | { | 164 | { |
137 | size = __copy_to_user(ptr, x, size); | 165 | size = __copy_to_user(ptr, x, size); |
@@ -144,6 +172,8 @@ static inline int __get_user_fn(void *x, const void __user *ptr, unsigned long s | |||
144 | return size ? -EFAULT : 0; | 172 | return size ? -EFAULT : 0; |
145 | } | 173 | } |
146 | 174 | ||
175 | #endif /* CONFIG_HAVE_MARCH_Z10_FEATURES */ | ||
176 | |||
147 | /* | 177 | /* |
148 | * These are the main single-value transfer routines. They automatically | 178 | * These are the main single-value transfer routines. They automatically |
149 | * use the right size if we just have the right pointer type. | 179 | * use the right size if we just have the right pointer type. |