select GENERIC_SMP_IDLE_THREAD
        select KTIME_SCALAR
        select GENERIC_CLOCKEVENTS_BROADCAST if SMP
+       select GENERIC_STRNCPY_FROM_USER
+       select GENERIC_STRNLEN_USER
        help
          The ARM series is a line of low-power-consumption RISC chip designs
          licensed by ARM Ltd and targeted at embedded applications and
 
 
 #define access_ok(type,addr,size)      (__range_ok(addr,size) == 0)
 
+#define user_addr_max() \
+       (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
+
 /*
  * The "__xxx" versions of the user access functions do not verify the
  * address space - it must have been done previously with a separate
 #define __clear_user(addr,n)           (memset((void __force *)addr, 0, n), 0)
 #endif
 
-extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count);
-extern unsigned long __must_check __strnlen_user(const char __user *s, long n);
-
 static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
 {
        if (access_ok(VERIFY_READ, from, n))
        return n;
 }
 
-static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       long res = -EFAULT;
-       if (access_ok(VERIFY_READ, src, 1))
-               res = __strncpy_from_user(dst, src, count);
-       return res;
-}
-
-#define strlen_user(s) strnlen_user(s, ~0UL >> 1)
+extern long strncpy_from_user(char *dest, const char __user *src, long count);
 
-static inline long __must_check strnlen_user(const char __user *s, long n)
-{
-       unsigned long res = 0;
-
-       if (__addr_ok(s))
-               res = __strnlen_user(s, n);
-
-       return res;
-}
+extern __must_check long strlen_user(const char __user *str);
+extern __must_check long strnlen_user(const char __user *str, long n);
 
 #endif /* _ASMARM_UACCESS_H */
 
--- /dev/null
+#ifndef __ASM_ARM_WORD_AT_A_TIME_H
+#define __ASM_ARM_WORD_AT_A_TIME_H
+
+#ifndef __ARMEB__
+
+/*
+ * Little-endian word-at-a-time zero byte handling.
+ * Heavily based on the x86 algorithm.
+ */
+#include <linux/kernel.h>
+
+struct word_at_a_time {
+       const unsigned long one_bits, high_bits;
+};
+
+#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
+
+static inline unsigned long has_zero(unsigned long a, unsigned long *bits,
+                                    const struct word_at_a_time *c)
+{
+       unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits;
+       *bits = mask;
+       return mask;
+}
+
+#define prep_zero_mask(a, bits, c) (bits)
+
+static inline unsigned long create_zero_mask(unsigned long bits)
+{
+       bits = (bits - 1) & ~bits;
+       return bits >> 7;
+}
+
+static inline unsigned long find_zero(unsigned long mask)
+{
+       unsigned long ret;
+
+#if __LINUX_ARM_ARCH__ >= 5
+       /* We have clz available. */
+       ret = fls(mask) >> 3;
+#else
+       /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */
+       ret = (0x0ff0001 + mask) >> 23;
+       /* Fix the 1 for 00 case */
+       ret &= mask;
+#endif
+
+       return ret;
+}
+
+#else  /* __ARMEB__ */
+#include <asm-generic/word-at-a-time.h>
+#endif
+
+#endif /* __ASM_ARM_WORD_AT_A_TIME_H */
 
 EXPORT_SYMBOL(memchr);
 EXPORT_SYMBOL(__memzero);
 
-       /* user mem (segment) */
-EXPORT_SYMBOL(__strnlen_user);
-EXPORT_SYMBOL(__strncpy_from_user);
-
 #ifdef CONFIG_MMU
 EXPORT_SYMBOL(copy_page);
 
 
                   csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
                   delay.o findbit.o memchr.o memcpy.o                \
                   memmove.o memset.o memzero.o setbit.o              \
-                  strncpy_from_user.o strnlen_user.o                 \
                   strchr.o strrchr.o                                 \
                   testchangebit.o testclearbit.o testsetbit.o        \
                   ashldi3.o ashrdi3.o lshrdi3.o muldi3.o             \
 
+++ /dev/null
-/*
- *  linux/arch/arm/lib/strncpy_from_user.S
- *
- *  Copyright (C) 1995-2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/errno.h>
-
-       .text
-       .align  5
-
-/*
- * Copy a string from user space to kernel space.
- *  r0 = dst, r1 = src, r2 = byte length
- * returns the number of characters copied (strlen of copied string),
- *  -EFAULT on exception, or "len" if we fill the whole buffer
- */
-ENTRY(__strncpy_from_user)
-       mov     ip, r1
-1:     subs    r2, r2, #1
-       ldrusr  r3, r1, 1, pl
-       bmi     2f
-       strb    r3, [r0], #1
-       teq     r3, #0
-       bne     1b
-       sub     r1, r1, #1      @ take NUL character out of count
-2:     sub     r0, r1, ip
-       mov     pc, lr
-ENDPROC(__strncpy_from_user)
-
-       .pushsection .fixup,"ax"
-       .align  0
-9001:  mov     r3, #0
-       strb    r3, [r0, #0]    @ null terminate
-       mov     r0, #-EFAULT
-       mov     pc, lr
-       .popsection
-
 
+++ /dev/null
-/*
- *  linux/arch/arm/lib/strnlen_user.S
- *
- *  Copyright (C) 1995-2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/errno.h>
-
-       .text
-       .align  5
-
-/* Prototype: unsigned long __strnlen_user(const char *str, long n)
- * Purpose  : get length of a string in user memory
- * Params   : str - address of string in user memory
- * Returns  : length of string *including terminator*
- *           or zero on exception, or n + 1 if too long
- */
-ENTRY(__strnlen_user)
-       mov     r2, r0
-1:
-       ldrusr  r3, r0, 1
-       teq     r3, #0
-       beq     2f
-       subs    r1, r1, #1
-       bne     1b
-       add     r0, r0, #1
-2:     sub     r0, r0, r2
-       mov     pc, lr
-ENDPROC(__strnlen_user)
-
-       .pushsection .fixup,"ax"
-       .align  0
-9001:  mov     r0, #0
-       mov     pc, lr
-       .popsection