Merge tag 'asm-generic-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 Sep 2021 22:13:02 +0000 (15:13 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 Sep 2021 22:13:02 +0000 (15:13 -0700)
Pull asm-generic updates from Arnd Bergmann:
 "The main content for 5.15 is a series that cleans up the handling of
  strncpy_from_user() and strnlen_user(), removing a lot of slightly
  incorrect versions of these in favor of the lib/strn*.c helpers that
  implement these correctly and more efficiently.

  The only architectures that retain a private version now are mips,
  ia64, um and parisc. I had offered to convert those at all, but Thomas
  Bogendoerfer wanted to keep the mips version for the moment until he
  had a chance to do regression testing.

  The branch also contains two patches for bitops and for ffs()"

* tag 'asm-generic-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic:
  bitops/non-atomic: make @nr unsigned to avoid any DIV
  asm-generic: ffs: Drop bogus reference to ffz location
  asm-generic: reverse GENERIC_{STRNCPY_FROM,STRNLEN}_USER symbols
  asm-generic: remove extra strn{cpy_from,len}_user declarations
  asm-generic: uaccess: remove inline strncpy_from_user/strnlen_user
  s390: use generic strncpy/strnlen from_user
  microblaze: use generic strncpy/strnlen from_user
  csky: use generic strncpy/strnlen from_user
  arc: use generic strncpy/strnlen from_user
  hexagon: use generic strncpy/strnlen from_user
  h8300: remove stale strncpy_from_user
  asm-generic/uaccess.h: remove __strncpy_from_user/__strnlen_user

42 files changed:
arch/alpha/Kconfig
arch/arc/include/asm/uaccess.h
arch/arc/mm/extable.c
arch/arm/Kconfig
arch/arm64/Kconfig
arch/csky/include/asm/uaccess.h
arch/csky/lib/usercopy.c
arch/h8300/kernel/h8300_ksyms.c
arch/h8300/lib/Makefile
arch/h8300/lib/strncpy.S [deleted file]
arch/hexagon/include/asm/uaccess.h
arch/hexagon/kernel/hexagon_ksyms.c
arch/hexagon/mm/Makefile
arch/hexagon/mm/strnlen_user.S [deleted file]
arch/ia64/Kconfig
arch/m68k/Kconfig
arch/microblaze/include/asm/uaccess.h
arch/microblaze/kernel/microblaze_ksyms.c
arch/microblaze/lib/uaccess_old.S
arch/mips/Kconfig
arch/nds32/Kconfig
arch/nios2/Kconfig
arch/openrisc/Kconfig
arch/parisc/Kconfig
arch/powerpc/Kconfig
arch/riscv/Kconfig
arch/s390/include/asm/uaccess.h
arch/s390/lib/uaccess.c
arch/sh/Kconfig
arch/sparc/Kconfig
arch/um/Kconfig
arch/um/include/asm/uaccess.h
arch/um/kernel/skas/uaccess.c
arch/x86/Kconfig
arch/xtensa/Kconfig
arch/xtensa/include/asm/uaccess.h
arch/xtensa/kernel/xtensa_ksyms.c
include/asm-generic/bitops/builtin-ffs.h
include/asm-generic/bitops/ffs.h
include/asm-generic/bitops/non-atomic.h
include/asm-generic/uaccess.h
lib/Kconfig

index 6c50877..02e5b67 100644 (file)
@@ -28,8 +28,6 @@ config ALPHA
        select AUDIT_ARCH
        select GENERIC_CPU_VULNERABILITIES
        select GENERIC_SMP_IDLE_THREAD
-       select GENERIC_STRNCPY_FROM_USER
-       select GENERIC_STRNLEN_USER
        select HAVE_ARCH_AUDITSYSCALL
        select HAVE_MOD_ARCH_SPECIFIC
        select MODULES_USE_ELF_RELA
index ea40ec7..783bfdb 100644 (file)
@@ -655,88 +655,16 @@ static inline unsigned long __arc_clear_user(void __user *to, unsigned long n)
        return res;
 }
 
-static inline long
-__arc_strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       long res = 0;
-       char val;
-
-       if (count == 0)
-               return 0;
-
-       __asm__ __volatile__(
-       "       mov     lp_count, %5            \n"
-       "       lp      3f                      \n"
-       "1:     ldb.ab  %3, [%2, 1]             \n"
-       "       breq.d  %3, 0, 3f               \n"
-       "       stb.ab  %3, [%1, 1]             \n"
-       "       add     %0, %0, 1       # Num of NON NULL bytes copied  \n"
-       "3:                                                             \n"
-       "       .section .fixup, \"ax\"         \n"
-       "       .align 4                        \n"
-       "4:     mov %0, %4              # sets @res as -EFAULT  \n"
-       "       j   3b                          \n"
-       "       .previous                       \n"
-       "       .section __ex_table, \"a\"      \n"
-       "       .align 4                        \n"
-       "       .word   1b, 4b                  \n"
-       "       .previous                       \n"
-       : "+r"(res), "+r"(dst), "+r"(src), "=r"(val)
-       : "g"(-EFAULT), "r"(count)
-       : "lp_count", "memory");
-
-       return res;
-}
-
-static inline long __arc_strnlen_user(const char __user *s, long n)
-{
-       long res, tmp1, cnt;
-       char val;
-
-       __asm__ __volatile__(
-       "       mov %2, %1                      \n"
-       "1:     ldb.ab  %3, [%0, 1]             \n"
-       "       breq.d  %3, 0, 2f               \n"
-       "       sub.f   %2, %2, 1               \n"
-       "       bnz 1b                          \n"
-       "       sub %2, %2, 1                   \n"
-       "2:     sub %0, %1, %2                  \n"
-       "3:     ;nop                            \n"
-       "       .section .fixup, \"ax\"         \n"
-       "       .align 4                        \n"
-       "4:     mov %0, 0                       \n"
-       "       j   3b                          \n"
-       "       .previous                       \n"
-       "       .section __ex_table, \"a\"      \n"
-       "       .align 4                        \n"
-       "       .word 1b, 4b                    \n"
-       "       .previous                       \n"
-       : "=r"(res), "=r"(tmp1), "=r"(cnt), "=r"(val)
-       : "0"(s), "1"(n)
-       : "memory");
-
-       return res;
-}
-
 #ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE
 
 #define INLINE_COPY_TO_USER
 #define INLINE_COPY_FROM_USER
 
 #define __clear_user(d, n)             __arc_clear_user(d, n)
