|
@@ -206,3 +206,63 @@ extern int fixup_exception(struct pt_regs *regs);
|
|
* Caller must check the pointer with access_ok() before calling this
|
|
* Caller must check the pointer with access_ok() before calling this
|
|
* function.
|
|
* function.
|
|
*
|
|
*
|
|
|
|
+ * Returns zero on success, or -EFAULT on error.
|
|
|
|
+ * On error, the variable @x is set to zero.
|
|
|
|
+ */
|
|
|
|
+#define __get_user(x,ptr) \
|
|
|
|
+ __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
|
|
|
|
+
|
|
|
|
+#define __get_user_nocheck(x,ptr,size) \
|
|
|
|
+({ \
|
|
|
|
+ long __gu_err = 0; \
|
|
|
|
+ unsigned long __gu_val; \
|
|
|
|
+ might_sleep(); \
|
|
|
|
+ __get_user_size(__gu_val,(ptr),(size),__gu_err); \
|
|
|
|
+ (x) = (__typeof__(*(ptr)))__gu_val; \
|
|
|
|
+ __gu_err; \
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+#define __get_user_check(x,ptr,size) \
|
|
|
|
+({ \
|
|
|
|
+ long __gu_err = -EFAULT; \
|
|
|
|
+ unsigned long __gu_val = 0; \
|
|
|
|
+ const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
|
|
|
|
+ might_sleep(); \
|
|
|
|
+ if (access_ok(VERIFY_READ,__gu_addr,size)) \
|
|
|
|
+ __get_user_size(__gu_val,__gu_addr,(size),__gu_err); \
|
|
|
|
+ (x) = (__typeof__(*(ptr)))__gu_val; \
|
|
|
|
+ __gu_err; \
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+extern long __get_user_bad(void);
|
|
|
|
+
|
|
|
|
+#define __get_user_size(x,ptr,size,retval) \
|
|
|
|
+do { \
|
|
|
|
+ retval = 0; \
|
|
|
|
+ __chk_user_ptr(ptr); \
|
|
|
|
+ switch (size) { \
|
|
|
|
+ case 1: __get_user_asm(x,ptr,retval,"ub"); break; \
|
|
|
|
+ case 2: __get_user_asm(x,ptr,retval,"uh"); break; \
|
|
|
|
+ case 4: __get_user_asm(x,ptr,retval,""); break; \
|
|
|
|
+ default: (x) = __get_user_bad(); \
|
|
|
|
+ } \
|
|
|
|
+} while (0)
|
|
|
|
+
|
|
|
|
+#define __get_user_asm(x, addr, err, itype) \
|
|
|
|
+ __asm__ __volatile__( \
|
|
|
|
+ " .fillinsn\n" \
|
|
|
|
+ "1: ld"itype" %1,@%2\n" \
|
|
|
|
+ " .fillinsn\n" \
|
|
|
|
+ "2:\n" \
|
|
|
|
+ ".section .fixup,\"ax\"\n" \
|
|
|
|
+ " .balign 4\n" \
|
|
|
|
+ "3: ldi %0,%3\n" \
|
|
|
|
+ " seth r14,#high(2b)\n" \
|
|
|
|
+ " or3 r14,r14,#low(2b)\n" \
|
|
|
|
+ " jmp r14\n" \
|
|
|
|
+ ".previous\n" \
|
|
|
|
+ ".section __ex_table,\"a\"\n" \
|
|
|
|
+ " .balign 4\n" \
|
|
|
|
+ " .long 1b,3b\n" \
|
|
|
|
+ ".previous" \
|
|
|
|
+ : "=&r" (err), "=&r" (x) \
|