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.22-rc1 271 lines 7.0 kB view raw
1/* Changes made by Lineo Inc. May 2001 2 * 3 * Based on: include/asm-m68knommu/uaccess.h 4 */ 5 6#ifndef __BLACKFIN_UACCESS_H 7#define __BLACKFIN_UACCESS_H 8 9/* 10 * User space memory access functions 11 */ 12#include <linux/sched.h> 13#include <linux/mm.h> 14#include <linux/string.h> 15 16#include <asm/segment.h> 17#ifndef CONFIG_NO_ACCESS_CHECK 18# include <asm/bfin-global.h> 19#endif 20 21#define get_ds() (KERNEL_DS) 22#define get_fs() (current_thread_info()->addr_limit) 23 24static inline void set_fs(mm_segment_t fs) 25{ 26 current_thread_info()->addr_limit = fs; 27} 28 29#define segment_eq(a,b) ((a) == (b)) 30 31#define VERIFY_READ 0 32#define VERIFY_WRITE 1 33 34#define access_ok(type,addr,size) _access_ok((unsigned long)(addr),(size)) 35 36static inline int is_in_rom(unsigned long addr) 37{ 38 /* 39 * What we are really trying to do is determine if addr is 40 * in an allocated kernel memory region. If not then assume 41 * we cannot free it or otherwise de-allocate it. Ideally 42 * we could restrict this to really being in a ROM or flash, 43 * but that would need to be done on a board by board basis, 44 * not globally. 45 */ 46 if ((addr < _ramstart) || (addr >= _ramend)) 47 return (1); 48 49 /* Default case, not in ROM */ 50 return (0); 51} 52 53/* 54 * The fs value determines whether argument validity checking should be 55 * performed or not. If get_fs() == USER_DS, checking is performed, with 56 * get_fs() == KERNEL_DS, checking is bypassed. 57 */ 58 59#ifdef CONFIG_NO_ACCESS_CHECK 60static inline int _access_ok(unsigned long addr, unsigned long size) { return 1; } 61#else 62#ifdef CONFIG_ACCESS_OK_L1 63extern int _access_ok(unsigned long addr, unsigned long size)__attribute__((l1_text)); 64#else 65extern int _access_ok(unsigned long addr, unsigned long size); 66#endif 67#endif 68 69/* 70 * The exception table consists of pairs of addresses: the first is the 71 * address of an instruction that is allowed to fault, and the second is 72 * the address at which the program should continue. No registers are 73 * modified, so it is entirely up to the continuation code to figure out 74 * what to do. 75 * 76 * All the routines below use bits of fixup code that are out of line 77 * with the main instruction path. This means when everything is well, 78 * we don't even have to jump over them. Further, they do not intrude 79 * on our cache or tlb entries. 80 */ 81 82struct exception_table_entry { 83 unsigned long insn, fixup; 84}; 85 86/* Returns 0 if exception not found and fixup otherwise. */ 87extern unsigned long search_exception_table(unsigned long); 88 89/* 90 * These are the main single-value transfer routines. They automatically 91 * use the right size if we just have the right pointer type. 92 */ 93 94#define put_user(x,p) \ 95 ({ \ 96 int _err = 0; \ 97 typeof(*(p)) _x = (x); \ 98 typeof(*(p)) *_p = (p); \ 99 if (!access_ok(VERIFY_WRITE, _p, sizeof(*(_p)))) {\ 100 _err = -EFAULT; \ 101 } \ 102 else { \ 103 switch (sizeof (*(_p))) { \ 104 case 1: \ 105 __put_user_asm(_x, _p, B); \ 106 break; \ 107 case 2: \ 108 __put_user_asm(_x, _p, W); \ 109 break; \ 110 case 4: \ 111 __put_user_asm(_x, _p, ); \ 112 break; \ 113 case 8: { \ 114 long _xl, _xh; \ 115 _xl = ((long *)&_x)[0]; \ 116 _xh = ((long *)&_x)[1]; \ 117 __put_user_asm(_xl, ((long *)_p)+0, ); \ 118 __put_user_asm(_xh, ((long *)_p)+1, ); \ 119 } break; \ 120 default: \ 121 _err = __put_user_bad(); \ 122 break; \ 123 } \ 124 } \ 125 _err; \ 126 }) 127 128#define __put_user(x,p) put_user(x,p) 129static inline int bad_user_access_length(void) 130{ 131 panic("bad_user_access_length"); 132 return -1; 133} 134 135#define __put_user_bad() (printk(KERN_INFO "put_user_bad %s:%d %s\n",\ 136 __FILE__, __LINE__, __FUNCTION__),\ 137 bad_user_access_length(), (-EFAULT)) 138 139/* 140 * Tell gcc we read from memory instead of writing: this is because 141 * we do not write to any memory gcc knows about, so there are no 142 * aliasing issues. 143 */ 144 145#define __ptr(x) ((unsigned long *)(x)) 146 147#define __put_user_asm(x,p,bhw) \ 148 __asm__ (#bhw"[%1] = %0;\n\t" \ 149 : /* no outputs */ \ 150 :"d" (x),"a" (__ptr(p)) : "memory") 151 152#define get_user(x,p) \ 153 ({ \ 154 int _err = 0; \ 155 typeof(*(p)) *_p = (p); \ 156 if (!access_ok(VERIFY_READ, _p, sizeof(*(_p)))) { \ 157 _err = -EFAULT; \ 158 } \ 159 else { \ 160 switch (sizeof(*(_p))) { \ 161 case 1: \ 162 __get_user_asm(x, _p, B,(Z)); \ 163 break; \ 164 case 2: \ 165 __get_user_asm(x, _p, W,(Z)); \ 166 break; \ 167 case 4: \ 168 __get_user_asm(x, _p, , ); \ 169 break; \ 170 case 8: { \ 171 unsigned long _xl, _xh; \ 172 __get_user_asm(_xl, ((unsigned long *)_p)+0, , ); \ 173 __get_user_asm(_xh, ((unsigned long *)_p)+1, , ); \ 174 ((unsigned long *)&x)[0] = _xl; \ 175 ((unsigned long *)&x)[1] = _xh; \ 176 } break; \ 177 default: \ 178 x = 0; \ 179 printk(KERN_INFO "get_user_bad: %s:%d %s\n", \ 180 __FILE__, __LINE__, __FUNCTION__); \ 181 _err = __get_user_bad(); \ 182 break; \ 183 } \ 184 } \ 185 _err; \ 186 }) 187 188#define __get_user(x,p) get_user(x,p) 189 190#define __get_user_bad() (bad_user_access_length(), (-EFAULT)) 191 192#define __get_user_asm(x,p,bhw,option) \ 193 { \ 194 unsigned long _tmp; \ 195 __asm__ ("%0 =" #bhw "[%1]"#option";\n\t" \ 196 : "=d" (_tmp) \ 197 : "a" (__ptr(p))); \ 198 (x) = (__typeof__(*(p))) _tmp; \ 199 } 200 201#define __copy_from_user(to, from, n) copy_from_user(to, from, n) 202#define __copy_to_user(to, from, n) copy_to_user(to, from, n) 203#define __copy_to_user_inatomic __copy_to_user 204#define __copy_from_user_inatomic __copy_from_user 205 206#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n))\ 207 return retval; }) 208 209#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n))\ 210 return retval; }) 211 212static inline long copy_from_user(void *to, 213 const void __user * from, unsigned long n) 214{ 215 if (access_ok(VERIFY_READ, from, n)) 216 memcpy(to, from, n); 217 else 218 return n; 219 return 0; 220} 221 222static inline long copy_to_user(void *to, 223 const void __user * from, unsigned long n) 224{ 225 if (access_ok(VERIFY_WRITE, to, n)) 226 memcpy(to, from, n); 227 else 228 return n; 229 return 0; 230} 231 232/* 233 * Copy a null terminated string from userspace. 234 */ 235 236static inline long strncpy_from_user(char *dst, 237 const char *src, long count) 238{ 239 char *tmp; 240 if (!access_ok(VERIFY_READ, src, 1)) 241 return -EFAULT; 242 strncpy(dst, src, count); 243 for (tmp = dst; *tmp && count > 0; tmp++, count--) ; 244 return (tmp - dst); 245} 246 247/* 248 * Return the size of a string (including the ending 0) 249 * 250 * Return 0 on exception, a value greater than N if too long 251 */ 252static inline long strnlen_user(const char *src, long n) 253{ 254 return (strlen(src) + 1); 255} 256 257#define strlen_user(str) strnlen_user(str, 32767) 258 259/* 260 * Zero Userspace 261 */ 262 263static inline unsigned long __clear_user(void *to, unsigned long n) 264{ 265 memset(to, 0, n); 266 return 0; 267} 268 269#define clear_user(to, n) __clear_user(to, n) 270 271#endif /* _BLACKFIN_UACCESS_H */