diff options
| -rw-r--r-- | arch/microblaze/include/asm/uaccess.h | 89 |
1 files changed, 66 insertions, 23 deletions
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h index 1af92025fff9..b079ac31a671 100644 --- a/arch/microblaze/include/asm/uaccess.h +++ b/arch/microblaze/include/asm/uaccess.h | |||
| @@ -146,31 +146,75 @@ static inline unsigned long __must_check clear_user(void __user *to, | |||
| 146 | 146 | ||
| 147 | #ifndef CONFIG_MMU | 147 | #ifndef CONFIG_MMU |
| 148 | 148 | ||
| 149 | /* Undefined function to trigger linker error */ | 149 | extern long __user_bad(void); |
| 150 | extern int bad_user_access_length(void); | 150 | |
| 151 | #define __get_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \ | ||
| 152 | ({ \ | ||
| 153 | __asm__ __volatile__ ( \ | ||
| 154 | "1:" insn " %1, %2, r0;" \ | ||
| 155 | " addk %0, r0, r0;" \ | ||
| 156 | "2: " \ | ||
| 157 | __FIXUP_SECTION \ | ||
| 158 | "3: brid 2b;" \ | ||
| 159 | " addik %0, r0, %3;" \ | ||
| 160 | ".previous;" \ | ||
| 161 | __EX_TABLE_SECTION \ | ||
| 162 | ".word 1b,3b;" \ | ||
| 163 | ".previous;" \ | ||
| 164 | : "=&r"(__gu_err), "=r"(__gu_val) \ | ||
| 165 | : "r"(__gu_ptr), "i"(-EFAULT) \ | ||
| 166 | ); \ | ||
| 167 | }) | ||
| 168 | |||
| 169 | /** | ||
| 170 | * get_user: - Get a simple variable from user space. | ||
| 171 | * @x: Variable to store result. | ||
| 172 | * @ptr: Source address, in user space. | ||
| 173 | * | ||
| 174 | * Context: User context only. This function may sleep. | ||
| 175 | * | ||
| 176 | * This macro copies a single simple variable from user space to kernel | ||
| 177 | * space. It supports simple types like char and int, but not larger | ||
| 178 | * data types like structures or arrays. | ||
| 179 | * | ||
| 180 | * @ptr must have pointer-to-simple-variable type, and the result of | ||
| 181 | * dereferencing @ptr must be assignable to @x without a cast. | ||
| 182 | * | ||
| 183 | * Returns zero on success, or -EFAULT on error. | ||
| 184 | * On error, the variable @x is set to zero. | ||
| 185 | */ | ||
| 186 | |||
| 187 | #define __get_user(x, ptr) \ | ||
| 188 | ({ \ | ||
| 189 | unsigned long __gu_val; \ | ||
| 190 | /*unsigned long __gu_ptr = (unsigned long)(ptr);*/ \ | ||
| 191 | long __gu_err; \ | ||
| 192 | switch (sizeof(*(ptr))) { \ | ||
| 193 | case 1: \ | ||
| 194 | __get_user_asm("lbu", (ptr), __gu_val, __gu_err); \ | ||
| 195 | break; \ | ||
| 196 | case 2: \ | ||
| 197 | __get_user_asm("lhu", (ptr), __gu_val, __gu_err); \ | ||
| 198 | break; \ | ||
| 199 | case 4: \ | ||
| 200 | __get_user_asm("lw", (ptr), __gu_val, __gu_err); \ | ||
| 201 | break; \ | ||
| 202 | default: \ | ||
| 203 | /* __gu_val = 0; __gu_err = -EINVAL;*/ __gu_err = __user_bad();\ | ||
| 204 | } \ | ||
| 205 | x = (__typeof__(*(ptr))) __gu_val; \ | ||
| 206 | __gu_err; \ | ||
| 207 | }) | ||
| 208 | |||
| 151 | 209 | ||
| 152 | /* FIXME this is function for optimalization -> memcpy */ | 210 | #define get_user(x, ptr) \ |
| 153 | #define __get_user(var, ptr) \ | 211 | ({ \ |
| 154 | ({ \ | 212 | access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) \ |
| 155 | int __gu_err = 0; \ | 213 | ? __get_user((x), (ptr)) : -EFAULT; \ |
| 156 | switch (sizeof(*(ptr))) { \ | ||
| 157 | case 1: \ | ||
| 158 | case 2: \ | ||
| 159 | case 4: \ | ||
| 160 | (var) = *(ptr); \ | ||
| 161 | break; \ | ||
| 162 | case 8: \ | ||
| 163 | memcpy((void *) &(var), (ptr), 8); \ | ||
| 164 | break; \ | ||
| 165 | default: \ | ||
| 166 | (var) = 0; \ | ||
| 167 | __gu_err = __get_user_bad(); \ | ||
| 168 | break; \ | ||
| 169 | } \ | ||
| 170 | __gu_err; \ | ||
| 171 | }) | 214 | }) |
| 172 | 215 | ||
| 173 | #define __get_user_bad() (bad_user_access_length(), (-EFAULT)) | 216 | /* Undefined function to trigger linker error */ |
| 217 | extern int bad_user_access_length(void); | ||
| 174 | 218 | ||
| 175 | /* FIXME is not there defined __pu_val */ | 219 | /* FIXME is not there defined __pu_val */ |
| 176 | #define __put_user(var, ptr) \ | 220 | #define __put_user(var, ptr) \ |
| @@ -197,7 +241,6 @@ extern int bad_user_access_length(void); | |||
| 197 | #define __put_user_bad() (bad_user_access_length(), (-EFAULT)) | 241 | #define __put_user_bad() (bad_user_access_length(), (-EFAULT)) |
| 198 | 242 | ||
| 199 | #define put_user(x, ptr) __put_user((x), (ptr)) | 243 | #define put_user(x, ptr) __put_user((x), (ptr)) |
| 200 | #define get_user(x, ptr) __get_user((x), (ptr)) | ||
| 201 | 244 | ||
| 202 | #define copy_to_user(to, from, n) (memcpy((to), (from), (n)), 0) | 245 | #define copy_to_user(to, from, n) (memcpy((to), (from), (n)), 0) |
| 203 | #define copy_from_user(to, from, n) (memcpy((to), (from), (n)), 0) | 246 | #define copy_from_user(to, from, n) (memcpy((to), (from), (n)), 0) |
