aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/asm-x86/uaccess.h84
-rw-r--r--include/asm-x86/uaccess_32.h77
-rw-r--r--include/asm-x86/uaccess_64.h51
3 files changed, 84 insertions, 128 deletions
diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h
index 8a1e45fdc980..bcda5d075921 100644
--- a/include/asm-x86/uaccess.h
+++ b/include/asm-x86/uaccess.h
@@ -178,6 +178,90 @@ extern int __get_user_bad(void);
178 __ret_gu; \ 178 __ret_gu; \
179}) 179})
180 180
181#ifdef CONFIG_X86_32
182#define __put_user_u64(x, addr, err) \
183 asm volatile("1: movl %%eax,0(%2)\n" \
184 "2: movl %%edx,4(%2)\n" \
185 "3:\n" \
186 ".section .fixup,\"ax\"\n" \
187 "4: movl %3,%0\n" \
188 " jmp 3b\n" \
189 ".previous\n" \
190 _ASM_EXTABLE(1b, 4b) \
191 _ASM_EXTABLE(2b, 4b) \
192 : "=r" (err) \
193 : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err))
194#else
195#define __put_user_u64(x, ptr, retval) \
196 __put_user_asm(x, ptr, retval, "q", "", "Zr", -EFAULT)
197#endif
198
199#ifdef CONFIG_X86_WP_WORKS_OK
200
201#define __put_user_size(x, ptr, size, retval, errret) \
202do { \
203 retval = 0; \
204 __chk_user_ptr(ptr); \
205 switch (size) { \
206 case 1: \
207 __put_user_asm(x, ptr, retval, "b", "b", "iq", errret); \
208 break; \
209 case 2: \
210 __put_user_asm(x, ptr, retval, "w", "w", "ir", errret); \
211 break; \
212 case 4: \
213 __put_user_asm(x, ptr, retval, "l", "k", "ir", errret);\
214 break; \
215 case 8: \
216 __put_user_u64((__typeof__(*ptr))(x), ptr, retval); \
217 break; \
218 default: \
219 __put_user_bad(); \
220 } \
221} while (0)
222
223#else
224
225#define __put_user_size(x, ptr, size, retval, errret) \
226do { \
227 __typeof__(*(ptr))__pus_tmp = x; \
228 retval = 0; \
229 \
230 if (unlikely(__copy_to_user_ll(ptr, &__pus_tmp, size) != 0)) \
231 retval = errret; \
232} while (0)
233
234#endif
235
236#define __put_user_nocheck(x, ptr, size) \
237({ \
238 long __pu_err; \
239 __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \
240 __pu_err; \
241})
242
243
244
245/* FIXME: this hack is definitely wrong -AK */
246struct __large_struct { unsigned long buf[100]; };
247#define __m(x) (*(struct __large_struct __user *)(x))
248
249/*
250 * Tell gcc we read from memory instead of writing: this is because
251 * we do not write to any memory gcc knows about, so there are no
252 * aliasing issues.
253 */
254#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
255 asm volatile("1: mov"itype" %"rtype"1,%2\n" \
256 "2:\n" \
257 ".section .fixup,\"ax\"\n" \
258 "3: mov %3,%0\n" \
259 " jmp 2b\n" \
260 ".previous\n" \
261 _ASM_EXTABLE(1b, 3b) \
262 : "=r"(err) \
263 : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
264
181 265
182#ifdef CONFIG_X86_32 266#ifdef CONFIG_X86_32
183# include "uaccess_32.h" 267# include "uaccess_32.h"
diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h
index 4c47a5ba65e3..fab755781b9b 100644
--- a/include/asm-x86/uaccess_32.h
+++ b/include/asm-x86/uaccess_32.h
@@ -145,83 +145,6 @@ extern void __put_user_8(void);
145#define __put_user(x, ptr) \ 145#define __put_user(x, ptr) \
146 __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) 146 __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
147 147
148#define __put_user_nocheck(x, ptr, size) \
149({ \
150 long __pu_err; \
151 __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \
152 __pu_err; \
153})
154
155
156#define __put_user_u64(x, addr, err) \
157 asm volatile("1: movl %%eax,0(%2)\n" \
158 "2: movl %%edx,4(%2)\n" \
159 "3:\n" \
160 ".section .fixup,\"ax\"\n" \
161 "4: movl %3,%0\n" \
162 " jmp 3b\n" \
163 ".previous\n" \
164 _ASM_EXTABLE(1b, 4b) \
165 _ASM_EXTABLE(2b, 4b) \
166 : "=r" (err) \
167 : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err))
168
169#ifdef CONFIG_X86_WP_WORKS_OK
170
171#define __put_user_size(x, ptr, size, retval, errret) \
172do { \
173 retval = 0; \
174 __chk_user_ptr(ptr); \
175 switch (size) { \
176 case 1: \
177 __put_user_asm(x, ptr, retval, "b", "b", "iq", errret); \
178 break; \
179 case 2: \
180 __put_user_asm(x, ptr, retval, "w", "w", "ir", errret); \
181 break; \
182 case 4: \
183 __put_user_asm(x, ptr, retval, "l", "k", "ir", errret);\
184 break; \
185 case 8: \
186 __put_user_u64((__typeof__(*ptr))(x), ptr, retval); \
187 break; \
188 default: \
189 __put_user_bad(); \
190 } \
191} while (0)
192
193#else
194
195#define __put_user_size(x, ptr, size, retval, errret) \
196do { \
197 __typeof__(*(ptr))__pus_tmp = x; \
198 retval = 0; \
199 \
200 if (unlikely(__copy_to_user_ll(ptr, &__pus_tmp, size) != 0)) \
201 retval = errret; \
202} while (0)
203
204#endif
205struct __large_struct { unsigned long buf[100]; };
206#define __m(x) (*(struct __large_struct __user *)(x))
207
208/*
209 * Tell gcc we read from memory instead of writing: this is because
210 * we do not write to any memory gcc knows about, so there are no
211 * aliasing issues.
212 */
213#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
214 asm volatile("1: mov"itype" %"rtype"1,%2\n" \
215 "2:\n" \
216 ".section .fixup,\"ax\"\n" \
217 "3: movl %3,%0\n" \
218 " jmp 2b\n" \
219 ".previous\n" \
220 _ASM_EXTABLE(1b, 3b) \
221 : "=r"(err) \
222 : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err))
223
224
225#define __get_user_nocheck(x, ptr, size) \ 148#define __get_user_nocheck(x, ptr, size) \
226({ \ 149({ \
227 long __gu_err; \ 150 long __gu_err; \
diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h
index 6532d638d5a3..42c01aa70e72 100644
--- a/include/asm-x86/uaccess_64.h
+++ b/include/asm-x86/uaccess_64.h
@@ -34,14 +34,6 @@ extern void __put_user_bad(void);
34#define __get_user_unaligned __get_user 34#define __get_user_unaligned __get_user
35#define __put_user_unaligned __put_user 35#define __put_user_unaligned __put_user
36 36
37#define __put_user_nocheck(x, ptr, size) \
38({ \
39 int __pu_err; \
40 __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \
41 __pu_err; \
42})
43
44
45#define __put_user_check(x, ptr, size) \ 37#define __put_user_check(x, ptr, size) \
46({ \ 38({ \
47 int __pu_err; \ 39 int __pu_err; \
@@ -65,49 +57,6 @@ extern void __put_user_bad(void);
65 __pu_err; \ 57 __pu_err; \
66}) 58})
67 59
68#define __put_user_size(x, ptr, size, retval, errret) \
69do { \
70 retval = 0; \
71 __chk_user_ptr(ptr); \
72 switch (size) { \
73 case 1: \
74 __put_user_asm(x, ptr, retval, "b", "b", "iq", errret);\
75 break; \
76 case 2: \
77 __put_user_asm(x, ptr, retval, "w", "w", "ir", errret);\
78 break; \
79 case 4: \
80 __put_user_asm(x, ptr, retval, "l", "k", "ir", errret);\
81 break; \
82 case 8: \
83 __put_user_asm(x, ptr, retval, "q", "", "Zr", errret); \
84 break; \
85 default: \
86 __put_user_bad(); \
87 } \
88} while (0)
89
90/* FIXME: this hack is definitely wrong -AK */
91struct __large_struct { unsigned long buf[100]; };
92#define __m(x) (*(struct __large_struct __user *)(x))
93
94/*
95 * Tell gcc we read from memory instead of writing: this is because
96 * we do not write to any memory gcc knows about, so there are no
97 * aliasing issues.
98 */
99#define __put_user_asm(x, addr, err, itype, rtype, ltype, errno) \
100 asm volatile("1: mov"itype" %"rtype"1,%2\n" \
101 "2:\n" \
102 ".section .fixup, \"ax\"\n" \
103 "3: mov %3,%0\n" \
104 " jmp 2b\n" \
105 ".previous\n" \
106 _ASM_EXTABLE(1b, 3b) \
107 : "=r"(err) \
108 : ltype (x), "m" (__m(addr)), "i" (errno), "0" (err))
109
110
111#define __get_user_nocheck(x, ptr, size) \ 60#define __get_user_nocheck(x, ptr, size) \
112({ \ 61({ \
113 int __gu_err; \ 62 int __gu_err; \