-#define __strncpy_from_user(d, s, n)   __arc_strncpy_from_user(d, s, n)
-#define __strnlen_user(s, n)           __arc_strnlen_user(s, n)
 #else
 extern unsigned long arc_clear_user_noinline(void __user *to,
                unsigned long n);
-extern long arc_strncpy_from_user_noinline (char *dst, const char __user *src,
-               long count);
-extern long arc_strnlen_user_noinline(const char __user *src, long n);
-
 #define __clear_user(d, n)             arc_clear_user_noinline(d, n)
-#define __strncpy_from_user(d, s, n)   arc_strncpy_from_user_noinline(d, s, n)
-#define __strnlen_user(s, n)           arc_strnlen_user_noinline(s, n)
-
 #endif
 
 #include <asm/segment.h>
index b06b09d..4e14c42 100644 (file)
@@ -32,16 +32,4 @@ unsigned long arc_clear_user_noinline(void __user *to,
 }
 EXPORT_SYMBOL(arc_clear_user_noinline);
 
-long arc_strncpy_from_user_noinline(char *dst, const char __user *src,
-               long count)
-{
-       return __arc_strncpy_from_user(dst, src, count);
-}
-EXPORT_SYMBOL(arc_strncpy_from_user_noinline);
-
-long arc_strnlen_user_noinline(const char __user *src, long n)
-{
-       return __arc_strnlen_user(src, n);
-}
-EXPORT_SYMBOL(arc_strnlen_user_noinline);
 #endif
index 2fb7012..1a48c17 100644 (file)
@@ -63,8 +63,6 @@ config ARM
        select GENERIC_PCI_IOMAP
        select GENERIC_SCHED_CLOCK
        select GENERIC_SMP_IDLE_THREAD
-       select GENERIC_STRNCPY_FROM_USER
-       select GENERIC_STRNLEN_USER
        select HANDLE_DOMAIN_IRQ
        select HARDIRQS_SW_RESEND
        select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT
index 62c3c1d..9dc1720 100644 (file)
@@ -130,8 +130,6 @@ config ARM64
        select GENERIC_PTDUMP
        select GENERIC_SCHED_CLOCK
        select GENERIC_SMP_IDLE_THREAD
-       select GENERIC_STRNCPY_FROM_USER
-       select GENERIC_STRNLEN_USER
        select GENERIC_TIME_VSYSCALL
        select GENERIC_GETTIMEOFDAY
        select GENERIC_VDSO_TIME_NS
index ac83823..c40f06e 100644 (file)
@@ -209,12 +209,6 @@ unsigned long raw_copy_to_user(void *to, const void *from, unsigned long n);
 unsigned long __clear_user(void __user *to, unsigned long n);
 #define __clear_user __clear_user
 
-long __strncpy_from_user(char *dst, const char *src, long count);
-#define __strncpy_from_user __strncpy_from_user
-
-long __strnlen_user(const char *s, long n);
-#define __strnlen_user __strnlen_user
-
 #include <asm/segment.h>
 #include <asm-generic/uaccess.h>
 
index c5d394a..3c01c54 100644 (file)
@@ -142,108 +142,6 @@ unsigned long raw_copy_to_user(void *to, const void *from,
 }
 EXPORT_SYMBOL(raw_copy_to_user);
 
