summaryrefslogtreecommitdiffstats
path: root/include/asm-alpha/uaccess.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-alpha/uaccess.h')
-rw-r--r--include/asm-alpha/uaccess.h57
1 files changed, 31 insertions, 26 deletions
diff --git a/include/asm-alpha/uaccess.h b/include/asm-alpha/uaccess.h
index a76b1fc38..5ab23c062 100644
--- a/include/asm-alpha/uaccess.h
+++ b/include/asm-alpha/uaccess.h
@@ -17,23 +17,18 @@
* For historical reasons, these macros are grossly misnamed.
*/
-#define KERNEL_DS (0UL)
-#define USER_DS (-0x40000000000UL)
+#define KERNEL_DS ((mm_segment_t) { 0UL })
+#define USER_DS ((mm_segment_t) { -0x40000000000UL })
#define VERIFY_READ 0
#define VERIFY_WRITE 1
#define get_fs() (current->tss.fs)
#define get_ds() (KERNEL_DS)
+#define set_fs(x) (current->tss.fs = (x))
-/* Our scheme relies on all bits being preserved. Trap those evil
- Intellists in their plot to use unsigned short. */
+#define segment_eq(a,b) ((a).seg == (b).seg)
-extern unsigned long __bad_fs_size(void);
-
-#define set_fs(x) (current->tss.fs = \
- sizeof(x) == sizeof(unsigned long) ? (x) \
- : __bad_fs_size())
/*
* Is a address valid? This does a straighforward calculation rather
@@ -45,12 +40,11 @@ extern unsigned long __bad_fs_size(void);
* - AND "addr+size" doesn't have any high-bits set
* - OR we are in kernel mode.
*/
-#define __access_ok(addr,size,mask) \
- (((mask) & (addr | size | (addr+size))) == 0)
-#define __access_mask get_fs()
+#define __access_ok(addr,size,segment) \
+ (((segment).seg & (addr | size | (addr+size))) == 0)
#define access_ok(type,addr,size) \
- __access_ok(((unsigned long)(addr)),(size),__access_mask)
+ __access_ok(((unsigned long)(addr)),(size),get_fs())
extern inline int verify_area(int type, const void * addr, unsigned long size)
{
@@ -70,9 +64,9 @@ extern inline int verify_area(int type, const void * addr, unsigned long size)
* (b) require any knowledge of processes at this stage
*/
#define put_user(x,ptr) \
- __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)),__access_mask)
+ __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)),get_fs())
#define get_user(x,ptr) \
- __get_user_check((x),(ptr),sizeof(*(ptr)),__access_mask)
+ __get_user_check((x),(ptr),sizeof(*(ptr)),get_fs())
/*
* The "__xxx" versions do not do address space checking, useful when
@@ -125,11 +119,11 @@ extern void __get_user_unknown(void);
__gu_err; \
})
-#define __get_user_check(x,ptr,size,mask) \
+#define __get_user_check(x,ptr,size,segment) \
({ \
long __gu_err = -EFAULT, __gu_val = 0; \
const __typeof__(*(ptr)) *__gu_addr = (ptr); \
- if (__access_ok((long)__gu_addr,size,mask)) { \
+ if (__access_ok((long)__gu_addr,size,segment)) { \
__gu_err = 0; \
switch (size) { \
case 1: __get_user_8(__gu_addr); break; \
@@ -238,11 +232,11 @@ extern void __put_user_unknown(void);
__pu_err; \
})
-#define __put_user_check(x,ptr,size,mask) \
+#define __put_user_check(x,ptr,size,segment) \
({ \
long __pu_err = -EFAULT; \
__typeof__(*(ptr)) *__pu_addr = (ptr); \
- if (__access_ok((long)__pu_addr,size,mask)) { \
+ if (__access_ok((long)__pu_addr,size,segment)) { \
__pu_err = 0; \
switch (size) { \
case 1: __put_user_8(x,__pu_addr); break; \
@@ -391,7 +385,7 @@ extern void __copy_user(void);
register void * __cu_to __asm__("$6") = (to); \
register const void * __cu_from __asm__("$7") = (from); \
register long __cu_len __asm__("$0") = (n); \
- if (__access_ok(((long)(v)),__cu_len,__access_mask)) { \
+ if (__access_ok(((long)(v)),__cu_len,get_fs())) { \
__asm__ __volatile__( \
"jsr $28,(%3),__copy_user" \
: "=r" (__cu_len), "=r" (__cu_from), "=r" (__cu_to) \
@@ -412,23 +406,34 @@ if (copy_from_user(to,from,n)) \
return retval; \
})
-extern void __clear_user(void);
+extern void __do_clear_user(void);
+
+#define __clear_user(to,n) \
+({ \
+ register void * __cl_to __asm__("$6") = (to); \
+ register long __cl_len __asm__("$0") = (n); \
+ __asm__ __volatile__( \
+ "jsr $28,(%2),__do_clear_user" \
+ : "=r"(__cl_len), "=r"(__cl_to) \
+ : "r"(__do_clear_user), "0"(__cl_len), "1"(__cl_to) \
+ : "$1","$2","$3","$4","$5","$28","memory"); \
+ __cl_len; \
+})
#define clear_user(to,n) \
({ \
register void * __cl_to __asm__("$6") = (to); \
register long __cl_len __asm__("$0") = (n); \
- if (__access_ok(((long)__cl_to),__cl_len,__access_mask)) { \
+ if (__access_ok(((long)__cl_to),__cl_len,get_fs())) { \
__asm__ __volatile__( \
- "jsr $28,(%2),__clear_user" \
+ "jsr $28,(%2),__do_clear_user" \
: "=r"(__cl_len), "=r"(__cl_to) \
- : "r"(__clear_user), "0"(__cl_len), "1"(__cl_to)\
+ : "r"(__do_clear_user), "0"(__cl_len), "1"(__cl_to)\
: "$1","$2","$3","$4","$5","$28","memory"); \
} \
__cl_len; \
})
-
/* Returns: -EFAULT if exception before terminator, N if the entire
buffer filled, else strlen. */
@@ -439,7 +444,7 @@ extern long __strncpy_from_user(char *__to, const char *__from, long __to_len);
char * __sfu_to = (to); \
const char * __sfu_from = (from); \
long __sfu_ret = -EFAULT; \
- if (__access_ok(((long)__sfu_from),0,__access_mask)) \
+ if (__access_ok(((long)__sfu_from),0,get_fs())) \
__sfu_ret = __strncpy_from_user(__sfu_to,__sfu_from,(n)); \
__sfu_ret; \
})