Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.26-rc2 285 lines 8.1 kB view raw
1#ifndef __ASM_SH_UACCESS_64_H 2#define __ASM_SH_UACCESS_64_H 3 4/* 5 * include/asm-sh/uaccess_64.h 6 * 7 * Copyright (C) 2000, 2001 Paolo Alberelli 8 * Copyright (C) 2003, 2004 Paul Mundt 9 * 10 * User space memory access functions 11 * 12 * Copyright (C) 1999 Niibe Yutaka 13 * 14 * Based on: 15 * MIPS implementation version 1.15 by 16 * Copyright (C) 1996, 1997, 1998 by Ralf Baechle 17 * and i386 version. 18 * 19 * This file is subject to the terms and conditions of the GNU General Public 20 * License. See the file "COPYING" in the main directory of this archive 21 * for more details. 22 */ 23#include <linux/errno.h> 24#include <linux/sched.h> 25 26#define VERIFY_READ 0 27#define VERIFY_WRITE 1 28 29/* 30 * The fs value determines whether argument validity checking should be 31 * performed or not. If get_fs() == USER_DS, checking is performed, with 32 * get_fs() == KERNEL_DS, checking is bypassed. 33 * 34 * For historical reasons (Data Segment Register?), these macros are misnamed. 35 */ 36 37#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) 38 39#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) 40#define USER_DS MAKE_MM_SEG(0x80000000) 41 42#define get_ds() (KERNEL_DS) 43#define get_fs() (current_thread_info()->addr_limit) 44#define set_fs(x) (current_thread_info()->addr_limit=(x)) 45 46#define segment_eq(a,b) ((a).seg == (b).seg) 47 48#define __addr_ok(addr) ((unsigned long)(addr) < (current_thread_info()->addr_limit.seg)) 49 50/* 51 * Uhhuh, this needs 33-bit arithmetic. We have a carry.. 52 * 53 * sum := addr + size; carry? --> flag = true; 54 * if (sum >= addr_limit) flag = true; 55 */ 56#define __range_ok(addr,size) (((unsigned long) (addr) + (size) < (current_thread_info()->addr_limit.seg)) ? 0 : 1) 57 58#define access_ok(type,addr,size) (__range_ok(addr,size) == 0) 59#define __access_ok(addr,size) (__range_ok(addr,size) == 0) 60 61/* 62 * Uh, these should become the main single-value transfer routines ... 63 * They automatically use the right size if we just have the right 64 * pointer type ... 65 * 66 * As MIPS uses the same address space for kernel and user data, we 67 * can just do these as direct assignments. 68 * 69 * Careful to not 70 * (a) re-use the arguments for side effects (sizeof is ok) 71 * (b) require any knowledge of processes at this stage 72 */ 73#define put_user(x,ptr) __put_user_check((x),(ptr),sizeof(*(ptr))) 74#define get_user(x,ptr) __get_user_check((x),(ptr),sizeof(*(ptr))) 75 76/* 77 * The "__xxx" versions do not do address space checking, useful when 78 * doing multiple accesses to the same area (the user has to do the 79 * checks by hand with "access_ok()") 80 */ 81#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr))) 82#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr))) 83 84/* 85 * The "xxx_ret" versions return constant specified in third argument, if 86 * something bad happens. These macros can be optimized for the 87 * case of just returning from the function xxx_ret is used. 88 */ 89 90#define put_user_ret(x,ptr,ret) ({ \ 91if (put_user(x,ptr)) return ret; }) 92 93#define get_user_ret(x,ptr,ret) ({ \ 94if (get_user(x,ptr)) return ret; }) 95 96#define __put_user_ret(x,ptr,ret) ({ \ 97if (__put_user(x,ptr)) return ret; }) 98 99#define __get_user_ret(x,ptr,ret) ({ \ 100if (__get_user(x,ptr)) return ret; }) 101 102struct __large_struct { unsigned long buf[100]; }; 103#define __m(x) (*(struct __large_struct *)(x)) 104 105#define __get_user_size(x,ptr,size,retval) \ 106do { \ 107 retval = 0; \ 108 switch (size) { \ 109 case 1: \ 110 retval = __get_user_asm_b(x, ptr); \ 111 break; \ 112 case 2: \ 113 retval = __get_user_asm_w(x, ptr); \ 114 break; \ 115 case 4: \ 116 retval = __get_user_asm_l(x, ptr); \ 117 break; \ 118 case 8: \ 119 retval = __get_user_asm_q(x, ptr); \ 120 break; \ 121 default: \ 122 __get_user_unknown(); \ 123 break; \ 124 } \ 125} while (0) 126 127#define __get_user_nocheck(x,ptr,size) \ 128({ \ 129 long __gu_err, __gu_val; \ 130 __get_user_size((void *)&__gu_val, (long)(ptr), \ 131 (size), __gu_err); \ 132 (x) = (__typeof__(*(ptr)))__gu_val; \ 133 __gu_err; \ 134}) 135 136#define __get_user_check(x,ptr,size) \ 137({ \ 138 long __gu_addr = (long)(ptr); \ 139 long __gu_err = -EFAULT, __gu_val; \ 140 if (__access_ok(__gu_addr, (size))) \ 141 __get_user_size((void *)&__gu_val, __gu_addr, \ 142 (size), __gu_err); \ 143 (x) = (__typeof__(*(ptr))) __gu_val; \ 144 __gu_err; \ 145}) 146 147extern long __get_user_asm_b(void *, long); 148extern long __get_user_asm_w(void *, long); 149extern long __get_user_asm_l(void *, long); 150extern long __get_user_asm_q(void *, long); 151extern void __get_user_unknown(void); 152 153#define __put_user_size(x,ptr,size,retval) \ 154do { \ 155 retval = 0; \ 156 switch (size) { \ 157 case 1: \ 158 retval = __put_user_asm_b(x, ptr); \ 159 break; \ 160 case 2: \ 161 retval = __put_user_asm_w(x, ptr); \ 162 break; \ 163 case 4: \ 164 retval = __put_user_asm_l(x, ptr); \ 165 break; \ 166 case 8: \ 167 retval = __put_user_asm_q(x, ptr); \ 168 break; \ 169 default: \ 170 __put_user_unknown(); \ 171 } \ 172} while (0) 173 174#define __put_user_nocheck(x,ptr,size) \ 175({ \ 176 long __pu_err; \ 177 __typeof__(*(ptr)) __pu_val = (x); \ 178 __put_user_size((void *)&__pu_val, (long)(ptr), (size), __pu_err); \ 179 __pu_err; \ 180}) 181 182#define __put_user_check(x,ptr,size) \ 183({ \ 184 long __pu_err = -EFAULT; \ 185 long __pu_addr = (long)(ptr); \ 186 __typeof__(*(ptr)) __pu_val = (x); \ 187 \ 188 if (__access_ok(__pu_addr, (size))) \ 189 __put_user_size((void *)&__pu_val, __pu_addr, (size), __pu_err);\ 190 __pu_err; \ 191}) 192 193extern long __put_user_asm_b(void *, long); 194extern long __put_user_asm_w(void *, long); 195extern long __put_user_asm_l(void *, long); 196extern long __put_user_asm_q(void *, long); 197extern void __put_user_unknown(void); 198 199 200/* Generic arbitrary sized copy. */ 201/* Return the number of bytes NOT copied */ 202/* XXX: should be such that: 4byte and the rest. */ 203extern __kernel_size_t __copy_user(void *__to, const void *__from, __kernel_size_t __n); 204 205#define copy_to_user_ret(to,from,n,retval) ({ \ 206if (copy_to_user(to,from,n)) \ 207 return retval; \ 208}) 209 210#define __copy_to_user(to,from,n) \ 211 __copy_user((void *)(to), \ 212 (void *)(from), n) 213 214#define __copy_to_user_ret(to,from,n,retval) ({ \ 215if (__copy_to_user(to,from,n)) \ 216 return retval; \ 217}) 218 219#define copy_from_user_ret(to,from,n,retval) ({ \ 220if (copy_from_user(to,from,n)) \ 221 return retval; \ 222}) 223 224#define __copy_from_user(to,from,n) \ 225 __copy_user((void *)(to), \ 226 (void *)(from), n) 227 228#define __copy_from_user_ret(to,from,n,retval) ({ \ 229if (__copy_from_user(to,from,n)) \ 230 return retval; \ 231}) 232 233#define __copy_to_user_inatomic __copy_to_user 234#define __copy_from_user_inatomic __copy_from_user 235 236/* XXX: Not sure it works well.. 237 should be such that: 4byte clear and the rest. */ 238extern __kernel_size_t __clear_user(void *addr, __kernel_size_t size); 239 240#define clear_user(addr,n) ({ \ 241void * __cl_addr = (addr); \ 242unsigned long __cl_size = (n); \ 243if (__cl_size && __access_ok(((unsigned long)(__cl_addr)), __cl_size)) \ 244__cl_size = __clear_user(__cl_addr, __cl_size); \ 245__cl_size; }) 246 247extern int __strncpy_from_user(unsigned long __dest, unsigned long __src, int __count); 248 249#define strncpy_from_user(dest,src,count) ({ \ 250unsigned long __sfu_src = (unsigned long) (src); \ 251int __sfu_count = (int) (count); \ 252long __sfu_res = -EFAULT; \ 253if(__access_ok(__sfu_src, __sfu_count)) { \ 254__sfu_res = __strncpy_from_user((unsigned long) (dest), __sfu_src, __sfu_count); \ 255} __sfu_res; }) 256 257#define strlen_user(str) strnlen_user(str, ~0UL >> 1) 258 259/* 260 * Return the size of a string (including the ending 0!) 261 */ 262extern long __strnlen_user(const char *__s, long __n); 263 264static inline long strnlen_user(const char *s, long n) 265{ 266 if (!__addr_ok(s)) 267 return 0; 268 else 269 return __strnlen_user(s, n); 270} 271 272struct exception_table_entry 273{ 274 unsigned long insn, fixup; 275}; 276 277#ifdef CONFIG_MMU 278#define ARCH_HAS_SEARCH_EXTABLE 279#endif 280 281/* Returns 0 if exception not found and fixup.unit otherwise. */ 282extern unsigned long search_exception_table(unsigned long addr); 283extern const struct exception_table_entry *search_exception_tables (unsigned long addr); 284 285#endif /* __ASM_SH_UACCESS_64_H */