-/*
- * __strncpy_from_user: - Copy a NUL terminated string from userspace,
- * with less checking.
- * @dst:   Destination address, in kernel space.  This buffer must be at
- *         least @count bytes long.
- * @src:   Source address, in user space.
- * @count: Maximum number of bytes to copy, including the trailing NUL.
- *
- * Copies a NUL-terminated string from userspace to kernel space.
- * Caller must check the specified block with access_ok() before calling
- * this function.
- *
- * On success, returns the length of the string (not including the trailing
- * NUL).
- *
- * If access to userspace fails, returns -EFAULT (some data may have been
- * copied).
- *
- * If @count is smaller than the length of the string, copies @count bytes
- * and returns @count.
- */
-long __strncpy_from_user(char *dst, const char *src, long count)
-{
-       long res, faultres;
-       int tmp;
-
-       __asm__ __volatile__(
-       "       cmpnei  %3, 0           \n"
-       "       bf      4f              \n"
-       "1:     cmpnei  %1, 0           \n"
-       "       bf      5f              \n"
-       "2:     ldb     %4, (%3, 0)     \n"
-       "       stb     %4, (%2, 0)     \n"
-       "       cmpnei  %4, 0           \n"
-       "       bf      3f              \n"
-       "       addi    %3,  1          \n"
-       "       addi    %2,  1          \n"
-       "       subi    %1,  1          \n"
-       "       br      1b              \n"
-       "3:     subu    %0, %1          \n"
-       "       br      5f              \n"
-       "4:     mov     %0, %5          \n"
-       "       br      5f              \n"
-       ".section __ex_table, \"a\"     \n"
-       ".align   2                     \n"
-       ".long    2b, 4b                \n"
-       ".previous                      \n"
-       "5:                             \n"
-       : "=r"(res), "=r"(count), "=r"(dst),
-         "=r"(src), "=r"(tmp), "=r"(faultres)
-       : "5"(-EFAULT), "0"(count), "1"(count),
-         "2"(dst), "3"(src)
-       : "memory");
-
-       return res;
-}
-EXPORT_SYMBOL(__strncpy_from_user);
-
-/*
- * strnlen_user: - Get the size of a string in user space.
- * @str: The string to measure.
- * @n:   The maximum valid length
- *
- * 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.
- */
-long __strnlen_user(const char *s, long n)
-{
-       unsigned long res, tmp;
-
-       __asm__ __volatile__(
-       "       cmpnei  %1, 0           \n"
-       "       bf      3f              \n"
-       "1:     cmpnei  %0, 0           \n"
-       "       bf      3f              \n"
-       "2:     ldb     %3, (%1, 0)     \n"
-       "       cmpnei  %3, 0           \n"
-       "       bf      3f              \n"
-       "       subi    %0,  1          \n"
-       "       addi    %1,  1          \n"
-       "       br      1b              \n"
-       "3:     subu    %2, %0          \n"
-       "       addi    %2,  1          \n"
-       "       br      5f              \n"
-       "4:     movi    %0, 0           \n"
-       "       br      5f              \n"
-       ".section __ex_table, \"a\"     \n"
-       ".align   2                     \n"
-       ".long    2b, 4b                \n"
-       ".previous                      \n"
-       "5:                             \n"
-       : "=r"(n), "=r"(s), "=r"(res), "=r"(tmp)
-       : "0"(n), "1"(s), "2"(n)
-       : "memory");
-
-       return res;
-}
-EXPORT_SYMBOL(__strnlen_user);
-
 /*
  * __clear_user: - Zero a block of memory in user space, with less checking.
  * @to:   Destination address, in user space.
index 1c6f902..853d6e8 100644 (file)
@@ -19,7 +19,6 @@ asmlinkage long __mulsi3(long, long);
 asmlinkage long __udivsi3(long, long);
 asmlinkage void *memcpy(void *, const void *, size_t);
 asmlinkage void *memset(void *, int, size_t);
-asmlinkage long strncpy_from_user(void *to, void *from, size_t n);
 
        /* gcc lib functions */
 EXPORT_SYMBOL(__ucmpdi2);
@@ -34,4 +33,3 @@ EXPORT_SYMBOL(__mulsi3);
 EXPORT_SYMBOL(__udivsi3);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(strncpy_from_user);
index 685fa83..5911c1f 100644 (file)
@@ -3,7 +3,7 @@
 # Makefile for H8/300-specific library files..
 #
 
-lib-y  = memcpy.o memset.o abs.o strncpy.o \
+lib-y  = memcpy.o memset.o abs.o \
         mulsi3.o udivsi3.o muldi3.o moddivsi3.o \
         ashldi3.o lshrdi3.o ashrdi3.o ucmpdi2.o \
         delay.o
