|
@@ -271,3 +271,65 @@ do { \
|
|
|
" .popsection" \
|
|
|
: "+r" (err), "=&r" (x) \
|
|
|
: "r" (addr), "i" (-EFAULT) \
|
|
|
+ : "cc")
|
|
|
+
|
|
|
+#ifndef __ARMEB__
|
|
|
+#define __get_user_asm_half(x,__gu_addr,err) \
|
|
|
+({ \
|
|
|
+ unsigned long __b1, __b2; \
|
|
|
+ __get_user_asm_byte(__b1, __gu_addr, err); \
|
|
|
+ __get_user_asm_byte(__b2, __gu_addr + 1, err); \
|
|
|
+ (x) = __b1 | (__b2 << 8); \
|
|
|
+})
|
|
|
+#else
|
|
|
+#define __get_user_asm_half(x,__gu_addr,err) \
|
|
|
+({ \
|
|
|
+ unsigned long __b1, __b2; \
|
|
|
+ __get_user_asm_byte(__b1, __gu_addr, err); \
|
|
|
+ __get_user_asm_byte(__b2, __gu_addr + 1, err); \
|
|
|
+ (x) = (__b1 << 8) | __b2; \
|
|
|
+})
|
|
|
+#endif
|
|
|
+
|
|
|
+#define __get_user_asm_word(x,addr,err) \
|
|
|
+ __asm__ __volatile__( \
|
|
|
+ "1: " TUSER(ldr) " %1,[%2],#0\n" \
|
|
|
+ "2:\n" \
|
|
|
+ " .pushsection .fixup,\"ax\"\n" \
|
|
|
+ " .align 2\n" \
|
|
|
+ "3: mov %0, %3\n" \
|
|
|
+ " mov %1, #0\n" \
|
|
|
+ " b 2b\n" \
|
|
|
+ " .popsection\n" \
|
|
|
+ " .pushsection __ex_table,\"a\"\n" \
|
|
|
+ " .align 3\n" \
|
|
|
+ " .long 1b, 3b\n" \
|
|
|
+ " .popsection" \
|
|
|
+ : "+r" (err), "=&r" (x) \
|
|
|
+ : "r" (addr), "i" (-EFAULT) \
|
|
|
+ : "cc")
|
|
|
+
|
|
|
+#define __put_user(x,ptr) \
|
|
|
+({ \
|
|
|
+ long __pu_err = 0; \
|
|
|
+ __put_user_err((x),(ptr),__pu_err); \
|
|
|
+ __pu_err; \
|
|
|
+})
|
|
|
+
|
|
|
+#define __put_user_error(x,ptr,err) \
|
|
|
+({ \
|
|
|
+ __put_user_err((x),(ptr),err); \
|
|
|
+ (void) 0; \
|
|
|
+})
|
|
|
+
|
|
|
+#define __put_user_err(x,ptr,err) \
|
|
|
+do { \
|
|
|
+ unsigned long __pu_addr = (unsigned long)(ptr); \
|
|
|
+ __typeof__(*(ptr)) __pu_val = (x); \
|
|
|
+ __chk_user_ptr(ptr); \
|
|
|
+ might_fault(); \
|
|
|
+ switch (sizeof(*(ptr))) { \
|
|
|
+ case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \
|
|
|
+ case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \
|
|
|
+ case 4: __put_user_asm_word(__pu_val,__pu_addr,err); break; \
|
|
|
+ case 8: __put_user_asm_dword(__pu_val,__pu_addr,err); break; \
|