Commit 235944be authored by Russell King's avatar Russell King

[ARM] Fix up {__,}put_user macros

- Make them work on 64-bit quantities
- clean up use of local pointers to prevent multiple references
  to the pointer (which may have side effects.)

Note that this causes __put_user to produce a warning each time
a pointer is passed as the first argument, since the 64-bit
implementation tries to cast a 32-bit pointer to a 64-bit long.

The fix for this warning waiting for comments from the GCC
community.
parent 3e393f8f
...@@ -37,7 +37,7 @@ static inline void set_fs (mm_segment_t fs) ...@@ -37,7 +37,7 @@ static inline void set_fs (mm_segment_t fs)
: "cc"); \ : "cc"); \
(flag == 0); }) (flag == 0); })
#define __put_user_asm_byte(x,addr,err) \ #define __put_user_asm_byte(x,__pu_addr,err) \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: strbt %1,[%2],#0\n" \ "1: strbt %1,[%2],#0\n" \
"2:\n" \ "2:\n" \
...@@ -51,27 +51,26 @@ static inline void set_fs (mm_segment_t fs) ...@@ -51,27 +51,26 @@ static inline void set_fs (mm_segment_t fs)
" .long 1b, 3b\n" \ " .long 1b, 3b\n" \
" .previous" \ " .previous" \
: "=r" (err) \ : "=r" (err) \
: "r" (x), "r" (addr), "i" (-EFAULT), "0" (err)) : "r" (x), "r" (__pu_addr), "i" (-EFAULT), "0" (err) \
: "cc")
#ifndef __ARMEB__ #ifndef __ARMEB__
#define __put_user_asm_half(x,addr,err) \ #define __put_user_asm_half(x,__pu_addr,err) \
({ \ ({ \
unsigned long __temp = (unsigned long)(x); \ unsigned long __temp = (unsigned long)(x); \
unsigned long __ptr = (unsigned long)(addr); \ __put_user_asm_byte(__temp, __pu_addr, err); \
__put_user_asm_byte(__temp, __ptr, err); \ __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \
__put_user_asm_byte(__temp >> 8, __ptr + 1, err); \
}) })
#else #else
#define __put_user_asm_half(x,addr,err) \ #define __put_user_asm_half(x,__pu_addr,err) \
({ \ ({ \
unsigned long __temp = (unsigned long)(x); \ unsigned long __temp = (unsigned long)(x); \
unsigned long __ptr = (unsigned long)(addr); \ __put_user_asm_byte(__temp >> 8, __pu_addr, err); \
__put_user_asm_byte(__temp >> 8, __ptr, err); \ __put_user_asm_byte(__temp, __pu_addr + 1, err); \
__put_user_asm_byte(__temp, __ptr + 1, err); \
}) })
#endif #endif
#define __put_user_asm_word(x,addr,err) \ #define __put_user_asm_word(x,__pu_addr,err) \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: strt %1,[%2],#0\n" \ "1: strt %1,[%2],#0\n" \
"2:\n" \ "2:\n" \
...@@ -85,7 +84,31 @@ static inline void set_fs (mm_segment_t fs) ...@@ -85,7 +84,31 @@ static inline void set_fs (mm_segment_t fs)
" .long 1b, 3b\n" \ " .long 1b, 3b\n" \
" .previous" \ " .previous" \
: "=r" (err) \ : "=r" (err) \
: "r" (x), "r" (addr), "i" (-EFAULT), "0" (err)) : "r" (x), "r" (__pu_addr), "i" (-EFAULT), "0" (err))
#define __put_user_asm_dword(x,__pu_addr,err) \
({ \
unsigned long long __temp = (unsigned long long)x; \
__asm__ __volatile__( \
"1: strt %1, [%2], #0\n" \
"2: strt %3, [%4], #0\n" \
"3:\n" \
" .section .fixup,\"ax\"\n" \
" .align 2\n" \
"4: mov %0, %5\n" \
" b 3b\n" \
" .previous\n" \
" .section __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 4b\n" \
" .long 2b, 4b\n" \
" .previous" \
: "=r" (err) \
: "r" (__temp), "r" (__pu_addr), \
"r" (__temp >> 32), "r" (__pu_addr + 4), \
"i" (-EFAULT), "0" (err) \
: "cc"); \
})
#define __get_user_asm_byte(x,addr,err) \ #define __get_user_asm_byte(x,addr,err) \
__asm__ __volatile__( \ __asm__ __volatile__( \
......
...@@ -81,7 +81,7 @@ extern int __get_user_bad(void); ...@@ -81,7 +81,7 @@ extern int __get_user_bad(void);
const register typeof(*(p)) *__p asm("r0") = (p); \ const register typeof(*(p)) *__p asm("r0") = (p); \
register typeof(*(p)) __r1 asm("r1"); \ register typeof(*(p)) __r1 asm("r1"); \
register int __e asm("r0"); \ register int __e asm("r0"); \
switch (sizeof(*(p))) { \ switch (sizeof(*(__p))) { \
case 1: \ case 1: \
__get_user_x(__r1, __p, __e, 1, "lr"); \ __get_user_x(__r1, __p, __e, 1, "lr"); \
break; \ break; \
...@@ -120,7 +120,7 @@ extern int __put_user_bad(void); ...@@ -120,7 +120,7 @@ extern int __put_user_bad(void);
const register typeof(*(p)) __r1 asm("r1") = (x); \ const register typeof(*(p)) __r1 asm("r1") = (x); \
const register typeof(*(p)) *__p asm("r0") = (p); \ const register typeof(*(p)) *__p asm("r0") = (p); \
register int __e asm("r0"); \ register int __e asm("r0"); \
switch (sizeof(*(p))) { \ switch (sizeof(*(__p))) { \
case 1: \ case 1: \
__put_user_x(__r1, __p, __e, 1, "r2", "lr"); \ __put_user_x(__r1, __p, __e, 1, "r2", "lr"); \
break; \ break; \
...@@ -256,14 +256,15 @@ static inline long strnlen_user(const char *s, long n) ...@@ -256,14 +256,15 @@ static inline long strnlen_user(const char *s, long n)
#define __put_user_nocheck(x,ptr,size) \ #define __put_user_nocheck(x,ptr,size) \
({ \ ({ \
long __pu_err = 0; \ long __pu_err = 0; \
__typeof__(*(ptr)) *__pu_addr = (ptr); \ unsigned long __pu_addr = (unsigned long)(ptr); \
__put_user_size((x),__pu_addr,(size),__pu_err); \ __put_user_size((x),__pu_addr,(size),__pu_err); \
__pu_err; \ __pu_err; \
}) })
#define __put_user_nocheck_error(x,ptr,size,err) \ #define __put_user_nocheck_error(x,ptr,size,err) \
({ \ ({ \
__put_user_size((x),(ptr),(size),err); \ unsigned long __pu_addr = (unsigned long)(ptr); \
__put_user_size((x),__pu_addr,(size),err); \
(void) 0; \ (void) 0; \
}) })
...@@ -273,6 +274,7 @@ do { \ ...@@ -273,6 +274,7 @@ do { \
case 1: __get_user_asm_byte(x,ptr,retval); break; \ case 1: __get_user_asm_byte(x,ptr,retval); break; \
case 2: __get_user_asm_half(x,ptr,retval); break; \ case 2: __get_user_asm_half(x,ptr,retval); break; \
case 4: __get_user_asm_word(x,ptr,retval); break; \ case 4: __get_user_asm_word(x,ptr,retval); break; \
case 8: __get_user_asm_dword(x,ptr,retval); break; \
default: (x) = __get_user_bad(); \ default: (x) = __get_user_bad(); \
} \ } \
} while (0) } while (0)
...@@ -283,6 +285,7 @@ do { \ ...@@ -283,6 +285,7 @@ do { \
case 1: __put_user_asm_byte(x,ptr,retval); break; \ case 1: __put_user_asm_byte(x,ptr,retval); break; \
case 2: __put_user_asm_half(x,ptr,retval); break; \ case 2: __put_user_asm_half(x,ptr,retval); break; \
case 4: __put_user_asm_word(x,ptr,retval); break; \ case 4: __put_user_asm_word(x,ptr,retval); break; \
case 8: __put_user_asm_dword(x,ptr,retval); break; \
default: __put_user_bad(); \ default: __put_user_bad(); \
} \ } \
} while (0) } while (0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment