sh: use the new generic strnlen_user() function
authorPaul Mundt <lethal@linux-sh.org>
Mon, 4 Jun 2012 06:46:05 +0000 (15:46 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Wed, 13 Jun 2012 01:28:37 +0000 (10:28 +0900)
This discards both the _32 and _64 versions in favour of the consolidated
generic one.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
arch/sh/Kconfig
arch/sh/include/asm/uaccess.h
arch/sh/include/asm/uaccess_32.h
arch/sh/include/asm/uaccess_64.h
arch/sh/include/asm/word-at-a-time.h [new file with mode: 0644]
arch/sh/kernel/cpu/sh5/entry.S
arch/sh/kernel/sh_ksyms_64.c

index cbffc26c043425873081405ff02af5d060bc79f7..31d9db7913e4352a10680f76f2aaa8a5e800eef5 100644 (file)
@@ -33,6 +33,7 @@ config SUPERH
        select GENERIC_CLOCKEVENTS
        select GENERIC_CMOS_UPDATE if SH_SH03 || SH_DREAMCAST
        select GENERIC_STRNCPY_FROM_USER
+       select GENERIC_STRNLEN_USER
        help
          The SuperH is a RISC processor targeted for use in embedded systems
          and consumer electronics; it was also used in the Sega Dreamcast
index 3df7eee9c1552e81414fc66403ae0795b56d4af7..8698a80ed00c1fcbebed2ec993887f104179d384 100644 (file)
@@ -104,6 +104,9 @@ struct __large_struct { unsigned long buf[100]; };
 
 extern long strncpy_from_user(char *dest, const char __user *src, long count);
 
+extern __must_check long strlen_user(const char __user *str);
+extern __must_check long strnlen_user(const char __user *str, long n);
+
 /* Generic arbitrary sized copy.  */
 /* Return the number of bytes NOT copied */
 __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
@@ -165,43 +168,6 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
        return __copy_size;
 }
 
-/**
- * strnlen_user: - Get the size of a string in user space.
- * @s: The string to measure.
- * @n: The maximum valid length
- *
- * Context: User context only.  This function may sleep.
- *
- * Get the size of a NUL-terminated string in user space.
- *
- * Returns the size of the string INCLUDING the terminating NUL.
- * On exception, returns 0.
- * If the string is too long, returns a value greater than @n.
- */
-static inline long strnlen_user(const char __user *s, long n)
-{
-       if (!__addr_ok(s))
-               return 0;
-       else
-               return __strnlen_user(s, n);
-}
-
-/**
- * strlen_user: - Get the size of a string in user space.
- * @str: The string to measure.
- *
- * Context: User context only.  This function may sleep.
- *
- * Get the size of a NUL-terminated string in user space.
- *
- * Returns the size of the string INCLUDING the terminating NUL.
- * On exception, returns 0.
- *
- * If there is a limit on the length of a valid string, you may wish to
- * consider using strnlen_user() instead.
- */
-#define strlen_user(str)       strnlen_user(str, ~0UL >> 1)
-
 /*
  * 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
index ef44d05bb631d33164a54416e9ae5fc25f4c652d..c0de7ee35ab7aa5ba80c393f4a2588102d01e2a1 100644 (file)
@@ -170,40 +170,4 @@ __asm__ __volatile__( \
 
 extern void __put_user_unknown(void);
 
-/*
- * Return the size of a string (including the ending 0 even when we have
- * exceeded the maximum string length).
- */
-static inline long __strnlen_user(const char __user *__s, long __n)
-{
-       unsigned long res;
-       unsigned long __dummy;
-
-       __asm__ __volatile__(
-               "1:\t"
-               "mov.b  @(%0,%3), %1\n\t"
-               "cmp/eq %4, %0\n\t"
-               "bt/s   2f\n\t"
-               " add   #1, %0\n\t"
-               "tst    %1, %1\n\t"
-               "bf     1b\n\t"
-               "2:\n"
-               ".section .fixup,\"ax\"\n"
-               "3:\n\t"
-               "mov.l  4f, %1\n\t"
-               "jmp    @%1\n\t"
-               " mov   #0, %0\n"
-               ".balign 4\n"
-               "4:     .long 2b\n"
-               ".previous\n"
-               ".section __ex_table,\"a\"\n"
-               "       .balign 4\n"
-               "       .long 1b,3b\n"
-               ".previous"
-               : "=z" (res), "=&r" (__dummy)
-               : "0" (0), "r" (__s), "r" (__n)
-               : "t");
-       return res;
-}
-
 #endif /* __ASM_SH_UACCESS_32_H */
index 0042c9054b2067351707f6b39325ce7e298a76c8..2e07e0f40c6af3038ca6b69fecfefefe528dc2b8 100644 (file)
@@ -84,6 +84,4 @@ extern long __put_user_asm_l(void *, long);
 extern long __put_user_asm_q(void *, long);
 extern void __put_user_unknown(void);
 
-extern long __strnlen_user(const char *__s, long __n);
-
 #endif /* __ASM_SH_UACCESS_64_H */
diff --git a/arch/sh/include/asm/word-at-a-time.h b/arch/sh/include/asm/word-at-a-time.h
new file mode 100644 (file)
index 0000000..6e38953
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef __ASM_SH_WORD_AT_A_TIME_H
+#define __ASM_SH_WORD_AT_A_TIME_H
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+# include <asm-generic/word-at-a-time.h>
+#else
+/*
+ * Little-endian version cribbed from x86.
+ */
+struct word_at_a_time {
+       const unsigned long one_bits, high_bits;
+};
+
+#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
+
+/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */
+static inline long count_masked_bytes(long mask)
+{
+       /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */
+       long a = (0x0ff0001+mask) >> 23;
+       /* Fix the 1 for 00 case */
+       return a & mask;
+}
+
+/* Return nonzero if it has a zero */
+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;
+}
+
+static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c)
+{
+       return bits;
+}
+
+static inline unsigned long create_zero_mask(unsigned long bits)
+{
+       bits = (bits - 1) & ~bits;
+       return bits >> 7;
+}
+
+/* The mask we created is directly usable as a bytemask */
+#define zero_bytemask(mask) (mask)
+
+static inline unsigned long find_zero(unsigned long mask)
+{
+       return count_masked_bytes(mask);
+}
+#endif
+
+#endif
index b7b3f63299b0e5c7808b68b496d60c5b5516c366..b7cf6a547f117c5eeae4b69f6b1ccbcdb41b37c8 100644 (file)
@@ -1568,46 +1568,6 @@ ___clear_user_exit:
 
 #endif /* CONFIG_MMU */
 
-/*
- * extern long __strnlen_user(const char *__s, long __n)
- *
- * Inputs:
- * (r2)  source address
- * (r3)  source size in bytes
- *
- * Ouputs:
- * (r2)  -EFAULT (in case of faulting)
- *       string length (otherwise)
- */
-       .global __strnlen_user
-__strnlen_user:
-       pta     ___strnlen_user_set_reply, tr0
-       pta     ___strnlen_user1, tr1
-       or      ZERO, ZERO, r5          /* r5 = counter */
-       movi    -(EFAULT), r6           /* r6 = reply, no real fixup */
-       or      ZERO, ZERO, r7          /* r7 = data, clear top byte of data */
-       beq     r3, ZERO, tr0
-
-___strnlen_user1:
-       ldx.b   r2, r5, r7              /* Fault address: only in reading */
-       addi    r3, -1, r3              /* No real fixup */
-       addi    r5, 1, r5
-       beq     r3, ZERO, tr0
-       bne     r7, ZERO, tr1
-! The line below used to be active.  This meant led to a junk byte lying between each pair
-! of entries in the argv & envp structures in memory.  Whilst the program saw the right data
-! via the argv and envp arguments to main, it meant the 'flat' representation visible through
-! /proc/$pid/cmdline was corrupt, causing trouble with ps, for example.
-!      addi    r5, 1, r5               /* Include '\0' */
-
-___strnlen_user_set_reply:
-       or      r5, ZERO, r6            /* If done, return counter */
-
-___strnlen_user_exit:
-       or      r6, ZERO, r2
-       ptabs   LINK, tr0
-       blink   tr0, ZERO
-
 /*
  * extern long __get_user_asm_?(void *val, long addr)
  *
@@ -1942,7 +1902,6 @@ asm_uaccess_start:
        .long   ___copy_user2, ___copy_user_exit
        .long   ___clear_user1, ___clear_user_exit
 #endif
-       .long   ___strnlen_user1, ___strnlen_user_exit
        .long   ___get_user_asm_b1, ___get_user_asm_b_exit
        .long   ___get_user_asm_w1, ___get_user_asm_w_exit
        .long   ___get_user_asm_l1, ___get_user_asm_l_exit
index 3a3ba60e4f934f6747019d0c6e1402cad6291c85..26a0774f5272af46839c1faaf924ae9a4e29af13 100644 (file)
@@ -32,7 +32,6 @@ EXPORT_SYMBOL(__get_user_asm_b);
 EXPORT_SYMBOL(__get_user_asm_w);
 EXPORT_SYMBOL(__get_user_asm_l);
 EXPORT_SYMBOL(__get_user_asm_q);
-EXPORT_SYMBOL(__strnlen_user);
 EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(__copy_user);