| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #ifndef __V850_UACCESS_H__ | 
 | 2 | #define __V850_UACCESS_H__ | 
 | 3 |  | 
 | 4 | /* | 
 | 5 |  * User space memory access functions | 
 | 6 |  */ | 
 | 7 |  | 
 | 8 | #include <linux/errno.h> | 
 | 9 | #include <linux/string.h> | 
 | 10 |  | 
 | 11 | #include <asm/segment.h> | 
 | 12 | #include <asm/machdep.h> | 
 | 13 |  | 
 | 14 | #define VERIFY_READ	0 | 
 | 15 | #define VERIFY_WRITE	1 | 
 | 16 |  | 
 | 17 | extern inline int access_ok (int type, const void *addr, unsigned long size) | 
 | 18 | { | 
 | 19 | 	/* XXX I guess we should check against real ram bounds at least, and | 
 | 20 | 	   possibly make sure ADDR is not within the kernel. | 
 | 21 | 	   For now we just check to make sure it's not a small positive | 
 | 22 | 	   or negative value, as that will at least catch some kinds of | 
 | 23 | 	   error.  In particular, we make sure that ADDR's not within the | 
 | 24 | 	   interrupt vector area, which we know starts at zero, or within the | 
 | 25 | 	   peripheral-I/O area, which is located just _before_ zero.  */ | 
 | 26 | 	unsigned long val = (unsigned long)addr; | 
 | 27 | 	return val >= (0x80 + NUM_CPU_IRQS*16) && val < 0xFFFFF000; | 
 | 28 | } | 
 | 29 |  | 
 | 30 | /* this function will go away soon - use access_ok() instead */ | 
 | 31 | extern inline int __deprecated verify_area (int type, const void *addr, unsigned long size) | 
 | 32 | { | 
 | 33 | 	return access_ok (type, addr, size) ? 0 : -EFAULT; | 
 | 34 | } | 
 | 35 |  | 
 | 36 | /* | 
 | 37 |  * The exception table consists of pairs of addresses: the first is the | 
 | 38 |  * address of an instruction that is allowed to fault, and the second is | 
 | 39 |  * the address at which the program should continue.  No registers are | 
 | 40 |  * modified, so it is entirely up to the continuation code to figure out | 
 | 41 |  * what to do. | 
 | 42 |  * | 
 | 43 |  * All the routines below use bits of fixup code that are out of line | 
 | 44 |  * with the main instruction path.  This means when everything is well, | 
 | 45 |  * we don't even have to jump over them.  Further, they do not intrude | 
 | 46 |  * on our cache or tlb entries. | 
 | 47 |  */ | 
 | 48 |  | 
 | 49 | struct exception_table_entry | 
 | 50 | { | 
 | 51 | 	unsigned long insn, fixup; | 
 | 52 | }; | 
 | 53 |  | 
 | 54 | /* Returns 0 if exception not found and fixup otherwise.  */ | 
 | 55 | extern unsigned long search_exception_table (unsigned long); | 
 | 56 |  | 
 | 57 |  | 
 | 58 | /* | 
 | 59 |  * These are the main single-value transfer routines.  They automatically | 
 | 60 |  * use the right size if we just have the right pointer type. | 
 | 61 |  */ | 
 | 62 |  | 
 | 63 | extern int bad_user_access_length (void); | 
 | 64 |  | 
 | 65 | #define __get_user(var, ptr)						      \ | 
 | 66 |   ({									      \ | 
 | 67 | 	  int __gu_err = 0;						      \ | 
 | 68 | 	  typeof(*(ptr)) __gu_val = 0;					      \ | 
 | 69 | 	  switch (sizeof (*(ptr))) {					      \ | 
 | 70 | 	  case 1:							      \ | 
 | 71 | 	  case 2:							      \ | 
 | 72 | 	  case 4:							      \ | 
 | 73 | 		  __gu_val = *(ptr);					      \ | 
 | 74 | 		  break;						      \ | 
 | 75 | 	  case 8:							      \ | 
 | 76 | 		  memcpy(&__gu_val, ptr, sizeof(__gu_val));		      \ | 
 | 77 | 		  break;						      \ | 
 | 78 | 	  default:							      \ | 
 | 79 | 		  __gu_val = 0;						      \ | 
 | 80 | 		  __gu_err = __get_user_bad ();				      \ | 
 | 81 | 		  break;						      \ | 
 | 82 | 	  }								      \ | 
 | 83 | 	  (var) = __gu_val;						      \ | 
 | 84 | 	  __gu_err;							      \ | 
 | 85 |   }) | 
 | 86 | #define __get_user_bad()	(bad_user_access_length (), (-EFAULT)) | 
 | 87 |  | 
 | 88 | #define __put_user(var, ptr)						      \ | 
 | 89 |   ({									      \ | 
 | 90 | 	  int __pu_err = 0;						      \ | 
 | 91 | 	  switch (sizeof (*(ptr))) {					      \ | 
 | 92 | 	  case 1:							      \ | 
 | 93 | 	  case 2:							      \ | 
 | 94 | 	  case 4:							      \ | 
 | 95 | 		  *(ptr) = (var);					      \ | 
 | 96 | 		  break;						      \ | 
 | 97 | 	  case 8: {							      \ | 
 | 98 | 	  	  typeof(*(ptr)) __pu_val = 0;				      \ | 
 | 99 | 		  memcpy(ptr, &__pu_val, sizeof(__pu_val));		      \ | 
 | 100 | 		  }							      \ | 
 | 101 | 		  break;						      \ | 
 | 102 | 	  default:							      \ | 
 | 103 | 		  __pu_err = __put_user_bad ();				      \ | 
 | 104 | 		  break;						      \ | 
 | 105 | 	  }								      \ | 
 | 106 | 	  __pu_err;							      \ | 
 | 107 |   }) | 
 | 108 | #define __put_user_bad()	(bad_user_access_length (), (-EFAULT)) | 
 | 109 |  | 
 | 110 | #define put_user(x, ptr)	__put_user(x, ptr) | 
 | 111 | #define get_user(x, ptr)	__get_user(x, ptr) | 
 | 112 |  | 
 | 113 | #define __copy_from_user(to, from, n)	(memcpy (to, from, n), 0) | 
 | 114 | #define __copy_to_user(to, from, n)	(memcpy(to, from, n), 0) | 
 | 115 |  | 
 | 116 | #define __copy_to_user_inatomic __copy_to_user | 
 | 117 | #define __copy_from_user_inatomic __copy_from_user | 
 | 118 |  | 
 | 119 | #define copy_from_user(to, from, n)	__copy_from_user (to, from, n) | 
 | 120 | #define copy_to_user(to, from, n) 	__copy_to_user(to, from, n) | 
 | 121 |  | 
 | 122 | #define copy_to_user_ret(to,from,n,retval) \ | 
 | 123 |   ({ if (copy_to_user (to,from,n)) return retval; }) | 
 | 124 |  | 
 | 125 | #define copy_from_user_ret(to,from,n,retval) \ | 
 | 126 |   ({ if (copy_from_user (to,from,n)) return retval; }) | 
 | 127 |  | 
 | 128 | /* | 
 | 129 |  * Copy a null terminated string from userspace. | 
 | 130 |  */ | 
 | 131 |  | 
 | 132 | static inline long | 
 | 133 | strncpy_from_user (char *dst, const char *src, long count) | 
 | 134 | { | 
 | 135 | 	char *tmp; | 
 | 136 | 	strncpy (dst, src, count); | 
 | 137 | 	for (tmp = dst; *tmp && count > 0; tmp++, count--) | 
 | 138 | 		; | 
 | 139 | 	return tmp - dst; | 
 | 140 | } | 
 | 141 |  | 
 | 142 | /* | 
 | 143 |  * Return the size of a string (including the ending 0) | 
 | 144 |  * | 
 | 145 |  * Return 0 on exception, a value greater than N if too long | 
 | 146 |  */ | 
 | 147 | static inline long strnlen_user (const char *src, long n) | 
 | 148 | { | 
 | 149 | 	return strlen (src) + 1; | 
 | 150 | } | 
 | 151 |  | 
 | 152 | #define strlen_user(str)	strnlen_user (str, 32767) | 
 | 153 |  | 
 | 154 | /* | 
 | 155 |  * Zero Userspace | 
 | 156 |  */ | 
 | 157 |  | 
 | 158 | static inline unsigned long | 
 | 159 | clear_user (void *to, unsigned long n) | 
 | 160 | { | 
 | 161 | 	memset (to, 0, n); | 
 | 162 | 	return 0; | 
 | 163 | } | 
 | 164 |  | 
 | 165 | #endif /* __V850_UACCESS_H__ */ |