diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-18 13:02:24 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-18 13:02:24 -0500 |
| commit | eaa0eda56223815cd9dc1225f715ff673ae77198 (patch) | |
| tree | 12ed5208dda2ecbf2a652d6c54f83c58f362707d /arch/sparc/include/asm | |
| parent | cad3ab5883b35b044200820bf2e1fbabe742740a (diff) | |
| parent | 643165c8bbc8617d8222cb50c89e34fe64d226cf (diff) | |
Merge tag 'asm-generic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic
Pull asm-generic uaccess.h cleanup from Arnd Bergmann:
"Like in 3.19, I once more have a multi-stage cleanup for one
asm-generic header file, this time the work was done by Michael
Tsirkin and cleans up the uaccess.h file in asm-generic, as well as
all architectures for which the respective maintainers did not pick up
his patches directly"
* tag 'asm-generic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic: (37 commits)
sparc32: nocheck uaccess coding style tweaks
sparc64: nocheck uaccess coding style tweaks
xtensa: macro whitespace fixes
sh: macro whitespace fixes
parisc: macro whitespace fixes
m68k: macro whitespace fixes
m32r: macro whitespace fixes
frv: macro whitespace fixes
cris: macro whitespace fixes
avr32: macro whitespace fixes
arm64: macro whitespace fixes
arm: macro whitespace fixes
alpha: macro whitespace fixes
blackfin: macro whitespace fixes
sparc64: uaccess_64 macro whitespace fixes
sparc32: uaccess_32 macro whitespace fixes
avr32: whitespace fix
sh: fix put_user sparse errors
metag: fix put_user sparse errors
ia64: fix put_user sparse errors
...
Diffstat (limited to 'arch/sparc/include/asm')
| -rw-r--r-- | arch/sparc/include/asm/uaccess_32.h | 339 | ||||
| -rw-r--r-- | arch/sparc/include/asm/uaccess_64.h | 222 |
2 files changed, 319 insertions, 242 deletions
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h index 9634d086fc56..64ee103dc29d 100644 --- a/arch/sparc/include/asm/uaccess_32.h +++ b/arch/sparc/include/asm/uaccess_32.h | |||
| @@ -37,7 +37,7 @@ | |||
| 37 | #define get_fs() (current->thread.current_ds) | 37 | #define get_fs() (current->thread.current_ds) |
| 38 | #define set_fs(val) ((current->thread.current_ds) = (val)) | 38 | #define set_fs(val) ((current->thread.current_ds) = (val)) |
| 39 | 39 | ||
| 40 | #define segment_eq(a,b) ((a).seg == (b).seg) | 40 | #define segment_eq(a, b) ((a).seg == (b).seg) |
| 41 | 41 | ||
| 42 | /* We have there a nice not-mapped page at PAGE_OFFSET - PAGE_SIZE, so that this test | 42 | /* We have there a nice not-mapped page at PAGE_OFFSET - PAGE_SIZE, so that this test |
| 43 | * can be fairly lightweight. | 43 | * can be fairly lightweight. |
| @@ -46,8 +46,8 @@ | |||
| 46 | */ | 46 | */ |
| 47 | #define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; }) | 47 | #define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; }) |
| 48 | #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) | 48 | #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) |
| 49 | #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size))) | 49 | #define __access_ok(addr, size) (__user_ok((addr) & get_fs().seg, (size))) |
| 50 | #define access_ok(type, addr, size) \ | 50 | #define access_ok(type, addr, size) \ |
| 51 | ({ (void)(type); __access_ok((unsigned long)(addr), size); }) | 51 | ({ (void)(type); __access_ok((unsigned long)(addr), size); }) |
| 52 | 52 | ||
| 53 | /* | 53 | /* |
| @@ -91,158 +91,221 @@ void __ret_efault(void); | |||
| 91 | * of a performance impact. Thus we have a few rather ugly macros here, | 91 | * of a performance impact. Thus we have a few rather ugly macros here, |
| 92 | * and hide all the ugliness from the user. | 92 | * and hide all the ugliness from the user. |
| 93 | */ | 93 | */ |
| 94 | #define put_user(x,ptr) ({ \ | 94 | #define put_user(x, ptr) ({ \ |
| 95 | unsigned long __pu_addr = (unsigned long)(ptr); \ | 95 | unsigned long __pu_addr = (unsigned long)(ptr); \ |
| 96 | __chk_user_ptr(ptr); \ | 96 | __chk_user_ptr(ptr); \ |
| 97 | __put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); }) | 97 | __put_user_check((__typeof__(*(ptr)))(x), __pu_addr, sizeof(*(ptr))); \ |
| 98 | 98 | }) | |
| 99 | #define get_user(x,ptr) ({ \ | 99 | |
| 100 | unsigned long __gu_addr = (unsigned long)(ptr); \ | 100 | #define get_user(x, ptr) ({ \ |
| 101 | __chk_user_ptr(ptr); \ | 101 | unsigned long __gu_addr = (unsigned long)(ptr); \ |
| 102 | __get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); }) | 102 | __chk_user_ptr(ptr); \ |
| 103 | __get_user_check((x), __gu_addr, sizeof(*(ptr)), __typeof__(*(ptr))); \ | ||
| 104 | }) | ||
| 103 | 105 | ||
| 104 | /* | 106 | /* |
| 105 | * The "__xxx" versions do not do address space checking, useful when | 107 | * The "__xxx" versions do not do address space checking, useful when |
| 106 | * doing multiple accesses to the same area (the user has to do the | 108 | * doing multiple accesses to the same area (the user has to do the |
| 107 | * checks by hand with "access_ok()") | 109 | * checks by hand with "access_ok()") |
| 108 | */ | 110 | */ |
| 109 | #define __put_user(x,ptr) __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) | 111 | #define __put_user(x, ptr) \ |
| 110 | #define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr))) | 112 | __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) |
| 113 | #define __get_user(x, ptr) \ | ||
| 114 | __get_user_nocheck((x), (ptr), sizeof(*(ptr)), __typeof__(*(ptr))) | ||
| 111 | 115 | ||
| 112 | struct __large_struct { unsigned long buf[100]; }; | 116 | struct __large_struct { unsigned long buf[100]; }; |
| 113 | #define __m(x) ((struct __large_struct __user *)(x)) | 117 | #define __m(x) ((struct __large_struct __user *)(x)) |
| 114 | 118 | ||
| 115 | #define __put_user_check(x,addr,size) ({ \ | 119 | #define __put_user_check(x, addr, size) ({ \ |
| 116 | register int __pu_ret; \ | 120 | register int __pu_ret; \ |
| 117 | if (__access_ok(addr,size)) { \ | 121 | if (__access_ok(addr, size)) { \ |
| 118 | switch (size) { \ | 122 | switch (size) { \ |
| 119 | case 1: __put_user_asm(x,b,addr,__pu_ret); break; \ | 123 | case 1: \ |
| 120 | case 2: __put_user_asm(x,h,addr,__pu_ret); break; \ | 124 | __put_user_asm(x, b, addr, __pu_ret); \ |
| 121 | case 4: __put_user_asm(x,,addr,__pu_ret); break; \ | 125 | break; \ |
| 122 | case 8: __put_user_asm(x,d,addr,__pu_ret); break; \ | 126 | case 2: \ |
| 123 | default: __pu_ret = __put_user_bad(); break; \ | 127 | __put_user_asm(x, h, addr, __pu_ret); \ |
| 124 | } } else { __pu_ret = -EFAULT; } __pu_ret; }) | 128 | break; \ |
| 125 | 129 | case 4: \ | |
| 126 | #define __put_user_nocheck(x,addr,size) ({ \ | 130 | __put_user_asm(x, , addr, __pu_ret); \ |
| 127 | register int __pu_ret; \ | 131 | break; \ |
| 128 | switch (size) { \ | 132 | case 8: \ |
| 129 | case 1: __put_user_asm(x,b,addr,__pu_ret); break; \ | 133 | __put_user_asm(x, d, addr, __pu_ret); \ |
| 130 | case 2: __put_user_asm(x,h,addr,__pu_ret); break; \ | 134 | break; \ |
| 131 | case 4: __put_user_asm(x,,addr,__pu_ret); break; \ | 135 | default: \ |
| 132 | case 8: __put_user_asm(x,d,addr,__pu_ret); break; \ | 136 | __pu_ret = __put_user_bad(); \ |
| 133 | default: __pu_ret = __put_user_bad(); break; \ | 137 | break; \ |
| 134 | } __pu_ret; }) | 138 | } \ |
| 135 | 139 | } else { \ | |
| 136 | #define __put_user_asm(x,size,addr,ret) \ | 140 | __pu_ret = -EFAULT; \ |
| 141 | } \ | ||
| 142 | __pu_ret; \ | ||
| 143 | }) | ||
| 144 | |||
| 145 | #define __put_user_nocheck(x, addr, size) ({ \ | ||
| 146 | register int __pu_ret; \ | ||
| 147 | switch (size) { \ | ||
| 148 | case 1: __put_user_asm(x, b, addr, __pu_ret); break; \ | ||
| 149 | case 2: __put_user_asm(x, h, addr, __pu_ret); break; \ | ||
| 150 | case 4: __put_user_asm(x, , addr, __pu_ret); break; \ | ||
| 151 | case 8: __put_user_asm(x, d, addr, __pu_ret); break; \ | ||
| 152 | default: __pu_ret = __put_user_bad(); break; \ | ||
| 153 | } \ | ||
| 154 | __pu_ret; \ | ||
| 155 | }) | ||
| 156 | |||
| 157 | #define __put_user_asm(x, size, addr, ret) \ | ||
| 137 | __asm__ __volatile__( \ | 158 | __asm__ __volatile__( \ |
| 138 | "/* Put user asm, inline. */\n" \ | 159 | "/* Put user asm, inline. */\n" \ |
| 139 | "1:\t" "st"#size " %1, %2\n\t" \ | 160 | "1:\t" "st"#size " %1, %2\n\t" \ |
| 140 | "clr %0\n" \ | 161 | "clr %0\n" \ |
| 141 | "2:\n\n\t" \ | 162 | "2:\n\n\t" \ |
| 142 | ".section .fixup,#alloc,#execinstr\n\t" \ | 163 | ".section .fixup,#alloc,#execinstr\n\t" \ |
| 143 | ".align 4\n" \ | 164 | ".align 4\n" \ |
| 144 | "3:\n\t" \ | 165 | "3:\n\t" \ |
| 145 | "b 2b\n\t" \ | 166 | "b 2b\n\t" \ |
| 146 | " mov %3, %0\n\t" \ | 167 | " mov %3, %0\n\t" \ |
| 147 | ".previous\n\n\t" \ | 168 | ".previous\n\n\t" \ |
| 148 | ".section __ex_table,#alloc\n\t" \ | 169 | ".section __ex_table,#alloc\n\t" \ |
| 149 | ".align 4\n\t" \ | 170 | ".align 4\n\t" \ |
| 150 | ".word 1b, 3b\n\t" \ | 171 | ".word 1b, 3b\n\t" \ |
| 151 | ".previous\n\n\t" \ | 172 | ".previous\n\n\t" \ |
| 152 | : "=&r" (ret) : "r" (x), "m" (*__m(addr)), \ | 173 | : "=&r" (ret) : "r" (x), "m" (*__m(addr)), \ |
| 153 | "i" (-EFAULT)) | 174 | "i" (-EFAULT)) |
| 154 | 175 | ||
| 155 | int __put_user_bad(void); | 176 | int __put_user_bad(void); |
| 156 | 177 | ||
| 157 | #define __get_user_check(x,addr,size,type) ({ \ | 178 | #define __get_user_check(x, addr, size, type) ({ \ |
| 158 | register int __gu_ret; \ | 179 | register int __gu_ret; \ |
| 159 | register unsigned long __gu_val; \ | 180 | register unsigned long __gu_val; \ |
| 160 | if (__access_ok(addr,size)) { \ | 181 | if (__access_ok(addr, size)) { \ |
| 161 | switch (size) { \ | 182 | switch (size) { \ |
| 162 | case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \ | 183 | case 1: \ |
| 163 | case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \ | 184 | __get_user_asm(__gu_val, ub, addr, __gu_ret); \ |
| 164 | case 4: __get_user_asm(__gu_val,,addr,__gu_ret); break; \ | 185 | break; \ |
| 165 | case 8: __get_user_asm(__gu_val,d,addr,__gu_ret); break; \ | 186 | case 2: \ |
| 166 | default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \ | 187 | __get_user_asm(__gu_val, uh, addr, __gu_ret); \ |
| 167 | } } else { __gu_val = 0; __gu_ret = -EFAULT; } x = (type) __gu_val; __gu_ret; }) | 188 | break; \ |
| 168 | 189 | case 4: \ | |
| 169 | #define __get_user_check_ret(x,addr,size,type,retval) ({ \ | 190 | __get_user_asm(__gu_val, , addr, __gu_ret); \ |
| 170 | register unsigned long __gu_val __asm__ ("l1"); \ | 191 | break; \ |
| 171 | if (__access_ok(addr,size)) { \ | 192 | case 8: \ |
| 172 | switch (size) { \ | 193 | __get_user_asm(__gu_val, d, addr, __gu_ret); \ |
| 173 | case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \ | 194 | break; \ |
| 174 | case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \ | 195 | default: \ |
| 175 | case 4: __get_user_asm_ret(__gu_val,,addr,retval); break; \ | 196 | __gu_val = 0; \ |
| 176 | case 8: __get_user_asm_ret(__gu_val,d,addr,retval); break; \ | 197 | __gu_ret = __get_user_bad(); \ |
| 177 | default: if (__get_user_bad()) return retval; \ | 198 | break; \ |
| 178 | } x = (type) __gu_val; } else return retval; }) | 199 | } \ |
| 179 | 200 | } else { \ | |
| 180 | #define __get_user_nocheck(x,addr,size,type) ({ \ | 201 | __gu_val = 0; \ |
| 181 | register int __gu_ret; \ | 202 | __gu_ret = -EFAULT; \ |
| 182 | register unsigned long __gu_val; \ | 203 | } \ |
| 183 | switch (size) { \ | 204 | x = (__force type) __gu_val; \ |
| 184 | case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \ | 205 | __gu_ret; \ |
| 185 | case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \ | 206 | }) |
| 186 | case 4: __get_user_asm(__gu_val,,addr,__gu_ret); break; \ | 207 | |
| 187 | case 8: __get_user_asm(__gu_val,d,addr,__gu_ret); break; \ | 208 | #define __get_user_check_ret(x, addr, size, type, retval) ({ \ |
| 188 | default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \ | 209 | register unsigned long __gu_val __asm__ ("l1"); \ |
| 189 | } x = (type) __gu_val; __gu_ret; }) | 210 | if (__access_ok(addr, size)) { \ |
| 190 | 211 | switch (size) { \ | |
| 191 | #define __get_user_nocheck_ret(x,addr,size,type,retval) ({ \ | 212 | case 1: \ |
| 192 | register unsigned long __gu_val __asm__ ("l1"); \ | 213 | __get_user_asm_ret(__gu_val, ub, addr, retval); \ |
| 193 | switch (size) { \ | 214 | break; \ |
| 194 | case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \ | 215 | case 2: \ |
| 195 | case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \ | 216 | __get_user_asm_ret(__gu_val, uh, addr, retval); \ |
| 196 | case 4: __get_user_asm_ret(__gu_val,,addr,retval); break; \ | 217 | break; \ |
| 197 | case 8: __get_user_asm_ret(__gu_val,d,addr,retval); break; \ | 218 | case 4: \ |
| 198 | default: if (__get_user_bad()) return retval; \ | 219 | __get_user_asm_ret(__gu_val, , addr, retval); \ |
| 199 | } x = (type) __gu_val; }) | 220 | break; \ |
| 200 | 221 | case 8: \ | |
| 201 | #define __get_user_asm(x,size,addr,ret) \ | 222 | __get_user_asm_ret(__gu_val, d, addr, retval); \ |
| 223 | break; \ | ||
| 224 | default: \ | ||
| 225 | if (__get_user_bad()) \ | ||
| 226 | return retval; \ | ||
| 227 | } \ | ||
| 228 | x = (__force type) __gu_val; \ | ||
| 229 | } else \ | ||
| 230 | return retval; \ | ||
| 231 | }) | ||
| 232 | |||
| 233 | #define __get_user_nocheck(x, addr, size, type) ({ \ | ||
| 234 | register int __gu_ret; \ | ||
| 235 | register unsigned long __gu_val; \ | ||
| 236 | switch (size) { \ | ||
| 237 | case 1: __get_user_asm(__gu_val, ub, addr, __gu_ret); break; \ | ||
| 238 | case 2: __get_user_asm(__gu_val, uh, addr, __gu_ret); break; \ | ||
| 239 | case 4: __get_user_asm(__gu_val, , addr, __gu_ret); break; \ | ||
| 240 | case 8: __get_user_asm(__gu_val, d, addr, __gu_ret); break; \ | ||
| 241 | default: \ | ||
| 242 | __gu_val = 0; \ | ||
| 243 | __gu_ret = __get_user_bad(); \ | ||
| 244 | break; \ | ||
| 245 | } \ | ||
| 246 | x = (__force type) __gu_val; \ | ||
| 247 | __gu_ret; \ | ||
| 248 | }) | ||
| 249 | |||
| 250 | #define __get_user_nocheck_ret(x, addr, size, type, retval) ({ \ | ||
| 251 | register unsigned long __gu_val __asm__ ("l1"); \ | ||
| 252 | switch (size) { \ | ||
| 253 | case 1: __get_user_asm_ret(__gu_val, ub, addr, retval); break; \ | ||
| 254 | case 2: __get_user_asm_ret(__gu_val, uh, addr, retval); break; \ | ||
| 255 | case 4: __get_user_asm_ret(__gu_val, , addr, retval); break; \ | ||
| 256 | case 8: __get_user_asm_ret(__gu_val, d, addr, retval); break; \ | ||
| 257 | default: \ | ||
| 258 | if (__get_user_bad()) \ | ||
| 259 | return retval; \ | ||
| 260 | } \ | ||
| 261 | x = (__force type) __gu_val; \ | ||
| 262 | }) | ||
| 263 | |||
| 264 | #define __get_user_asm(x, size, addr, ret) \ | ||
| 202 | __asm__ __volatile__( \ | 265 | __asm__ __volatile__( \ |
| 203 | "/* Get user asm, inline. */\n" \ | 266 | "/* Get user asm, inline. */\n" \ |
| 204 | "1:\t" "ld"#size " %2, %1\n\t" \ | 267 | "1:\t" "ld"#size " %2, %1\n\t" \ |
| 205 | "clr %0\n" \ | 268 | "clr %0\n" \ |
| 206 | "2:\n\n\t" \ | 269 | "2:\n\n\t" \ |
| 207 | ".section .fixup,#alloc,#execinstr\n\t" \ | 270 | ".section .fixup,#alloc,#execinstr\n\t" \ |
| 208 | ".align 4\n" \ | 271 | ".align 4\n" \ |
| 209 | "3:\n\t" \ | 272 | "3:\n\t" \ |
| 210 | "clr %1\n\t" \ | 273 | "clr %1\n\t" \ |
| 211 | "b 2b\n\t" \ | 274 | "b 2b\n\t" \ |
| 212 | " mov %3, %0\n\n\t" \ | 275 | " mov %3, %0\n\n\t" \ |
| 213 | ".previous\n\t" \ | 276 | ".previous\n\t" \ |
| 214 | ".section __ex_table,#alloc\n\t" \ | 277 | ".section __ex_table,#alloc\n\t" \ |
| 215 | ".align 4\n\t" \ | 278 | ".align 4\n\t" \ |
| 216 | ".word 1b, 3b\n\n\t" \ | 279 | ".word 1b, 3b\n\n\t" \ |
| 217 | ".previous\n\t" \ | 280 | ".previous\n\t" \ |
| 218 | : "=&r" (ret), "=&r" (x) : "m" (*__m(addr)), \ | 281 | : "=&r" (ret), "=&r" (x) : "m" (*__m(addr)), \ |
| 219 | "i" (-EFAULT)) | 282 | "i" (-EFAULT)) |
| 220 | 283 | ||
| 221 | #define __get_user_asm_ret(x,size,addr,retval) \ | 284 | #define __get_user_asm_ret(x, size, addr, retval) \ |
| 222 | if (__builtin_constant_p(retval) && retval == -EFAULT) \ | 285 | if (__builtin_constant_p(retval) && retval == -EFAULT) \ |
| 223 | __asm__ __volatile__( \ | 286 | __asm__ __volatile__( \ |
| 224 | "/* Get user asm ret, inline. */\n" \ | 287 | "/* Get user asm ret, inline. */\n" \ |
| 225 | "1:\t" "ld"#size " %1, %0\n\n\t" \ | 288 | "1:\t" "ld"#size " %1, %0\n\n\t" \ |
| 226 | ".section __ex_table,#alloc\n\t" \ | 289 | ".section __ex_table,#alloc\n\t" \ |
| 227 | ".align 4\n\t" \ | 290 | ".align 4\n\t" \ |
| 228 | ".word 1b,__ret_efault\n\n\t" \ | 291 | ".word 1b,__ret_efault\n\n\t" \ |
| 229 | ".previous\n\t" \ | 292 | ".previous\n\t" \ |
| 230 | : "=&r" (x) : "m" (*__m(addr))); \ | 293 | : "=&r" (x) : "m" (*__m(addr))); \ |
| 231 | else \ | 294 | else \ |
| 232 | __asm__ __volatile__( \ | 295 | __asm__ __volatile__( \ |
| 233 | "/* Get user asm ret, inline. */\n" \ | 296 | "/* Get user asm ret, inline. */\n" \ |
| 234 | "1:\t" "ld"#size " %1, %0\n\n\t" \ | 297 | "1:\t" "ld"#size " %1, %0\n\n\t" \ |
| 235 | ".section .fixup,#alloc,#execinstr\n\t" \ | 298 | ".section .fixup,#alloc,#execinstr\n\t" \ |
| 236 | ".align 4\n" \ | 299 | ".align 4\n" \ |
| 237 | "3:\n\t" \ | 300 | "3:\n\t" \ |
| 238 | "ret\n\t" \ | 301 | "ret\n\t" \ |
| 239 | " restore %%g0, %2, %%o0\n\n\t" \ | 302 | " restore %%g0, %2, %%o0\n\n\t" \ |
| 240 | ".previous\n\t" \ | 303 | ".previous\n\t" \ |
| 241 | ".section __ex_table,#alloc\n\t" \ | 304 | ".section __ex_table,#alloc\n\t" \ |
| 242 | ".align 4\n\t" \ | 305 | ".align 4\n\t" \ |
| 243 | ".word 1b, 3b\n\n\t" \ | 306 | ".word 1b, 3b\n\n\t" \ |
| 244 | ".previous\n\t" \ | 307 | ".previous\n\t" \ |
| 245 | : "=&r" (x) : "m" (*__m(addr)), "i" (retval)) | 308 | : "=&r" (x) : "m" (*__m(addr)), "i" (retval)) |
| 246 | 309 | ||
| 247 | int __get_user_bad(void); | 310 | int __get_user_bad(void); |
| 248 | 311 | ||
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h index c990a5e577f0..a35194b7dba0 100644 --- a/arch/sparc/include/asm/uaccess_64.h +++ b/arch/sparc/include/asm/uaccess_64.h | |||
| @@ -41,11 +41,11 @@ | |||
| 41 | #define get_fs() ((mm_segment_t){(current_thread_info()->current_ds)}) | 41 | #define get_fs() ((mm_segment_t){(current_thread_info()->current_ds)}) |
| 42 | #define get_ds() (KERNEL_DS) | 42 | #define get_ds() (KERNEL_DS) |
| 43 | 43 | ||
| 44 | #define segment_eq(a,b) ((a).seg == (b).seg) | 44 | #define segment_eq(a, b) ((a).seg == (b).seg) |
| 45 | 45 | ||
| 46 | #define set_fs(val) \ | 46 | #define set_fs(val) \ |
| 47 | do { \ | 47 | do { \ |
| 48 | current_thread_info()->current_ds =(val).seg; \ | 48 | current_thread_info()->current_ds = (val).seg; \ |
| 49 | __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \ | 49 | __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \ |
| 50 | } while(0) | 50 | } while(0) |
| 51 | 51 | ||
| @@ -88,121 +88,135 @@ void __retl_efault(void); | |||
| 88 | * of a performance impact. Thus we have a few rather ugly macros here, | 88 | * of a performance impact. Thus we have a few rather ugly macros here, |
| 89 | * and hide all the ugliness from the user. | 89 | * and hide all the ugliness from the user. |
| 90 | */ | 90 | */ |
| 91 | #define put_user(x,ptr) ({ \ | 91 | #define put_user(x, ptr) ({ \ |
| 92 | unsigned long __pu_addr = (unsigned long)(ptr); \ | 92 | unsigned long __pu_addr = (unsigned long)(ptr); \ |
| 93 | __chk_user_ptr(ptr); \ | 93 | __chk_user_ptr(ptr); \ |
| 94 | __put_user_nocheck((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); }) | 94 | __put_user_nocheck((__typeof__(*(ptr)))(x), __pu_addr, sizeof(*(ptr)));\ |
| 95 | }) | ||
| 95 | 96 | ||
| 96 | #define get_user(x,ptr) ({ \ | 97 | #define get_user(x, ptr) ({ \ |
| 97 | unsigned long __gu_addr = (unsigned long)(ptr); \ | 98 | unsigned long __gu_addr = (unsigned long)(ptr); \ |
| 98 | __chk_user_ptr(ptr); \ | 99 | __chk_user_ptr(ptr); \ |
| 99 | __get_user_nocheck((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); }) | 100 | __get_user_nocheck((x), __gu_addr, sizeof(*(ptr)), __typeof__(*(ptr)));\ |
| 101 | }) | ||
| 100 | 102 | ||
| 101 | #define __put_user(x,ptr) put_user(x,ptr) | 103 | #define __put_user(x, ptr) put_user(x, ptr) |
| 102 | #define __get_user(x,ptr) get_user(x,ptr) | 104 | #define __get_user(x, ptr) get_user(x, ptr) |
| 103 | 105 | ||
| 104 | struct __large_struct { unsigned long buf[100]; }; | 106 | struct __large_struct { unsigned long buf[100]; }; |
| 105 | #define __m(x) ((struct __large_struct *)(x)) | 107 | #define __m(x) ((struct __large_struct *)(x)) |
| 106 | 108 | ||
| 107 | #define __put_user_nocheck(data,addr,size) ({ \ | 109 | #define __put_user_nocheck(data, addr, size) ({ \ |
| 108 | register int __pu_ret; \ | 110 | register int __pu_ret; \ |
| 109 | switch (size) { \ | 111 | switch (size) { \ |
| 110 | case 1: __put_user_asm(data,b,addr,__pu_ret); break; \ | 112 | case 1: __put_user_asm(data, b, addr, __pu_ret); break; \ |
| 111 | case 2: __put_user_asm(data,h,addr,__pu_ret); break; \ | 113 | case 2: __put_user_asm(data, h, addr, __pu_ret); break; \ |
| 112 | case 4: __put_user_asm(data,w,addr,__pu_ret); break; \ | 114 | case 4: __put_user_asm(data, w, addr, __pu_ret); break; \ |
| 113 | case 8: __put_user_asm(data,x,addr,__pu_ret); break; \ | 115 | case 8: __put_user_asm(data, x, addr, __pu_ret); break; \ |
| 114 | default: __pu_ret = __put_user_bad(); break; \ | 116 | default: __pu_ret = __put_user_bad(); break; \ |
| 115 | } __pu_ret; }) | 117 | } \ |
| 116 | 118 | __pu_ret; \ | |
| 117 | #define __put_user_asm(x,size,addr,ret) \ | 119 | }) |
| 120 | |||
| 121 | #define __put_user_asm(x, size, addr, ret) \ | ||
| 118 | __asm__ __volatile__( \ | 122 | __asm__ __volatile__( \ |
| 119 | "/* Put user asm, inline. */\n" \ | 123 | "/* Put user asm, inline. */\n" \ |
| 120 | "1:\t" "st"#size "a %1, [%2] %%asi\n\t" \ | 124 | "1:\t" "st"#size "a %1, [%2] %%asi\n\t" \ |
| 121 | "clr %0\n" \ | 125 | "clr %0\n" \ |
| 122 | "2:\n\n\t" \ | 126 | "2:\n\n\t" \ |
| 123 | ".section .fixup,#alloc,#execinstr\n\t" \ | 127 | ".section .fixup,#alloc,#execinstr\n\t" \ |
| 124 | ".align 4\n" \ | 128 | ".align 4\n" \ |
| 125 | "3:\n\t" \ | 129 | "3:\n\t" \ |
| 126 | "sethi %%hi(2b), %0\n\t" \ | 130 | "sethi %%hi(2b), %0\n\t" \ |
| 127 | "jmpl %0 + %%lo(2b), %%g0\n\t" \ | 131 | "jmpl %0 + %%lo(2b), %%g0\n\t" \ |
| 128 | " mov %3, %0\n\n\t" \ | 132 | " mov %3, %0\n\n\t" \ |
| 129 | ".previous\n\t" \ | 133 | ".previous\n\t" \ |
| 130 | ".section __ex_table,\"a\"\n\t" \ | 134 | ".section __ex_table,\"a\"\n\t" \ |
| 131 | ".align 4\n\t" \ | 135 | ".align 4\n\t" \ |
| 132 | ".word 1b, 3b\n\t" \ | 136 | ".word 1b, 3b\n\t" \ |
| 133 | ".previous\n\n\t" \ | 137 | ".previous\n\n\t" \ |
| 134 | : "=r" (ret) : "r" (x), "r" (__m(addr)), \ | 138 | : "=r" (ret) : "r" (x), "r" (__m(addr)), \ |
| 135 | "i" (-EFAULT)) | 139 | "i" (-EFAULT)) |
| 136 | 140 | ||
| 137 | int __put_user_bad(void); | 141 | int __put_user_bad(void); |
| 138 | 142 | ||
| 139 | #define __get_user_nocheck(data,addr,size,type) ({ \ | 143 | #define __get_user_nocheck(data, addr, size, type) ({ \ |
| 140 | register int __gu_ret; \ | 144 | register int __gu_ret; \ |
| 141 | register unsigned long __gu_val; \ | 145 | register unsigned long __gu_val; \ |
| 142 | switch (size) { \ | 146 | switch (size) { \ |
| 143 | case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \ | 147 | case 1: __get_user_asm(__gu_val, ub, addr, __gu_ret); break; \ |
| 144 | case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \ | 148 | case 2: __get_user_asm(__gu_val, uh, addr, __gu_ret); break; \ |
| 145 | case 4: __get_user_asm(__gu_val,uw,addr,__gu_ret); break; \ | 149 | case 4: __get_user_asm(__gu_val, uw, addr, __gu_ret); break; \ |
| 146 | case 8: __get_user_asm(__gu_val,x,addr,__gu_ret); break; \ | 150 | case 8: __get_user_asm(__gu_val, x, addr, __gu_ret); break; \ |
| 147 | default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \ | 151 | default: \ |
| 148 | } data = (type) __gu_val; __gu_ret; }) | 152 | __gu_val = 0; \ |
| 149 | 153 | __gu_ret = __get_user_bad(); \ | |
| 150 | #define __get_user_nocheck_ret(data,addr,size,type,retval) ({ \ | 154 | break; \ |
| 151 | register unsigned long __gu_val __asm__ ("l1"); \ | 155 | } \ |
| 152 | switch (size) { \ | 156 | data = (__force type) __gu_val; \ |
| 153 | case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \ | 157 | __gu_ret; \ |
| 154 | case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \ | 158 | }) |
| 155 | case 4: __get_user_asm_ret(__gu_val,uw,addr,retval); break; \ | 159 | |
| 156 | case 8: __get_user_asm_ret(__gu_val,x,addr,retval); break; \ | 160 | #define __get_user_nocheck_ret(data, addr, size, type, retval) ({ \ |
| 157 | default: if (__get_user_bad()) return retval; \ | 161 | register unsigned long __gu_val __asm__ ("l1"); \ |
| 158 | } data = (type) __gu_val; }) | 162 | switch (size) { \ |
| 159 | 163 | case 1: __get_user_asm_ret(__gu_val, ub, addr, retval); break; \ | |
| 160 | #define __get_user_asm(x,size,addr,ret) \ | 164 | case 2: __get_user_asm_ret(__gu_val, uh, addr, retval); break; \ |
| 165 | case 4: __get_user_asm_ret(__gu_val, uw, addr, retval); break; \ | ||
| 166 | case 8: __get_user_asm_ret(__gu_val, x, addr, retval); break; \ | ||
| 167 | default: \ | ||
| 168 | if (__get_user_bad()) \ | ||
| 169 | return retval; \ | ||
| 170 | } \ | ||
| 171 | data = (__force type) __gu_val; \ | ||
| 172 | }) | ||
| 173 | |||
| 174 | #define __get_user_asm(x, size, addr, ret) \ | ||
| 161 | __asm__ __volatile__( \ | 175 | __asm__ __volatile__( \ |
| 162 | "/* Get user asm, inline. */\n" \ | 176 | "/* Get user asm, inline. */\n" \ |
| 163 | "1:\t" "ld"#size "a [%2] %%asi, %1\n\t" \ | 177 | "1:\t" "ld"#size "a [%2] %%asi, %1\n\t" \ |
| 164 | "clr %0\n" \ | 178 | "clr %0\n" \ |
| 165 | "2:\n\n\t" \ | 179 | "2:\n\n\t" \ |
| 166 | ".section .fixup,#alloc,#execinstr\n\t" \ | 180 | ".section .fixup,#alloc,#execinstr\n\t" \ |
| 167 | ".align 4\n" \ | 181 | ".align 4\n" \ |
| 168 | "3:\n\t" \ | 182 | "3:\n\t" \ |
| 169 | "sethi %%hi(2b), %0\n\t" \ | 183 | "sethi %%hi(2b), %0\n\t" \ |
| 170 | "clr %1\n\t" \ | 184 | "clr %1\n\t" \ |
| 171 | "jmpl %0 + %%lo(2b), %%g0\n\t" \ | 185 | "jmpl %0 + %%lo(2b), %%g0\n\t" \ |
| 172 | " mov %3, %0\n\n\t" \ | 186 | " mov %3, %0\n\n\t" \ |
| 173 | ".previous\n\t" \ | 187 | ".previous\n\t" \ |
| 174 | ".section __ex_table,\"a\"\n\t" \ | 188 | ".section __ex_table,\"a\"\n\t" \ |
| 175 | ".align 4\n\t" \ | 189 | ".align 4\n\t" \ |
| 176 | ".word 1b, 3b\n\n\t" \ | 190 | ".word 1b, 3b\n\n\t" \ |
| 177 | ".previous\n\t" \ | 191 | ".previous\n\t" \ |
| 178 | : "=r" (ret), "=r" (x) : "r" (__m(addr)), \ | 192 | : "=r" (ret), "=r" (x) : "r" (__m(addr)), \ |
| 179 | "i" (-EFAULT)) | 193 | "i" (-EFAULT)) |
| 180 | 194 | ||
| 181 | #define __get_user_asm_ret(x,size,addr,retval) \ | 195 | #define __get_user_asm_ret(x, size, addr, retval) \ |
| 182 | if (__builtin_constant_p(retval) && retval == -EFAULT) \ | 196 | if (__builtin_constant_p(retval) && retval == -EFAULT) \ |
| 183 | __asm__ __volatile__( \ | 197 | __asm__ __volatile__( \ |
| 184 | "/* Get user asm ret, inline. */\n" \ | 198 | "/* Get user asm ret, inline. */\n" \ |
| 185 | "1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \ | 199 | "1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \ |
| 186 | ".section __ex_table,\"a\"\n\t" \ | 200 | ".section __ex_table,\"a\"\n\t" \ |
| 187 | ".align 4\n\t" \ | 201 | ".align 4\n\t" \ |
| 188 | ".word 1b,__ret_efault\n\n\t" \ | 202 | ".word 1b,__ret_efault\n\n\t" \ |
| 189 | ".previous\n\t" \ | 203 | ".previous\n\t" \ |
| 190 | : "=r" (x) : "r" (__m(addr))); \ | 204 | : "=r" (x) : "r" (__m(addr))); \ |
| 191 | else \ | 205 | else \ |
| 192 | __asm__ __volatile__( \ | 206 | __asm__ __volatile__( \ |
| 193 | "/* Get user asm ret, inline. */\n" \ | 207 | "/* Get user asm ret, inline. */\n" \ |
| 194 | "1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \ | 208 | "1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \ |
| 195 | ".section .fixup,#alloc,#execinstr\n\t" \ | 209 | ".section .fixup,#alloc,#execinstr\n\t" \ |
| 196 | ".align 4\n" \ | 210 | ".align 4\n" \ |
| 197 | "3:\n\t" \ | 211 | "3:\n\t" \ |
| 198 | "ret\n\t" \ | 212 | "ret\n\t" \ |
| 199 | " restore %%g0, %2, %%o0\n\n\t" \ | 213 | " restore %%g0, %2, %%o0\n\n\t" \ |
| 200 | ".previous\n\t" \ | 214 | ".previous\n\t" \ |
| 201 | ".section __ex_table,\"a\"\n\t" \ | 215 | ".section __ex_table,\"a\"\n\t" \ |
| 202 | ".align 4\n\t" \ | 216 | ".align 4\n\t" \ |
| 203 | ".word 1b, 3b\n\n\t" \ | 217 | ".word 1b, 3b\n\n\t" \ |
| 204 | ".previous\n\t" \ | 218 | ".previous\n\t" \ |
| 205 | : "=r" (x) : "r" (__m(addr)), "i" (retval)) | 219 | : "=r" (x) : "r" (__m(addr)), "i" (retval)) |
| 206 | 220 | ||
| 207 | int __get_user_bad(void); | 221 | int __get_user_bad(void); |
| 208 | 222 | ||
