]> err.no Git - linux-2.6/commitdiff
powerpc: merge uaccess.h
authorStephen Rothwell <sfr@canb.auug.org.au>
Sat, 29 Oct 2005 07:51:31 +0000 (17:51 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Tue, 1 Nov 2005 03:34:03 +0000 (14:34 +1100)
There is still a bug to be fixed and more merging to be done.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
include/asm-powerpc/uaccess.h [new file with mode: 0644]
include/asm-ppc/uaccess.h [deleted file]
include/asm-ppc64/uaccess.h [deleted file]

diff --git a/include/asm-powerpc/uaccess.h b/include/asm-powerpc/uaccess.h
new file mode 100644 (file)
index 0000000..2ecc3e1
--- /dev/null
@@ -0,0 +1,504 @@
+#ifndef _ARCH_POWERPC_UACCESS_H
+#define _ARCH_POWERPC_UACCESS_H
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <asm/processor.h>
+
+#define VERIFY_READ    0
+#define VERIFY_WRITE   1
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not.  If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ *
+ * The fs/ds values are now the highest legal address in the "segment".
+ * This simplifies the checking in the routines below.
+ */
+
+#define MAKE_MM_SEG(s)  ((mm_segment_t) { (s) })
+
+#ifdef __powerpc64__
+#define KERNEL_DS      MAKE_MM_SEG(0UL)
+#define USER_DS                MAKE_MM_SEG(0xf000000000000000UL)
+#else
+#define KERNEL_DS      MAKE_MM_SEG(~0UL)
+#define USER_DS                MAKE_MM_SEG(TASK_SIZE - 1)
+#endif
+
+#define get_ds()       (KERNEL_DS)
+#define get_fs()       (current->thread.fs)
+#define set_fs(val)    (current->thread.fs = (val))
+
+#define segment_eq(a, b)       ((a).seg == (b).seg)
+
+#ifdef __powerpc64__
+/*
+ * Use the alpha trick for checking ranges:
+ *
+ * Is a address valid? This does a straightforward calculation rather
+ * than tests.
+ *
+ * Address valid if:
+ *  - "addr" doesn't have any high-bits set
+ *  - AND "size" doesn't have any high-bits set
+ *  - OR we are in kernel mode.
+ *
+ * We dont have to check for high bits in (addr+size) because the first
+ * two checks force the maximum result to be below the start of the
+ * kernel region.
+ */
+#define __access_ok(addr, size, segment)       \
+       (((segment).seg & (addr | size )) == 0)
+
+#else
+
+#define __access_ok(addr, size, segment)       \
+       (((addr) <= (segment).seg) &&           \
+        (((size) == 0) || (((size) - 1) <= ((segment).seg - (addr)))))
+
+#endif
+
+#define access_ok(type, addr, size)            \
+       (__chk_user_ptr(addr),                  \
+        __access_ok((__force unsigned long)(addr), (size), get_fs()))
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry {
+       unsigned long insn;
+       unsigned long fixup;
+};
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ *
+ * This gets kind of ugly. We want to return _two_ values in "get_user()"
+ * and yet we don't want to do any pointers, because that is too much
+ * of a performance impact. Thus we have a few rather ugly macros here,
+ * and hide all the ugliness from the user.
+ *
+ * The "__xxx" versions of the user access functions are versions that
+ * do not verify the address space, that must have been done previously
+ * with a separate "access_ok()" call (this is used when we do multiple
+ * accesses to the same area of user memory).
+ *
+ * As we use the same address space for kernel and user data on the
+ * PowerPC, we can just do these as direct assignments.  (Of course, the
+ * exception handling means that it's no longer "just"...)
+ *
+ * The "user64" versions of the user access functions are versions that
+ * allow access of 64-bit data. The "get_user" functions do not
+ * properly handle 64-bit data because the value gets down cast to a long.
+ * The "put_user" functions already handle 64-bit data properly but we add
+ * "user64" versions for completeness
+ */
+#define get_user(x, ptr) \
+       __get_user_check((x), (ptr), sizeof(*(ptr)))
+#define put_user(x, ptr) \
+       __put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
+
+#define __get_user(x, ptr) \
+       __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+#define __put_user(x, ptr) \
+       __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
+#ifndef __powerpc64__
+#define __get_user64(x, ptr) \
+       __get_user64_nocheck((x), (ptr), sizeof(*(ptr)))
+#define __put_user64(x, ptr) __put_user(x, ptr)
+#endif
+
+#ifdef __powerpc64__
+#define __get_user_unaligned __get_user
+#define __put_user_unaligned __put_user
+#endif
+
+extern long __put_user_bad(void);
+
+#ifdef __powerpc64__
+#define __EX_TABLE_ALIGN       "3"
+#define __EX_TABLE_TYPE                "llong"
+#else
+#define __EX_TABLE_ALIGN       "2"
+#define __EX_TABLE_TYPE                "long"
+#endif
+
+/*
+ * We don't tell gcc that we are accessing memory, but this is OK
+ * because we do not write to any memory gcc knows about, so there
+ * are no aliasing issues.
+ */
+#define __put_user_asm(x, addr, err, op)                       \
+       __asm__ __volatile__(                                   \
+               "1:     " op " %1,0(%2) # put_user\n"           \
+               "2:\n"                                          \
+               ".section .fixup,\"ax\"\n"                      \
+               "3:     li %0,%3\n"                             \
+               "       b 2b\n"                                 \
+               ".previous\n"                                   \
+               ".section __ex_table,\"a\"\n"                   \
+               "       .align " __EX_TABLE_ALIGN "\n"          \
+               "       ."__EX_TABLE_TYPE" 1b,3b\n"             \
+               ".previous"                                     \
+               : "=r" (err)                                    \
+               : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
+
+#ifndef __powerpc64__
+#define __put_user_asm2(x, addr, err)                          \
+       __asm__ __volatile__(                                   \
+               "1:     stw %1,0(%2)\n"                         \
+               "2:     stw %1+1,4(%2)\n"                       \
+               "3:\n"                                          \
+               ".section .fixup,\"ax\"\n"                      \
+               "4:     li %0,%3\n"                             \
+               "       b 3b\n"                                 \
+               ".previous\n"                                   \
+               ".section __ex_table,\"a\"\n"                   \
+               "       .align " __EX_TABLE_ALIGN "\n"          \
+               "       ." __EX_TABLE_TYPE " 1b,4b\n"           \
+               "       ." __EX_TABLE_TYPE " 2b,4b\n"           \
+               ".previous"                                     \
+               : "=r" (err)                                    \
+               : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
+#else /* __powerpc64__ */
+#define __put_user_asm2(x, ptr, retval)                                \
+         __put_user_asm(x, ptr, retval, "std")
+#endif /* __powerpc64__ */
+
+#define __put_user_size(x, ptr, size, retval)                  \
+do {                                                           \
+       retval = 0;                                             \
+       switch (size) {                                         \
+         case 1: __put_user_asm(x, ptr, retval, "stb"); break; \
+         case 2: __put_user_asm(x, ptr, retval, "sth"); break; \
+         case 4: __put_user_asm(x, ptr, retval, "stw"); break; \
+         case 8: __put_user_asm2(x, ptr, retval); break;       \
+         default: __put_user_bad();                            \
+       }                                                       \
+} while (0)
+
+#define __put_user_nocheck(x, ptr, size)                       \
+({                                                             \
+       long __pu_err;                                          \
+       might_sleep();                                          \
+       __chk_user_ptr(ptr);                                    \
+       __put_user_size((x), (ptr), (size), __pu_err);          \
+       __pu_err;                                               \
+})
+
+#define __put_user_check(x, ptr, size)                                 \
+({                                                                     \
+       long __pu_err = -EFAULT;                                        \
+       __typeof__(*(ptr)) __user *__pu_addr = (ptr);                   \
+       might_sleep();                                                  \
+       if (access_ok(VERIFY_WRITE, __pu_addr, size))                   \
+               __put_user_size((x), __pu_addr, (size), __pu_err);      \
+       __pu_err;                                                       \
+})
+
+extern long __get_user_bad(void);
+
+#define __get_user_asm(x, addr, err, op)               \
+       __asm__ __volatile__(                           \
+               "1:     "op" %1,0(%2)   # get_user\n"   \
+               "2:\n"                                  \
+               ".section .fixup,\"ax\"\n"              \
+               "3:     li %0,%3\n"                     \
+               "       li %1,0\n"                      \
+               "       b 2b\n"                         \
+               ".previous\n"                           \
+               ".section __ex_table,\"a\"\n"           \
+               "       .align "__EX_TABLE_ALIGN "\n"   \
+               "       ." __EX_TABLE_TYPE " 1b,3b\n"   \
+               ".previous"                             \
+               : "=r" (err), "=r" (x)                  \
+               : "b" (addr), "i" (-EFAULT), "0" (err))
+
+#ifndef __powerpc64__
+#define __get_user_asm2(x, addr, err)                  \
+       __asm__ __volatile__(                           \
+               "1:     lwz %1,0(%2)\n"                 \
+               "2:     lwz %1+1,4(%2)\n"               \
+               "3:\n"                                  \
+               ".section .fixup,\"ax\"\n"              \
+               "4:     li %0,%3\n"                     \
+               "       li %1,0\n"                      \
+               "       li %1+1,0\n"                    \
+               "       b 3b\n"                         \
+               ".previous\n"                           \
+               ".section __ex_table,\"a\"\n"           \
+               "       .align " __EX_TABLE_ALIGN "\n"  \
+               "       ." __EX_TABLE_TYPE " 1b,4b\n"   \
+               "       ." __EX_TABLE_TYPE " 2b,4b\n"   \
+               ".previous"                             \
+               : "=r" (err), "=&r" (x)                 \
+               : "b" (addr), "i" (-EFAULT), "0" (err))
+#else
+#define __get_user_asm2(x, addr, err)                  \
+       __get_user_asm(x, addr, err, "ld")
+#endif /* __powerpc64__ */
+
+#define __get_user_size(x, ptr, size, retval)                  \
+do {                                                           \
+       retval = 0;                                             \
+       __chk_user_ptr(ptr);                                    \
+       if (size > sizeof(x))                                   \
+               (x) = __get_user_bad();                         \
+       switch (size) {                                         \
+       case 1: __get_user_asm(x, ptr, retval, "lbz"); break;   \
+       case 2: __get_user_asm(x, ptr, retval, "lhz"); break;   \
+       case 4: __get_user_asm(x, ptr, retval, "lwz"); break;   \
+       case 8: __get_user_asm2(x, ptr, retval);  break;        \
+       default: (x) = __get_user_bad();                        \
+       }                                                       \
+} while (0)
+
+#define __get_user_nocheck(x, ptr, size)                       \
+({                                                             \
+       long __gu_err;                                          \
+       unsigned long __gu_val;                                 \
+       __chk_user_ptr(ptr);                                    \
+       might_sleep();                                          \
+       __get_user_size(__gu_val, (ptr), (size), __gu_err);     \
+       (x) = (__typeof__(*(ptr)))__gu_val;                     \
+       __gu_err;                                               \
+})
+
+#ifndef __powerpc64__
+#define __get_user64_nocheck(x, ptr, size)                     \
+({                                                             \
+       long __gu_err;                                          \
+       long long __gu_val;                                     \
+       __chk_user_ptr(ptr);                                    \
+       might_sleep();                                          \
+       __get_user_size(__gu_val, (ptr), (size), __gu_err);     \
+       (x) = (__typeof__(*(ptr)))__gu_val;                     \
+       __gu_err;                                               \
+})
+#endif /* __powerpc64__ */
+
+#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;                                                       \
+})
+
+/* more complex routines */
+
+extern unsigned long __copy_tofrom_user(void __user *to,
+               const void __user *from, unsigned long size);
+
+#ifndef __powerpc64__
+extern inline unsigned long
+copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+       unsigned long over;
+
+       if (access_ok(VERIFY_READ, from, n))
+               return __copy_tofrom_user((__force void __user *)to, from, n);
+       if ((unsigned long)from < TASK_SIZE) {
+               over = (unsigned long)from + n - TASK_SIZE;
+               return __copy_tofrom_user((__force void __user *)to, from,
+                               n - over) + over;
+       }
+       return n;
+}
+
+extern inline unsigned long
+copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+       unsigned long over;
+
+       if (access_ok(VERIFY_WRITE, to, n))
+               return __copy_tofrom_user(to, (__force void __user *)from, n);
+       if ((unsigned long)to < TASK_SIZE) {
+               over = (unsigned long)to + n - TASK_SIZE;
+               return __copy_tofrom_user(to, (__force void __user *)from,
+                               n - over) + over;
+       }
+       return n;
+}
+
+#else /* __powerpc64__ */
+
+static inline unsigned long
+__copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
+{
+       if (__builtin_constant_p(n) && (n <= 8)) {
+               unsigned long ret;
+
+               switch (n) {
+               case 1:
+                       __get_user_size(*(u8 *)to, from, 1, ret);
+                       break;
+               case 2:
+                       __get_user_size(*(u16 *)to, from, 2, ret);
+                       break;
+               case 4:
+                       __get_user_size(*(u32 *)to, from, 4, ret);
+                       break;
+               case 8:
+                       __get_user_size(*(u64 *)to, from, 8, ret);
+                       break;
+               }
+               return (ret == -EFAULT) ? n : 0;
+       }
+       return __copy_tofrom_user((__force void __user *) to, from, n);
+}
+
+static inline unsigned long
+__copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
+{
+       if (__builtin_constant_p(n) && (n <= 8)) {
+               unsigned long ret;
+
+               switch (n) {
+               case 1:
+                       __put_user_size(*(u8 *)from, (u8 __user *)to, 1, ret);
+                       break;
+               case 2:
+                       __put_user_size(*(u16 *)from, (u16 __user *)to, 2, ret);
+                       break;
+               case 4:
+                       __put_user_size(*(u32 *)from, (u32 __user *)to, 4, ret);
+                       break;
+               case 8:
+                       __put_user_size(*(u64 *)from, (u64 __user *)to, 8, ret);
+                       break;
+               }
+               return (ret == -EFAULT) ? n : 0;
+       }
+       return __copy_tofrom_user(to, (__force const void __user *) from, n);
+}
+
+#endif /* __powerpc64__ */
+
+static inline unsigned long
+__copy_from_user(void *to, const void __user *from, unsigned long size)
+{
+       might_sleep();
+#ifndef __powerpc64__
+       return __copy_tofrom_user((__force void __user *)to, from, size);
+#else /* __powerpc64__ */
+       return __copy_from_user_inatomic(to, from, size);
+#endif /* __powerpc64__ */
+}
+
+static inline unsigned long
+__copy_to_user(void __user *to, const void *from, unsigned long size)
+{
+       might_sleep();
+#ifndef __powerpc64__
+       return __copy_tofrom_user(to, (__force void __user *)from, size);
+#else /* __powerpc64__ */
+       return __copy_to_user_inatomic(to, from, size);
+#endif /* __powerpc64__ */
+}
+
+#ifndef __powerpc64__
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+#else /* __powerpc64__ */
+#define __copy_in_user(to, from, size) \
+       __copy_tofrom_user((to), (from), (size))
+
+extern unsigned long copy_from_user(void *to, const void __user *from,
+                                   unsigned long n);
+extern unsigned long copy_to_user(void __user *to, const void *from,
+                                 unsigned long n);
+extern unsigned long copy_in_user(void __user *to, const void __user *from,
+                                 unsigned long n);
+#endif /* __powerpc64__ */
+
+extern unsigned long __clear_user(void __user *addr, unsigned long size);
+
+static inline unsigned long clear_user(void __user *addr, unsigned long size)
+{
+       might_sleep();
+       if (likely(access_ok(VERIFY_WRITE, addr, size)))
+               return __clear_user(addr, size);
+#ifndef __powerpc64__
+       if ((unsigned long)addr < TASK_SIZE) {
+               unsigned long over = (unsigned long)addr + size - TASK_SIZE;
+               return __clear_user(addr, size - over) + over;
+       }
+#endif /* __powerpc64__ */
+       return size;
+}
+
+extern int __strncpy_from_user(char *dst, const char __user *src, long count);
+
+static inline long strncpy_from_user(char *dst, const char __user *src,
+               long count)
+{
+       might_sleep();
+       if (likely(access_ok(VERIFY_READ, src, 1)))
+               return __strncpy_from_user(dst, src, count);
+       return -EFAULT;
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error
+ */
+#ifndef __powerpc64__
+extern int __strnlen_user(const char __user *str, long len, unsigned long top);
+#else /* __powerpc64__ */
+extern int __strnlen_user(const char __user *str, long len);
+#endif /* __powerpc64__ */
+
+/*
+ * Returns the length of the string at str (including the null byte),
+ * or 0 if we hit a page we can't access,
+ * or something > len if we didn't find a null byte.
+ *
+ * The `top' parameter to __strnlen_user is to make sure that
+ * we can never overflow from the user area into kernel space.
+ */
+static inline int strnlen_user(const char __user *str, long len)
+{
+#ifndef __powerpc64__
+       unsigned long top = current->thread.fs.seg;
+
+       if ((unsigned long)str > top)
+               return 0;
+       return __strnlen_user(str, len, top);
+#else /* __powerpc64__ */
+       might_sleep();
+       if (likely(access_ok(VERIFY_READ, str, 1)))
+               return __strnlen_user(str, len);
+       return 0;
+#endif /* __powerpc64__ */
+}
+
+#define strlen_user(str)       strnlen_user((str), 0x7ffffffe)
+
+#endif  /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+
+#endif /* _ARCH_POWERPC_UACCESS_H */
diff --git a/include/asm-ppc/uaccess.h b/include/asm-ppc/uaccess.h
deleted file mode 100644 (file)
index 63f5622..0000000
+++ /dev/null
@@ -1,393 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _PPC_UACCESS_H
-#define _PPC_UACCESS_H
-
-#ifndef __ASSEMBLY__
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <asm/processor.h>
-
-#define VERIFY_READ    0
-#define VERIFY_WRITE   1
-
-/*
- * The fs value determines whether argument validity checking should be
- * performed or not.  If get_fs() == USER_DS, checking is performed, with
- * get_fs() == KERNEL_DS, checking is bypassed.
- *
- * For historical reasons, these macros are grossly misnamed.
- *
- * The fs/ds values are now the highest legal address in the "segment".
- * This simplifies the checking in the routines below.
- */
-
-#define KERNEL_DS      ((mm_segment_t) { ~0UL })
-#define USER_DS                ((mm_segment_t) { TASK_SIZE - 1 })
-
-#define get_ds()       (KERNEL_DS)
-#define get_fs()       (current->thread.fs)
-#define set_fs(val)    (current->thread.fs = (val))
-
-#define segment_eq(a,b)        ((a).seg == (b).seg)
-
-#define __access_ok(addr,size)                                             \
-       ((addr) <= current->thread.fs.seg                                   \
-        && ((size) == 0 || (size) - 1 <= current->thread.fs.seg - (addr)))
-
-#define access_ok(type, addr, size) \
-       (__chk_user_ptr(addr),__access_ok((unsigned long)(addr),(size)))
-
-/*
- * The exception table consists of pairs of addresses: the first is the
- * address of an instruction that is allowed to fault, and the second is
- * the address at which the program should continue.  No registers are
- * modified, so it is entirely up to the continuation code to figure out
- * what to do.
- *
- * All the routines below use bits of fixup code that are out of line
- * with the main instruction path.  This means when everything is well,
- * we don't even have to jump over them.  Further, they do not intrude
- * on our cache or tlb entries.
- */
-
-struct exception_table_entry
-{
-       unsigned long insn, fixup;
-};
-
-/*
- * These are the main single-value transfer routines.  They automatically
- * use the right size if we just have the right pointer type.
- *
- * This gets kind of ugly. We want to return _two_ values in "get_user()"
- * and yet we don't want to do any pointers, because that is too much
- * of a performance impact. Thus we have a few rather ugly macros here,
- * and hide all the ugliness from the user.
- *
- * The "__xxx" versions of the user access functions are versions that
- * do not verify the address space, that must have been done previously
- * with a separate "access_ok()" call (this is used when we do multiple
- * accesses to the same area of user memory).
- *
- * As we use the same address space for kernel and user data on the
- * PowerPC, we can just do these as direct assignments.  (Of course, the
- * exception handling means that it's no longer "just"...)
- *
- * The "user64" versions of the user access functions are versions that 
- * allow access of 64-bit data. The "get_user" functions do not 
- * properly handle 64-bit data because the value gets down cast to a long. 
- * The "put_user" functions already handle 64-bit data properly but we add 
- * "user64" versions for completeness
- */
-#define get_user(x,ptr) \
-  __get_user_check((x),(ptr),sizeof(*(ptr)))
-#define get_user64(x,ptr) \
-  __get_user64_check((x),(ptr),sizeof(*(ptr)))
-#define put_user(x,ptr) \
-  __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
-#define put_user64(x,ptr) put_user(x,ptr)
-
-#define __get_user(x,ptr) \
-  __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
-#define __get_user64(x,ptr) \
-  __get_user64_nocheck((x),(ptr),sizeof(*(ptr)))
-#define __put_user(x,ptr) \
-  __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
-#define __put_user64(x,ptr) __put_user(x,ptr)
-
-extern long __put_user_bad(void);
-
-#define __put_user_nocheck(x,ptr,size)                 \
-({                                                     \
-       long __pu_err;                                  \
-       __chk_user_ptr(ptr);                            \
-       __put_user_size((x),(ptr),(size),__pu_err);     \
-       __pu_err;                                       \
-})
-
-#define __put_user_check(x,ptr,size)                           \
-({                                                             \
-       long __pu_err = -EFAULT;                                \
-       __typeof__(*(ptr)) __user *__pu_addr = (ptr);           \
-       if (access_ok(VERIFY_WRITE,__pu_addr,size))             \
-               __put_user_size((x),__pu_addr,(size),__pu_err); \
-       __pu_err;                                               \
-})
-
-#define __put_user_size(x,ptr,size,retval)             \
-do {                                                   \
-       retval = 0;                                     \
-       switch (size) {                                 \
-       case 1:                                         \
-               __put_user_asm(x, ptr, retval, "stb");  \
-               break;                                  \
-       case 2:                                         \
-               __put_user_asm(x, ptr, retval, "sth");  \
-               break;                                  \
-       case 4:                                         \
-               __put_user_asm(x, ptr, retval, "stw");  \
-               break;                                  \
-       case 8:                                         \
-               __put_user_asm2(x, ptr, retval);        \
-               break;                                  \
-       default:                                        \
-               __put_user_bad();                       \
-       }                                               \
-} while (0)
-
-/*
- * We don't tell gcc that we are accessing memory, but this is OK
- * because we do not write to any memory gcc knows about, so there
- * are no aliasing issues.
- */
-#define __put_user_asm(x, addr, err, op)                       \
-       __asm__ __volatile__(                                   \
-               "1:     "op" %1,0(%2)\n"                        \
-               "2:\n"                                          \
-               ".section .fixup,\"ax\"\n"                      \
-               "3:     li %0,%3\n"                             \
-               "       b 2b\n"                                 \
-               ".previous\n"                                   \
-               ".section __ex_table,\"a\"\n"                   \
-               "       .align 2\n"                             \
-               "       .long 1b,3b\n"                          \
-               ".previous"                                     \
-               : "=r" (err)                                    \
-               : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
-
-#define __put_user_asm2(x, addr, err)                          \
-       __asm__ __volatile__(                                   \
-               "1:     stw %1,0(%2)\n"                         \
-               "2:     stw %1+1,4(%2)\n"                       \
-               "3:\n"                                          \
-               ".section .fixup,\"ax\"\n"                      \
-               "4:     li %0,%3\n"                             \
-               "       b 3b\n"                                 \
-               ".previous\n"                                   \
-               ".section __ex_table,\"a\"\n"                   \
-               "       .align 2\n"                             \
-               "       .long 1b,4b\n"                          \
-               "       .long 2b,4b\n"                          \
-               ".previous"                                     \
-               : "=r" (err)                                    \
-               : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
-
-#define __get_user_nocheck(x, ptr, size)                       \
-({                                                             \
-       long __gu_err;                                          \
-       unsigned long __gu_val;                                 \
-       __chk_user_ptr(ptr);                                    \
-       __get_user_size(__gu_val, (ptr), (size), __gu_err);     \
-       (x) = (__typeof__(*(ptr)))__gu_val;                     \
-       __gu_err;                                               \
-})
-
-#define __get_user64_nocheck(x, ptr, size)                     \
-({                                                             \
-       long __gu_err;                                          \
-       long long __gu_val;                                     \
-       __chk_user_ptr(ptr);                                    \
-       __get_user_size64(__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);             \
-       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;                                                       \
-})
-
-#define __get_user64_check(x, ptr, size)                                 \
-({                                                                       \
-       long __gu_err = -EFAULT;                                          \
-       long long __gu_val = 0;                                           \
-       const __typeof__(*(ptr)) __user *__gu_addr = (ptr);               \
-       if (access_ok(VERIFY_READ, __gu_addr, (size)))                    \
-               __get_user_size64(__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;                                             \
-       switch (size) {                                         \
-       case 1:                                                 \
-               __get_user_asm(x, ptr, retval, "lbz");          \
-               break;                                          \
-       case 2:                                                 \
-               __get_user_asm(x, ptr, retval, "lhz");          \
-               break;                                          \
-       case 4:                                                 \
-               __get_user_asm(x, ptr, retval, "lwz");          \
-               break;                                          \
-       default:                                                \
-               x = __get_user_bad();                           \
-       }                                                       \
-} while (0)
-
-#define __get_user_size64(x, ptr, size, retval)                        \
-do {                                                           \
-       retval = 0;                                             \
-       switch (size) {                                         \
-       case 1:                                                 \
-               __get_user_asm(x, ptr, retval, "lbz");          \
-               break;                                          \
-       case 2:                                                 \
-               __get_user_asm(x, ptr, retval, "lhz");          \
-               break;                                          \
-       case 4:                                                 \
-               __get_user_asm(x, ptr, retval, "lwz");          \
-               break;                                          \
-       case 8:                                                 \
-               __get_user_asm2(x, ptr, retval);                \
-               break;                                          \
-       default:                                                \
-               x = __get_user_bad();                           \
-       }                                                       \
-} while (0)
-
-#define __get_user_asm(x, addr, err, op)               \
-       __asm__ __volatile__(                           \
-               "1:     "op" %1,0(%2)\n"                \
-               "2:\n"                                  \
-               ".section .fixup,\"ax\"\n"              \
-               "3:     li %0,%3\n"                     \
-               "       li %1,0\n"                      \
-               "       b 2b\n"                         \
-               ".previous\n"                           \
-               ".section __ex_table,\"a\"\n"           \
-               "       .align 2\n"                     \
-               "       .long 1b,3b\n"                  \
-               ".previous"                             \
-               : "=r"(err), "=r"(x)                    \
-               : "b"(addr), "i"(-EFAULT), "0"(err))
-
-#define __get_user_asm2(x, addr, err)                  \
-       __asm__ __volatile__(                           \
-               "1:     lwz %1,0(%2)\n"                 \
-               "2:     lwz %1+1,4(%2)\n"               \
-               "3:\n"                                  \
-               ".section .fixup,\"ax\"\n"              \
-               "4:     li %0,%3\n"                     \
-               "       li %1,0\n"                      \
-               "       li %1+1,0\n"                    \
-               "       b 3b\n"                         \
-               ".previous\n"                           \
-               ".section __ex_table,\"a\"\n"           \
-               "       .align 2\n"                     \
-               "       .long 1b,4b\n"                  \
-               "       .long 2b,4b\n"                  \
-               ".previous"                             \
-               : "=r"(err), "=&r"(x)                   \
-               : "b"(addr), "i"(-EFAULT), "0"(err))
-
-/* more complex routines */
-
-extern int __copy_tofrom_user(void __user *to, const void __user *from,
-                             unsigned long size);
-
-extern inline unsigned long
-copy_from_user(void *to, const void __user *from, unsigned long n)
-{
-       unsigned long over;
-
-       if (access_ok(VERIFY_READ, from, n))
-               return __copy_tofrom_user((__force void __user *)to, from, n);
-       if ((unsigned long)from < TASK_SIZE) {
-               over = (unsigned long)from + n - TASK_SIZE;
-               return __copy_tofrom_user((__force void __user *)to, from, n - over) + over;
-       }
-       return n;
-}
-
-extern inline unsigned long
-copy_to_user(void __user *to, const void *from, unsigned long n)
-{
-       unsigned long over;
-
-       if (access_ok(VERIFY_WRITE, to, n))
-               return __copy_tofrom_user(to, (__force void __user *) from, n);
-       if ((unsigned long)to < TASK_SIZE) {
-               over = (unsigned long)to + n - TASK_SIZE;
-               return __copy_tofrom_user(to, (__force void __user *) from, n - over) + over;
-       }
-       return n;
-}
-
-static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long size)
-{
-       return __copy_tofrom_user((__force void __user *)to, from, size);
-}
-
-static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long size)
-{
-       return __copy_tofrom_user(to, (__force void __user *)from, size);
-}
-
-#define __copy_to_user_inatomic __copy_to_user
-#define __copy_from_user_inatomic __copy_from_user
-
-extern unsigned long __clear_user(void __user *addr, unsigned long size);
-
-extern inline unsigned long
-clear_user(void __user *addr, unsigned long size)
-{
-       if (access_ok(VERIFY_WRITE, addr, size))
-               return __clear_user(addr, size);
-       if ((unsigned long)addr < TASK_SIZE) {
-               unsigned long over = (unsigned long)addr + size - TASK_SIZE;
-               return __clear_user(addr, size - over) + over;
-       }
-       return size;
-}
-
-extern int __strncpy_from_user(char *dst, const char __user *src, long count);
-
-extern inline long
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       if (access_ok(VERIFY_READ, src, 1))
-               return __strncpy_from_user(dst, src, count);
-       return -EFAULT;
-}
-
-/*
- * Return the size of a string (including the ending 0)
- *
- * Return 0 for error
- */
-
-extern int __strnlen_user(const char __user *str, long len, unsigned long top);
-
-/*
- * Returns the length of the string at str (including the null byte),
- * or 0 if we hit a page we can't access,
- * or something > len if we didn't find a null byte.
- *
- * The `top' parameter to __strnlen_user is to make sure that
- * we can never overflow from the user area into kernel space.
- */
-extern __inline__ int strnlen_user(const char __user *str, long len)
-{
-       unsigned long top = current->thread.fs.seg;
-
-       if ((unsigned long)str > top)
-               return 0;
-       return __strnlen_user(str, len, top);
-}
-
-#define strlen_user(str)       strnlen_user((str), 0x7ffffffe)
-
-#endif  /* __ASSEMBLY__ */
-
-#endif /* _PPC_UACCESS_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc64/uaccess.h b/include/asm-ppc64/uaccess.h
deleted file mode 100644 (file)
index 132c127..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-#ifndef _PPC64_UACCESS_H
-#define _PPC64_UACCESS_H
-
-/* 
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef __ASSEMBLY__
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <asm/processor.h>
-
-#define VERIFY_READ    0
-#define VERIFY_WRITE   1
-
-/*
- * The fs value determines whether argument validity checking should be
- * performed or not.  If get_fs() == USER_DS, checking is performed, with
- * get_fs() == KERNEL_DS, checking is bypassed.
- *
- * For historical reasons, these macros are grossly misnamed.
- */
-
-#define MAKE_MM_SEG(s)  ((mm_segment_t) { (s) })
-
-#define KERNEL_DS      MAKE_MM_SEG(0UL)
-#define USER_DS                MAKE_MM_SEG(0xf000000000000000UL)
-
-#define get_ds()       (KERNEL_DS)
-#define get_fs()       (current->thread.fs)
-#define set_fs(val)    (current->thread.fs = (val))
-
-#define segment_eq(a,b)        ((a).seg == (b).seg)
-
-/*
- * Use the alpha trick for checking ranges:
- *
- * Is a address valid? This does a straightforward calculation rather
- * than tests.
- *
- * Address valid if:
- *  - "addr" doesn't have any high-bits set
- *  - AND "size" doesn't have any high-bits set
- *  - OR we are in kernel mode.
- *
- * We dont have to check for high bits in (addr+size) because the first
- * two checks force the maximum result to be below the start of the
- * kernel region.
- */
-#define __access_ok(addr,size,segment) \
-       (((segment).seg & (addr | size )) == 0)
-
-#define access_ok(type,addr,size) \
-       __access_ok(((__force unsigned long)(addr)),(size),get_fs())
-
-/*
- * The exception table consists of pairs of addresses: the first is the
- * address of an instruction that is allowed to fault, and the second is
- * the address at which the program should continue.  No registers are
- * modified, so it is entirely up to the continuation code to figure out
- * what to do.
- *
- * All the routines below use bits of fixup code that are out of line
- * with the main instruction path.  This means when everything is well,
- * we don't even have to jump over them.  Further, they do not intrude
- * on our cache or tlb entries.
- */
-
-struct exception_table_entry
-{
-       unsigned long insn, fixup;
-};
-
-/* Returns 0 if exception not found and fixup otherwise.  */
-extern unsigned long search_exception_table(unsigned long);
-
-/*
- * These are the main single-value transfer routines.  They automatically
- * use the right size if we just have the right pointer type.
- *
- * This gets kind of ugly. We want to return _two_ values in "get_user()"
- * and yet we don't want to do any pointers, because that is too much
- * of a performance impact. Thus we have a few rather ugly macros here,
- * and hide all the ugliness from the user.
- *
- * The "__xxx" versions of the user access functions are versions that
- * do not verify the address space, that must have been done previously
- * with a separate "access_ok()" call (this is used when we do multiple
- * accesses to the same area of user memory).
- *
- * As we use the same address space for kernel and user data on the
- * PowerPC, we can just do these as direct assignments.  (Of course, the
- * exception handling means that it's no longer "just"...)
- */
-#define get_user(x,ptr) \
-  __get_user_check((x),(ptr),sizeof(*(ptr)))
-#define put_user(x,ptr) \
-  __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
-
-#define __get_user(x,ptr) \
-  __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
-#define __put_user(x,ptr) \
-  __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
-
-#define __get_user_unaligned __get_user
-#define __put_user_unaligned __put_user
-
-extern long __put_user_bad(void);
-
-#define __put_user_nocheck(x,ptr,size)                         \
-({                                                             \
-       long __pu_err;                                          \
-       might_sleep();                                          \
-       __chk_user_ptr(ptr);                                    \
-       __put_user_size((x),(ptr),(size),__pu_err,-EFAULT);     \
-       __pu_err;                                               \
-})
-
-#define __put_user_check(x,ptr,size)                                   \
-({                                                                     \
-       long __pu_err = -EFAULT;                                        \
-       void __user *__pu_addr = (ptr);                                 \
-       might_sleep();                                                  \
-       if (access_ok(VERIFY_WRITE,__pu_addr,size))                     \
-               __put_user_size((x),__pu_addr,(size),__pu_err,-EFAULT); \
-       __pu_err;                                                       \
-})
-
-#define __put_user_size(x,ptr,size,retval,errret)                      \
-do {                                                                   \
-       retval = 0;                                                     \
-       switch (size) {                                                 \
-         case 1: __put_user_asm(x,ptr,retval,"stb",errret); break;     \
-         case 2: __put_user_asm(x,ptr,retval,"sth",errret); break;     \
-         case 4: __put_user_asm(x,ptr,retval,"stw",errret); break;     \
-         case 8: __put_user_asm(x,ptr,retval,"std",errret); break;     \
-         default: __put_user_bad();                                    \
-       }                                                               \
-} while (0)
-
-/*
- * We don't tell gcc that we are accessing memory, but this is OK
- * because we do not write to any memory gcc knows about, so there
- * are no aliasing issues.
- */
-#define __put_user_asm(x, addr, err, op, errret)               \
-       __asm__ __volatile__(                                   \
-               "1:     "op" %1,0(%2)   # put_user\n"           \
-               "2:\n"                                          \
-               ".section .fixup,\"ax\"\n"                      \
-               "3:     li %0,%3\n"                             \
-               "       b 2b\n"                                 \
-               ".previous\n"                                   \
-               ".section __ex_table,\"a\"\n"                   \
-               "       .align 3\n"                             \
-               "       .llong 1b,3b\n"                         \
-               ".previous"                                     \
-               : "=r"(err)                                     \
-               : "r"(x), "b"(addr), "i"(errret), "0"(err))
-
-
-#define __get_user_nocheck(x,ptr,size)                         \
-({                                                             \
-       long __gu_err;                                          \
-       unsigned long __gu_val;                                 \
-       might_sleep();                                          \
-       __get_user_size(__gu_val,(ptr),(size),__gu_err,-EFAULT);\
-       (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,-EFAULT);\
-       (x) = (__typeof__(*(ptr)))__gu_val;                             \
-       __gu_err;                                                       \
-})
-
-extern long __get_user_bad(void);
-
-#define __get_user_size(x,ptr,size,retval,errret)                      \
-do {                                                                   \
-       retval = 0;                                                     \
-       __chk_user_ptr(ptr);                                            \
-       switch (size) {                                                 \
-         case 1: __get_user_asm(x,ptr,retval,"lbz",errret); break;     \
-         case 2: __get_user_asm(x,ptr,retval,"lhz",errret); break;     \
-         case 4: __get_user_asm(x,ptr,retval,"lwz",errret); break;     \
-         case 8: __get_user_asm(x,ptr,retval,"ld",errret);  break;     \
-         default: (x) = __get_user_bad();                              \
-       }                                                               \
-} while (0)
-
-#define __get_user_asm(x, addr, err, op, errret)       \
-       __asm__ __volatile__(                           \
-               "1:     "op" %1,0(%2)   # get_user\n"   \
-               "2:\n"                                  \
-               ".section .fixup,\"ax\"\n"              \
-               "3:     li %0,%3\n"                     \
-               "       li %1,0\n"                      \
-               "       b 2b\n"                         \
-               ".previous\n"                           \
-               ".section __ex_table,\"a\"\n"           \
-               "       .align 3\n"                     \
-               "       .llong 1b,3b\n"                 \
-               ".previous"                             \
-               : "=r"(err), "=r"(x)                    \
-               : "b"(addr), "i"(errret), "0"(err))
-
-/* more complex routines */
-
-extern unsigned long __copy_tofrom_user(void __user *to, const void __user *from,
-                                       unsigned long size);
-
-static inline unsigned long
-__copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
-{
-       if (__builtin_constant_p(n)) {
-               unsigned long ret;
-
-               switch (n) {
-               case 1:
-                       __get_user_size(*(u8 *)to, from, 1, ret, 1);
-                       return ret;
-               case 2:
-                       __get_user_size(*(u16 *)to, from, 2, ret, 2);
-                       return ret;
-               case 4:
-                       __get_user_size(*(u32 *)to, from, 4, ret, 4);
-                       return ret;
-               case 8:
-                       __get_user_size(*(u64 *)to, from, 8, ret, 8);
-                       return ret;
-               }
-       }
-       return __copy_tofrom_user((__force void __user *) to, from, n);
-}
-
-static inline unsigned long
-__copy_from_user(void *to, const void __user *from, unsigned long n)
-{
-       might_sleep();
-       return __copy_from_user_inatomic(to, from, n);
-}
-
-static inline unsigned long
-__copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
-{
-       if (__builtin_constant_p(n)) {
-               unsigned long ret;
-
-               switch (n) {
-               case 1:
-                       __put_user_size(*(u8 *)from, (u8 __user *)to, 1, ret, 1);
-                       return ret;
-               case 2:
-                       __put_user_size(*(u16 *)from, (u16 __user *)to, 2, ret, 2);
-                       return ret;
-               case 4:
-                       __put_user_size(*(u32 *)from, (u32 __user *)to, 4, ret, 4);
-                       return ret;
-               case 8:
-                       __put_user_size(*(u64 *)from, (u64 __user *)to, 8, ret, 8);
-                       return ret;
-               }
-       }
-       return __copy_tofrom_user(to, (__force const void __user *) from, n);
-}
-
-static inline unsigned long
-__copy_to_user(void __user *to, const void *from, unsigned long n)
-{
-       might_sleep();
-       return __copy_to_user_inatomic(to, from, n);
-}
-
-#define __copy_in_user(to, from, size) \
-       __copy_tofrom_user((to), (from), (size))
-
-extern unsigned long copy_from_user(void *to, const void __user *from,
-                                   unsigned long n);
-extern unsigned long copy_to_user(void __user *to, const void *from,
-                                 unsigned long n);
-extern unsigned long copy_in_user(void __user *to, const void __user *from,
-                                 unsigned long n);
-
-extern unsigned long __clear_user(void __user *addr, unsigned long size);
-
-static inline unsigned long
-clear_user(void __user *addr, unsigned long size)
-{
-       might_sleep();
-       if (likely(access_ok(VERIFY_WRITE, addr, size)))
-               size = __clear_user(addr, size);
-       return size;
-}
-
-extern int __strncpy_from_user(char *dst, const char __user *src, long count);
-
-static inline long
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       might_sleep();
-       if (likely(access_ok(VERIFY_READ, src, 1)))
-               return __strncpy_from_user(dst, src, count);
-       return -EFAULT;
-}
-
-/*
- * Return the size of a string (including the ending 0)
- *
- * Return 0 for error
- */
-extern int __strnlen_user(const char __user *str, long len);
-
-/*
- * Returns the length of the string at str (including the null byte),
- * or 0 if we hit a page we can't access,
- * or something > len if we didn't find a null byte.
- */
-static inline int strnlen_user(const char __user *str, long len)
-{
-       might_sleep();
-       if (likely(access_ok(VERIFY_READ, str, 1)))
-               return __strnlen_user(str, len);
-       return 0;
-}
-
-#define strlen_user(str)       strnlen_user((str), 0x7ffffffe)
-
-#endif  /* __ASSEMBLY__ */
-
-#endif /* _PPC64_UACCESS_H */