diff --git a/arch/h8300/lib/strncpy.S b/arch/h8300/lib/strncpy.S
deleted file mode 100644 (file)
index 8b65d7c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-;;; SPDX-License-Identifier: GPL-2.0
-;;; strncpy.S
-
-#include <asm/linkage.h>
-
-       .text
-.global strncpy_from_user
-
-;;; long strncpy_from_user(void *to, void *from, size_t n)
-strncpy_from_user:
-       mov.l   er2,er2
-       bne     1f
-       sub.l   er0,er0
-       rts
-1:
-       mov.l   er4,@-sp
-       sub.l   er3,er3
-2:
-       mov.b   @er1+,r4l
-       mov.b   r4l,@er0
-       adds    #1,er0
-       beq     3f
-       inc.l   #1,er3
-       dec.l   #1,er2
-       bne     2b
-3:
-       dec.l   #1,er2
-4:
-       mov.b   r4l,@er0
-       adds    #1,er0
-       dec.l   #1,er2
-       bne     4b
-       mov.l   er3,er0
-       mov.l   @sp+,er4
-       rts
index c1019a7..ef5bfef 100644 (file)
@@ -57,38 +57,7 @@ unsigned long raw_copy_to_user(void __user *to, const void *from,
 __kernel_size_t __clear_user_hexagon(void __user *dest, unsigned long count);
 #define __clear_user(a, s) __clear_user_hexagon((a), (s))
 
-#define __strncpy_from_user(dst, src, n) hexagon_strncpy_from_user(dst, src, n)
-
-/*  get around the ifndef in asm-generic/uaccess.h  */
-#define __strnlen_user __strnlen_user
-
-extern long __strnlen_user(const char __user *src, long n);
-
-static inline long hexagon_strncpy_from_user(char *dst, const char __user *src,
-                                            long n);
-
 #include <asm-generic/uaccess.h>
 
-/*  Todo:  an actual accelerated version of this.  */
-static inline long hexagon_strncpy_from_user(char *dst, const char __user *src,
-                                            long n)
-{
-       long res = __strnlen_user(src, n);
-
-       if (unlikely(!res))
-               return -EFAULT;
-
-       if (res > n) {
-               long left = raw_copy_from_user(dst, src, n);
-               if (unlikely(left))
-                       memset(dst + (n - left), 0, left);
-               return n;
-       } else {
-               long left = raw_copy_from_user(dst, src, res);
-               if (unlikely(left))
-                       memset(dst + (res - left), 0, left);
-               return res-1;
-       }
-}
 
 #endif
index 35545a7..ec56ce2 100644 (file)
@@ -15,7 +15,6 @@ EXPORT_SYMBOL(__clear_user_hexagon);
 EXPORT_SYMBOL(raw_copy_from_user);
 EXPORT_SYMBOL(raw_copy_to_user);
 EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(__strnlen_user);
 EXPORT_SYMBOL(__vmgetie);
 EXPORT_SYMBOL(__vmsetie);
 EXPORT_SYMBOL(__vmyield);
index 8938384..49911a9 100644 (file)
@@ -4,4 +4,4 @@
 #
 
 obj-y := init.o ioremap.o uaccess.o vm_fault.o cache.o
-obj-y += copy_to_user.o copy_from_user.o strnlen_user.o vm_tlb.o
+obj-y += copy_to_user.o copy_from_user.o vm_tlb.o
diff --git a/arch/hexagon/mm/strnlen_user.S b/arch/hexagon/mm/strnlen_user.S
deleted file mode 100644 (file)
index 4b5574a..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * User string length functions for kernel
- *
- * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- */
-
-#define isrc   r0
-#define max    r1      /*  Do not change!  */
-
-#define end    r2
-#define tmp1   r3
-
-#define obo    r6      /*  off-by-one  */
-#define start  r7
-#define mod8   r8
-#define dbuf    r15:14
-#define dcmp   r13:12
-
-/*
- * The vector mask version of this turned out *really* badly.
- * The hardware loop version also turned out *really* badly.
- * Seems straight pointer arithmetic basically wins here.
- */
-
-#define fname __strnlen_user
-
-       .text
-       .global fname
-       .type fname, @function
-       .p2align 5  /*  why?  */
-fname:
-       {
-               mod8 = and(isrc,#7);
-               end = add(isrc,max);
-               start = isrc;
-       }
-       {
-               P0 = cmp.eq(mod8,#0);
-               mod8 = and(end,#7);
-               dcmp = #0;
-               if (P0.new) jump:t dw_loop;     /*  fire up the oven  */
-       }
-
-alignment_loop:
-fail_1:        {
-               tmp1 = memb(start++#1);
-       }
-       {
-               P0 = cmp.eq(tmp1,#0);
-               if (P0.new) jump:nt exit_found;
-               P1 = cmp.gtu(end,start);
-               mod8 = and(start,#7);
-       }
-       {
-               if (!P1) jump exit_error;  /*  hit the end  */
-               P0 = cmp.eq(mod8,#0);
-       }
-       {
-               if (!P0) jump alignment_loop;
-       }
-
-
-
-dw_loop:
-fail_2:        {
-               dbuf = memd(start);
-               obo = add(start,#1);
-       }
-       {
-               P0 = vcmpb.eq(dbuf,dcmp);
-       }
-       {
-               tmp1 = P0;
-               P0 = cmp.gtu(end,start);
-       }
-       {
-               tmp1 = ct0(tmp1);
-               mod8 = and(end,#7);
-               if (!P0) jump end_check;
-       }
-       {
-               P0 = cmp.eq(tmp1,#32);
-               if (!P0.new) jump:nt exit_found;
-               if (!P0.new) start = add(obo,tmp1);
-       }
-       {
-               start = add(start,#8);
-               jump dw_loop;
-       }       /*  might be nice to combine these jumps...   */
-
-
-end_check:
-       {
-               P0 = cmp.gt(tmp1,mod8);
-               if (P0.new) jump:nt exit_error; /*  neverfound!  */
-               start = add(obo,tmp1);
-       }
-
-exit_found:
-       {
-               R0 = sub(start,isrc);
-               jumpr R31;
-       }
-
-exit_error:
-       {
-               R0 = add(max,#1);
-               jumpr R31;
-       }
-
-       /*  Uh, what does the "fixup" return here?  */
-       .falign
-fix_1:
-       {
-               R0 = #0;
-               jumpr R31;
-       }
-
-       .size fname,.-fname
-
-
-.section __ex_table,"a"
-.long fail_1,fix_1
-.long fail_2,fix_1
-.previous
index 4993c7a..045792c 100644 (file)
@@ -9,6 +9,8 @@ menu "Processor type and features"
 config IA64
        bool
        select ARCH_HAS_DMA_MARK_CLEAN
+       select ARCH_HAS_STRNCPY_FROM_USER
+       select ARCH_HAS_STRNLEN_USER
        select ARCH_MIGHT_HAVE_PC_PARPORT
        select ARCH_MIGHT_HAVE_PC_SERIO
        select ACPI
index d632a1d..774c35f 100644 (file)
@@ -16,8 +16,6 @@ config M68K
        select GENERIC_CPU_DEVICES
        select GENERIC_IOMAP
        select GENERIC_IRQ_SHOW
-       select GENERIC_STRNCPY_FROM_USER if MMU
-       select GENERIC_STRNLEN_USER if MMU
        select HAVE_AOUT if MMU
        select HAVE_ASM_MODVERSIONS
        select HAVE_DEBUG_BUGVERBOSE
index c44b594..d2a8ef9 100644 (file)
@@ -35,6 +35,7 @@
 
 # define get_fs()      (current_thread_info()->addr_limit)
 # define set_fs(val)   (current_thread_info()->addr_limit = (val))
+# define user_addr_max() get_fs().seg
 
 # define uaccess_kernel()      (get_fs().seg == KERNEL_DS.seg)
 
@@ -296,28 +297,14 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
 /*
  * Copy a null terminated string from userspace.
  */
-extern int __strncpy_user(char *to, const char __user *from, int len);
-
-static inline long
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       if (!access_ok(src, 1))
-               return -EFAULT;
-       return __strncpy_user(dst, src, count);
-}
+__must_check long strncpy_from_user(char *dst, const char __user *src,
+                                   long count);
 
 /*
  * Return the size of a string (including the ending 0)
  *
  * Return 0 on exception, a value greater than N if too long
  */
-extern int __strnlen_user(const char __user *sstr, int len);
-
-static inline long strnlen_user(const char __user *src, long n)
-{
-       if (!access_ok(src, 1))
-               return 0;
-       return __strnlen_user(src, n);
-}
+__must_check long strnlen_user(const char __user *sstr, long len);
 
 #endif /* _ASM_MICROBLAZE_UACCESS_H */
index 303aaf1..c892e17 100644 (file)
@@ -26,7 +26,6 @@ EXPORT_SYMBOL(_mcount);
  * Assembly functions that may be used (directly or indirectly) by modules
  */
 EXPORT_SYMBOL(__copy_tofrom_user);
-EXPORT_SYMBOL(__strncpy_user);
 
 #ifdef CONFIG_OPT_LIB_ASM
 EXPORT_SYMBOL(memcpy);
index eca2900..dd5f3bf 100644 (file)
 #include <linux/linkage.h>
 #include <asm/page.h>
 
-/*
- * int __strncpy_user(char *to, char *from, int len);
- *
- * Returns:
- *  -EFAULT  for an exception
- *  len      if we hit the buffer limit
- *  bytes copied
- */
-
-       .text
-.globl __strncpy_user;
-.type  __strncpy_user, @function
-.align 4;
-__strncpy_user:
-
-       /*
-        * r5 - to
-        * r6 - from
-        * r7 - len
-        * r3 - temp count
-        * r4 - temp val
-        */
-       beqid   r7,3f
-       addik   r3,r7,0         /* temp_count = len */
-1:
-       lbu     r4,r6,r0
-       beqid   r4,2f
-       sb      r4,r5,r0
-
-       addik   r5,r5,1
-       addik   r6,r6,1         /* delay slot */
-
-       addik   r3,r3,-1
-       bnei    r3,1b           /* break on len */
-2:
-       rsubk   r3,r3,r7        /* temp_count = len - temp_count */
-3:
-       rtsd    r15,8
-       nop
-       .size   __strncpy_user, . - __strncpy_user
-
-       .section        .fixup, "ax"
-       .align  2
-4:
-       brid    3b
-       addik   r3,r0, -EFAULT
-
-       .section        __ex_table, "a"
-       .word   1b,4b
-
-/*
- * int __strnlen_user(char __user *str, int maxlen);
- *
- * Returns:
- *  0 on error
- *  maxlen + 1  if no NUL byte found within maxlen bytes
- *  size of the string (including NUL byte)
- */
-
-       .text
-.globl __strnlen_user;
-.type  __strnlen_user, @function
-.align 4;
-__strnlen_user:
-       beqid   r6,3f
-       addik   r3,r6,0
-1:
-       lbu     r4,r5,r0
-       beqid   r4,2f           /* break on NUL */
-       addik   r3,r3,-1        /* delay slot */
-
-       bneid   r3,1b
-       addik   r5,r5,1         /* delay slot */
-
-       addik   r3,r3,-1        /* for break on len */
-2:
-       rsubk   r3,r3,r6
-3:
-       rtsd    r15,8
-       nop
-       .size   __strnlen_user, . - __strnlen_user
-
-       .section        .fixup,"ax"
-4:
-       brid    3b
-       addk    r3,r0,r0
-
-       .section        __ex_table,"a"
-       .word   1b,4b
-
 /* Loop unrolling for __copy_tofrom_user */
 #define COPY(offset)   \
 1:     lwi     r4 , r6, 0x0000 + offset;       \
index 6dfb27d..24e3742 100644 (file)
@@ -9,6 +9,8 @@ config MIPS
        select ARCH_HAS_KCOV
        select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE if !EVA
        select ARCH_HAS_PTE_SPECIAL if !(32BIT && CPU_HAS_RIXI)
+       select ARCH_HAS_STRNCPY_FROM_USER
+       select ARCH_HAS_STRNLEN_USER
        select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
        select ARCH_HAS_UBSAN_SANITIZE_ALL
        select ARCH_HAS_GCOV_PROFILE_ALL
index 6231390..9c9f387 100644 (file)
@@ -26,8 +26,6 @@ config NDS32
        select GENERIC_LIB_LSHRDI3
        select GENERIC_LIB_MULDI3
        select GENERIC_LIB_UCMPDI2
-       select GENERIC_STRNCPY_FROM_USER
-       select GENERIC_STRNLEN_USER
        select GENERIC_TIME_VSYSCALL
        select HANDLE_DOMAIN_IRQ
        select HAVE_ARCH_TRACEHOOK
index c24955c..3efe553 100644 (file)
@@ -13,8 +13,6 @@ config NIOS2
        select GENERIC_CPU_DEVICES
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
-       select GENERIC_STRNCPY_FROM_USER
-       select GENERIC_STRNLEN_USER
        select HAVE_ARCH_TRACEHOOK
        select HAVE_ARCH_KGDB
        select IRQ_DOMAIN
index 591acc5..50035a9 100644 (file)
@@ -25,8 +25,6 @@ config OPENRISC
        select HAVE_UID16
        select GENERIC_ATOMIC64
        select GENERIC_CLOCKEVENTS_BROADCAST
-       select GENERIC_STRNCPY_FROM_USER
-       select GENERIC_STRNLEN_USER
        select GENERIC_SMP_IDLE_THREAD
        select MODULES_USE_ELF_RELA
        select HAVE_DEBUG_STACKOVERFLOW
index 4f8c1fb..95d4bbf 100644 (file)
@@ -10,6 +10,7 @@ config PARISC
        select ARCH_HAS_ELF_RANDOMIZE
        select ARCH_HAS_STRICT_KERNEL_RWX
        select ARCH_HAS_UBSAN_SANITIZE_ALL
+       select ARCH_HAS_STRNLEN_USER
        select ARCH_NO_SG_CHAIN
        select ARCH_SUPPORTS_HUGETLBFS if PA20
        select ARCH_SUPPORTS_MEMORY_FAILURE
@@ -33,7 +34,6 @@ config PARISC
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_CPU_DEVICES
-       select GENERIC_STRNCPY_FROM_USER
        select GENERIC_LIB_DEVMEM_IS_ALLOWED
        select SYSCTL_ARCH_UNALIGN_ALLOW
        select SYSCTL_EXCEPTION_TRACE
index 663766f..678a0ac 100644 (file)
@@ -183,8 +183,6 @@ config PPC
        select GENERIC_IRQ_SHOW_LEVEL
        select GENERIC_PCI_IOMAP                if PCI
        select GENERIC_SMP_IDLE_THREAD
-       select GENERIC_STRNCPY_FROM_USER
-       select GENERIC_STRNLEN_USER
        select GENERIC_TIME_VSYSCALL
        select GENERIC_VDSO_TIME_NS
        select HAVE_ARCH_AUDITSYSCALL
index 4f7b70a..1452584 100644 (file)
@@ -56,8 +56,6 @@ config RISCV
        select GENERIC_PTDUMP if MMU
        select GENERIC_SCHED_CLOCK
        select GENERIC_SMP_IDLE_THREAD
-       select GENERIC_STRNCPY_FROM_USER if MMU
-       select GENERIC_STRNLEN_USER if MMU
        select GENERIC_TIME_VSYSCALL if MMU && 64BIT
        select HANDLE_DOMAIN_IRQ
        select HAVE_ARCH_AUDITSYSCALL
index 2316f24..9ed9aa3 100644 (file)
@@ -233,23 +233,9 @@ raw_copy_in_user(void __user *to, const void __user *from, unsigned long n);
 /*
  * Copy a null terminated string from userspace.
  */
+long __must_check strncpy_from_user(char *dst, const char __user *src, long count);
 
-long __strncpy_from_user(char *dst, const char __user *src, long count);
-
-static inline long __must_check
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       might_fault();
-       return __strncpy_from_user(dst, src, count);
-}
-
-unsigned long __must_check __strnlen_user(const char __user *src, unsigned long count);
-
-static inline unsigned long strnlen_user(const char __user *src, unsigned long n)
-{
-       might_fault();
-       return __strnlen_user(src, n);
-}
+long __must_check strnlen_user(const char __user *src, long count);
 
 /*
  * Zero Userspace
index 7ec8b1f..94ca99b 100644 (file)
@@ -338,55 +338,3 @@ unsigned long __clear_user(void __user *to, unsigned long size)
        return clear_user_xc(to, size);
 }
 EXPORT_SYMBOL(__clear_user);
-
-static inline unsigned long strnlen_user_srst(const char __user *src,
-                                             unsigned long size)
-{
-       unsigned long tmp1, tmp2;
-
-       asm volatile(
-               "   lghi  0,0\n"
-               "   la    %2,0(%1)\n"
-               "   la    %3,0(%0,%1)\n"
-               "   slgr  %0,%0\n"
-               "   sacf  256\n"
-               "0: srst  %3,%2\n"
-               "   jo    0b\n"
-               "   la    %0,1(%3)\n"   /* strnlen_user results includes \0 */
-               "   slgr  %0,%1\n"
-               "1: sacf  768\n"
-               EX_TABLE(0b,1b)
-               : "+a" (size), "+a" (src), "=a" (tmp1), "=a" (tmp2)
-               :
-               : "cc", "memory", "0");
-       return size;
-}
-
-unsigned long __strnlen_user(const char __user *src, unsigned long size)
-{
-       if (unlikely(!size))
-               return 0;
-       return strnlen_user_srst(src, size);
-}
-EXPORT_SYMBOL(__strnlen_user);
-
-long __strncpy_from_user(char *dst, const char __user *src, long size)
-{
-       size_t done, len, offset, len_str;
-
-       if (unlikely(size <= 0))
-               return 0;
-       done = 0;
-       do {
-               offset = (size_t)src & (L1_CACHE_BYTES - 1);
-               len = min(size - done, L1_CACHE_BYTES - offset);
-               if (copy_from_user(dst, src, len))
-                       return -EFAULT;
-               len_str = strnlen(dst, len);
-               done += len_str;
-               src += len_str;
-               dst += len_str;
-       } while ((len_str == len) && (done < size));
-       return done;
-}
-EXPORT_SYMBOL(__strncpy_from_user);
index b683b69..f37280e 100644 (file)
@@ -22,8 +22,6 @@ config SUPERH
        select GENERIC_IRQ_SHOW
        select GENERIC_PCI_IOMAP if PCI
        select GENERIC_SCHED_CLOCK
-       select GENERIC_STRNCPY_FROM_USER
-       select GENERIC_STRNLEN_USER
        select GENERIC_SMP_IDLE_THREAD
        select GUP_GET_PTE_LOW_HIGH if X2TLB
        select HAVE_ARCH_AUDITSYSCALL
index f0c0f95..fa650e4 100644 (file)
@@ -37,8 +37,6 @@ config SPARC
        select HAVE_EBPF_JIT if SPARC64
        select HAVE_DEBUG_BUGVERBOSE
        select GENERIC_SMP_IDLE_THREAD
-       select GENERIC_STRNCPY_FROM_USER
-       select GENERIC_STRNLEN_USER
        select MODULES_USE_ELF_RELA
        select PCI_SYSCALL if PCI
        select PCI_MSI_ARCH_FALLBACKS if PCI_MSI
index 0561b73..77e66d3 100644 (file)
@@ -7,6 +7,8 @@ config UML
        default y
        select ARCH_EPHEMERAL_INODES
        select ARCH_HAS_KCOV
+       select ARCH_HAS_STRNCPY_FROM_USER
+       select ARCH_HAS_STRNLEN_USER
        select ARCH_NO_PREEMPT
        select HAVE_ARCH_AUDITSYSCALL
        select HAVE_ARCH_SECCOMP_FILTER
index fe66d65..191ef36 100644 (file)
 
 extern unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n);
 extern unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n);
-extern long __strncpy_from_user(char *dst, const char __user *src, long count);
-extern long __strnlen_user(const void __user *str, long len);
 extern unsigned long __clear_user(void __user *mem, unsigned long len);
 static inline int __access_ok(unsigned long addr, unsigned long size);
 
 /* Teach asm-generic/uaccess.h that we have C functions for these. */
 #define __access_ok __access_ok
 #define __clear_user __clear_user
-#define __strnlen_user __strnlen_user
-#define __strncpy_from_user __strncpy_from_user
+
 #define INLINE_COPY_FROM_USER
 #define INLINE_COPY_TO_USER
 
index 6c76df9..a509be9 100644 (file)
@@ -189,11 +189,14 @@ static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
        return 0;
 }
 
-long __strncpy_from_user(char *dst, const char __user *src, long count)
+long strncpy_from_user(char *dst, const char __user *src, long count)
 {
        long n;
        char *ptr = dst;
 
+       if (!access_ok(src, 1))
+               return -EFAULT;
+
        if (uaccess_kernel()) {
                strncpy(dst, (__force void *) src, count);
                return strnlen(dst, count);
@@ -205,7 +208,7 @@ long __strncpy_from_user(char *dst, const char __user *src, long count)
                return -EFAULT;
        return strnlen(dst, count);
 }
-EXPORT_SYMBOL(__strncpy_from_user);
+EXPORT_SYMBOL(strncpy_from_user);
 
 static int clear_chunk(unsigned long addr, int len, void *unused)
 {
@@ -236,10 +239,13 @@ static int strnlen_chunk(unsigned long str, int len, void *arg)
        return 0;
 }
 
-long __strnlen_user(const void __user *str, long len)
+long strnlen_user(const char __user *str, long len)
 {
        int count = 0, n;
 
+       if (!access_ok(str, 1))
+               return -EFAULT;
+
        if (uaccess_kernel())
                return strnlen((__force char*)str, len) + 1;
 
@@ -248,7 +254,7 @@ long __strnlen_user(const void __user *str, long len)
                return count + 1;
        return 0;
 }
-EXPORT_SYMBOL(__strnlen_user);
+EXPORT_SYMBOL(strnlen_user);
 
 /**
  * arch_futex_atomic_op_inuser() - Atomic arithmetic operation with constant
index 45962aa..1146b85 100644 (file)
@@ -145,8 +145,6 @@ config X86
        select GENERIC_PENDING_IRQ              if SMP
        select GENERIC_PTDUMP
        select GENERIC_SMP_IDLE_THREAD
-       select GENERIC_STRNCPY_FROM_USER
-       select GENERIC_STRNLEN_USER
        select GENERIC_TIME_VSYSCALL
        select GENERIC_GETTIMEOFDAY
        select GENERIC_VDSO_TIME_NS
index 3878880..f02b885 100644 (file)
@@ -7,6 +7,8 @@ config XTENSA
        select ARCH_HAS_SYNC_DMA_FOR_CPU if MMU
        select ARCH_HAS_SYNC_DMA_FOR_DEVICE if MMU
        select ARCH_HAS_DMA_SET_UNCACHED if MMU
+       select ARCH_HAS_STRNCPY_FROM_USER if !KASAN
+       select ARCH_HAS_STRNLEN_USER
        select ARCH_USE_MEMTEST
        select ARCH_USE_QUEUED_RWLOCKS
        select ARCH_USE_QUEUED_SPINLOCKS
@@ -20,7 +22,6 @@ config XTENSA
        select GENERIC_IRQ_SHOW
        select GENERIC_PCI_IOMAP
        select GENERIC_SCHED_CLOCK
-       select GENERIC_STRNCPY_FROM_USER if KASAN
        select HAVE_ARCH_AUDITSYSCALL
        select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
        select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL
index 5c9fb80..75bd8fb 100644 (file)
@@ -290,8 +290,7 @@ clear_user(void __user *addr, unsigned long size)
 #define __clear_user  __xtensa_clear_user
 
 
-#ifndef CONFIG_GENERIC_STRNCPY_FROM_USER
-
+#ifdef CONFIG_ARCH_HAS_STRNCPY_FROM_USER
 extern long __strncpy_user(char *dst, const char __user *src, long count);
 
 static inline long
index 415fe7f..d79edbb 100644 (file)
@@ -43,7 +43,7 @@ EXPORT_SYMBOL(memmove);
 EXPORT_SYMBOL(__memset);
 EXPORT_SYMBOL(__memcpy);
 EXPORT_SYMBOL(__memmove);
-#ifndef CONFIG_GENERIC_STRNCPY_FROM_USER
+#ifdef CONFIG_ARCH_HAS_STRNCPY_FROM_USER
 EXPORT_SYMBOL(__strncpy_user);
 #endif
 EXPORT_SYMBOL(clear_page);
index 1dacfdb..7b12932 100644 (file)
@@ -8,7 +8,7 @@
  *
  * This is defined the same way as
  * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
+ * differs in spirit from ffz (man ffs).
  */
 #define ffs(x) __builtin_ffs(x)
 
index e81868b..323fd5d 100644 (file)
@@ -8,7 +8,7 @@
  *
  * This is defined the same way as
  * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
+ * differs in spirit from ffz (man ffs).
  */
 static inline int ffs(int x)
 {
index 365377f..078cc68 100644 (file)
@@ -14,7 +14,7 @@
  * may be that only one operation succeeds.
  */
 static __always_inline void
-arch___set_bit(int nr, volatile unsigned long *addr)
+arch___set_bit(unsigned int nr, volatile unsigned long *addr)
 {
        unsigned long mask = BIT_MASK(nr);
        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
@@ -24,7 +24,7 @@ arch___set_bit(int nr, volatile unsigned long *addr)
 #define __set_bit arch___set_bit
 
 static __always_inline void
-arch___clear_bit(int nr, volatile unsigned long *addr)
+arch___clear_bit(unsigned int nr, volatile unsigned long *addr)
 {
        unsigned long mask = BIT_MASK(nr);
        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
@@ -43,7 +43,7 @@ arch___clear_bit(int nr, volatile unsigned long *addr)
  * may be that only one operation succeeds.
  */
 static __always_inline
-void arch___change_bit(int nr, volatile unsigned long *addr)
+void arch___change_bit(unsigned int nr, volatile unsigned long *addr)
 {
        unsigned long mask = BIT_MASK(nr);
        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
@@ -62,7 +62,7 @@ void arch___change_bit(int nr, volatile unsigned long *addr)
  * but actually fail.  You must protect multiple accesses with a lock.
  */
 static __always_inline int
-arch___test_and_set_bit(int nr, volatile unsigned long *addr)
+arch___test_and_set_bit(unsigned int nr, volatile unsigned long *addr)
 {
        unsigned long mask = BIT_MASK(nr);
        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
@@ -83,7 +83,7 @@ arch___test_and_set_bit(int nr, volatile unsigned long *addr)
  * but actually fail.  You must protect multiple accesses with a lock.
  */
 static __always_inline int
-arch___test_and_clear_bit(int nr, volatile unsigned long *addr)
+arch___test_and_clear_bit(unsigned int nr, volatile unsigned long *addr)
 {
        unsigned long mask = BIT_MASK(nr);
        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
@@ -96,7 +96,7 @@ arch___test_and_clear_bit(int nr, volatile unsigned long *addr)
 
 /* WARNING: non atomic and it can be reordered! */
 static __always_inline int
-arch___test_and_change_bit(int nr, volatile unsigned long *addr)
+arch___test_and_change_bit(unsigned int nr, volatile unsigned long *addr)
 {
        unsigned long mask = BIT_MASK(nr);
        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
@@ -113,7 +113,7 @@ arch___test_and_change_bit(int nr, volatile unsigned long *addr)
  * @addr: Address to start counting from
  */
 static __always_inline int
-arch_test_bit(int nr, const volatile unsigned long *addr)
+arch_test_bit(unsigned int nr, const volatile unsigned long *addr)
 {
        return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
 }
index a0b2f27..10ffa8b 100644 (file)
@@ -119,6 +119,11 @@ static inline void set_fs(mm_segment_t fs)
 #ifndef uaccess_kernel
 #define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
 #endif
+
+#ifndef user_addr_max
+#define user_addr_max() (uaccess_kernel() ? ~0UL : TASK_SIZE)
+#endif
+
 #endif /* CONFIG_SET_FS */
 
 #define access_ok(addr, size) __access_ok((unsigned long)(addr),(size))
@@ -243,50 +248,6 @@ static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
 
 extern int __get_user_bad(void) __attribute__((noreturn));
 
-/*
- * Copy a null terminated string from userspace.
- */
-#ifndef __strncpy_from_user
-static inline long
-__strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       char *tmp;
-       strncpy(dst, (const char __force *)src, count);
-       for (tmp = dst; *tmp && count > 0; tmp++, count--)
-               ;
-       return (tmp - dst);
-}
-#endif
-
-static inline long
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       if (!access_ok(src, 1))
-               return -EFAULT;
-       return __strncpy_from_user(dst, src, count);
-}
-
-/*
- * Return the size of a string (including the ending 0)
- *
- * Return 0 on exception, a value greater than N if too long
- */
-#ifndef __strnlen_user
-#define __strnlen_user(s, n) (strnlen((s), (n)) + 1)
-#endif
-
-/*
- * Unlike strnlen, strnlen_user includes the nul terminator in
- * its returned count. Callers should check for a returned value
- * greater than N as an indication the string is too long.
- */
-static inline long strnlen_user(const char __user *src, long n)
-{
-       if (!access_ok(src, 1))
-               return 0;
-       return __strnlen_user(src, n);
-}
-
 /*
  * Zero Userspace
  */
@@ -311,4 +272,8 @@ clear_user(void __user *to, unsigned long n)
 
 #include <asm/extable.h>
 
+__must_check long strncpy_from_user(char *dst, const char __user *src,
+                                   long count);
+__must_check long strnlen_user(const char __user *src, long n);
+
 #endif /* __ASM_GENERIC_UACCESS_H */
index 5c9c068..5e7165e 100644 (file)
@@ -50,12 +50,18 @@ config HAVE_ARCH_BITREVERSE
          This option enables the use of hardware bit-reversal instructions on
          architectures which support such operations.
 
-config GENERIC_STRNCPY_FROM_USER
+config ARCH_HAS_STRNCPY_FROM_USER
        bool
 
-config GENERIC_STRNLEN_USER
+config ARCH_HAS_STRNLEN_USER
        bool
 
+config GENERIC_STRNCPY_FROM_USER
+       def_bool !ARCH_HAS_STRNCPY_FROM_USER
+
+config GENERIC_STRNLEN_USER
+       def_bool !ARCH_HAS_STRNLEN_USER
+
 config GENERIC_NET_UTILS
        bool