diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-26 19:57:16 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-26 19:57:16 -0400 |
| commit | 1e2aec873ad6d16538512dbb96853caa1fa076af (patch) | |
| tree | d792b19ac47be44debd24610ae27f1330fa490e4 | |
| parent | ae32adc1e06d096399f195eeda12d443d53539c4 (diff) | |
| parent | 2c66f623631709aa5f2e4c14c7e089682e7394a3 (diff) | |
Merge branch 'generic-string-functions'
This makes <asm/word-at-a-time.h> actually live up to its promise of
allowing architectures to help tune the string functions that do their
work a word at a time.
David had already taken the x86 strncpy_from_user() function, modified
it to work on sparc, and then done the extra work to make it generically
useful. This then expands on that work by making x86 use that generic
version, completing the circle.
But more importantly, it fixes up the word-at-a-time interfaces so that
it's now easy to also support things like strnlen_user(), and pretty
much most random string functions.
David reports that it all works fine on sparc, and Jonas Bonn reported
that an earlier version of this worked on OpenRISC too. It's pretty
easy for architectures to add support for this and just replace their
private versions with the generic code.
* generic-string-functions:
sparc: use the new generic strnlen_user() function
x86: use the new generic strnlen_user() function
lib: add generic strnlen_user() function
word-at-a-time: make the interfaces truly generic
x86: use generic strncpy_from_user routine
| -rw-r--r-- | arch/openrisc/include/asm/Kbuild | 1 | ||||
| -rw-r--r-- | arch/sparc/Kconfig | 1 | ||||
| -rw-r--r-- | arch/sparc/include/asm/Kbuild | 1 | ||||
| -rw-r--r-- | arch/sparc/include/asm/uaccess_32.h | 22 | ||||
| -rw-r--r-- | arch/sparc/include/asm/uaccess_64.h | 8 | ||||
| -rw-r--r-- | arch/sparc/lib/Makefile | 1 | ||||
| -rw-r--r-- | arch/sparc/lib/ksyms.c | 2 | ||||
| -rw-r--r-- | arch/sparc/lib/strlen_user_32.S | 109 | ||||
| -rw-r--r-- | arch/sparc/lib/strlen_user_64.S | 97 | ||||
| -rw-r--r-- | arch/x86/Kconfig | 2 | ||||
| -rw-r--r-- | arch/x86/include/asm/uaccess.h | 4 | ||||
| -rw-r--r-- | arch/x86/include/asm/uaccess_32.h | 17 | ||||
| -rw-r--r-- | arch/x86/include/asm/uaccess_64.h | 3 | ||||
| -rw-r--r-- | arch/x86/include/asm/word-at-a-time.h | 32 | ||||
| -rw-r--r-- | arch/x86/lib/usercopy.c | 97 | ||||
| -rw-r--r-- | arch/x86/lib/usercopy_32.c | 41 | ||||
| -rw-r--r-- | arch/x86/lib/usercopy_64.c | 48 | ||||
| -rw-r--r-- | fs/namei.c | 22 | ||||
| -rw-r--r-- | include/asm-generic/word-at-a-time.h | 52 | ||||
| -rw-r--r-- | lib/Kconfig | 3 | ||||
| -rw-r--r-- | lib/Makefile | 1 | ||||
| -rw-r--r-- | lib/strncpy_from_user.c | 47 | ||||
| -rw-r--r-- | lib/strnlen_user.c | 138 |
23 files changed, 259 insertions, 490 deletions
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild index c936483bc8e2..3f35c38d7b64 100644 --- a/arch/openrisc/include/asm/Kbuild +++ b/arch/openrisc/include/asm/Kbuild | |||
| @@ -66,3 +66,4 @@ generic-y += topology.h | |||
| 66 | generic-y += types.h | 66 | generic-y += types.h |
| 67 | generic-y += ucontext.h | 67 | generic-y += ucontext.h |
| 68 | generic-y += user.h | 68 | generic-y += user.h |
| 69 | generic-y += word-at-a-time.h | ||
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 15e9e05740da..83bd051754e1 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
| @@ -35,6 +35,7 @@ config SPARC | |||
| 35 | select GENERIC_CMOS_UPDATE | 35 | select GENERIC_CMOS_UPDATE |
| 36 | select GENERIC_CLOCKEVENTS | 36 | select GENERIC_CLOCKEVENTS |
| 37 | select GENERIC_STRNCPY_FROM_USER | 37 | select GENERIC_STRNCPY_FROM_USER |
| 38 | select GENERIC_STRNLEN_USER | ||
| 38 | 39 | ||
| 39 | config SPARC32 | 40 | config SPARC32 |
| 40 | def_bool !64BIT | 41 | def_bool !64BIT |
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index 2c2e38821f60..67f83e0a0d68 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild | |||
| @@ -21,3 +21,4 @@ generic-y += div64.h | |||
| 21 | generic-y += local64.h | 21 | generic-y += local64.h |
| 22 | generic-y += irq_regs.h | 22 | generic-y += irq_regs.h |
| 23 | generic-y += local.h | 23 | generic-y += local.h |
| 24 | generic-y += word-at-a-time.h | ||
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h index 59586b57ef1a..53a28dd59f59 100644 --- a/arch/sparc/include/asm/uaccess_32.h +++ b/arch/sparc/include/asm/uaccess_32.h | |||
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | ||
| 17 | #ifndef __ASSEMBLY__ | 17 | #ifndef __ASSEMBLY__ |
| 18 | 18 | ||
| 19 | #include <asm/processor.h> | ||
| 20 | |||
| 19 | #define ARCH_HAS_SORT_EXTABLE | 21 | #define ARCH_HAS_SORT_EXTABLE |
| 20 | #define ARCH_HAS_SEARCH_EXTABLE | 22 | #define ARCH_HAS_SEARCH_EXTABLE |
| 21 | 23 | ||
| @@ -304,24 +306,8 @@ static inline unsigned long clear_user(void __user *addr, unsigned long n) | |||
| 304 | return n; | 306 | return n; |
| 305 | } | 307 | } |
| 306 | 308 | ||
| 307 | extern long __strlen_user(const char __user *); | 309 | extern __must_check long strlen_user(const char __user *str); |
| 308 | extern long __strnlen_user(const char __user *, long len); | 310 | extern __must_check long strnlen_user(const char __user *str, long n); |
| 309 | |||
| 310 | static inline long strlen_user(const char __user *str) | ||
| 311 | { | ||
| 312 | if (!access_ok(VERIFY_READ, str, 0)) | ||
| 313 | return 0; | ||
| 314 | else | ||
| 315 | return __strlen_user(str); | ||
| 316 | } | ||
| 317 | |||
| 318 | static inline long strnlen_user(const char __user *str, long len) | ||
| 319 | { | ||
| 320 | if (!access_ok(VERIFY_READ, str, 0)) | ||
| 321 | return 0; | ||
| 322 | else | ||
| 323 | return __strnlen_user(str, len); | ||
| 324 | } | ||
| 325 | 311 | ||
| 326 | #endif /* __ASSEMBLY__ */ | 312 | #endif /* __ASSEMBLY__ */ |
| 327 | 313 | ||
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h index dcdfb89cbf3f..7c831d848b4e 100644 --- a/arch/sparc/include/asm/uaccess_64.h +++ b/arch/sparc/include/asm/uaccess_64.h | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | 17 | ||
| 18 | #ifndef __ASSEMBLY__ | 18 | #ifndef __ASSEMBLY__ |
| 19 | 19 | ||
| 20 | #include <asm/processor.h> | ||
| 21 | |||
| 20 | /* | 22 | /* |
| 21 | * Sparc64 is segmented, though more like the M68K than the I386. | 23 | * Sparc64 is segmented, though more like the M68K than the I386. |
| 22 | * We use the secondary ASI to address user memory, which references a | 24 | * We use the secondary ASI to address user memory, which references a |
| @@ -257,11 +259,9 @@ extern unsigned long __must_check __clear_user(void __user *, unsigned long); | |||
| 257 | 259 | ||
| 258 | #define clear_user __clear_user | 260 | #define clear_user __clear_user |
| 259 | 261 | ||
| 260 | extern long __strlen_user(const char __user *); | 262 | extern __must_check long strlen_user(const char __user *str); |
| 261 | extern long __strnlen_user(const char __user *, long len); | 263 | extern __must_check long strnlen_user(const char __user *str, long n); |
| 262 | 264 | ||
| 263 | #define strlen_user __strlen_user | ||
| 264 | #define strnlen_user __strnlen_user | ||
| 265 | #define __copy_to_user_inatomic ___copy_to_user | 265 | #define __copy_to_user_inatomic ___copy_to_user |
| 266 | #define __copy_from_user_inatomic ___copy_from_user | 266 | #define __copy_from_user_inatomic ___copy_from_user |
| 267 | 267 | ||
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index 943d98dc4cdb..dff4096f3dec 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile | |||
| @@ -10,7 +10,6 @@ lib-y += strlen.o | |||
| 10 | lib-y += checksum_$(BITS).o | 10 | lib-y += checksum_$(BITS).o |
| 11 | lib-$(CONFIG_SPARC32) += blockops.o | 11 | lib-$(CONFIG_SPARC32) += blockops.o |
| 12 | lib-y += memscan_$(BITS).o memcmp.o strncmp_$(BITS).o | 12 | lib-y += memscan_$(BITS).o memcmp.o strncmp_$(BITS).o |
| 13 | lib-y += strlen_user_$(BITS).o | ||
| 14 | lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o | 13 | lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o |
| 15 | lib-$(CONFIG_SPARC32) += copy_user.o locks.o | 14 | lib-$(CONFIG_SPARC32) += copy_user.o locks.o |
| 16 | lib-$(CONFIG_SPARC64) += atomic_64.o | 15 | lib-$(CONFIG_SPARC64) += atomic_64.o |
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c index 6b278abdb63d..3b31218cafc6 100644 --- a/arch/sparc/lib/ksyms.c +++ b/arch/sparc/lib/ksyms.c | |||
| @@ -15,8 +15,6 @@ | |||
| 15 | 15 | ||
| 16 | /* string functions */ | 16 | /* string functions */ |
| 17 | EXPORT_SYMBOL(strlen); | 17 | EXPORT_SYMBOL(strlen); |
| 18 | EXPORT_SYMBOL(__strlen_user); | ||
| 19 | EXPORT_SYMBOL(__strnlen_user); | ||
| 20 | EXPORT_SYMBOL(strncmp); | 18 | EXPORT_SYMBOL(strncmp); |
| 21 | 19 | ||
| 22 | /* mem* functions */ | 20 | /* mem* functions */ |
diff --git a/arch/sparc/lib/strlen_user_32.S b/arch/sparc/lib/strlen_user_32.S deleted file mode 100644 index 8c8a371df3c9..000000000000 --- a/arch/sparc/lib/strlen_user_32.S +++ /dev/null | |||
| @@ -1,109 +0,0 @@ | |||
| 1 | /* strlen_user.S: Sparc optimized strlen_user code | ||
| 2 | * | ||
| 3 | * Return length of string in userspace including terminating 0 | ||
| 4 | * or 0 for error | ||
| 5 | * | ||
| 6 | * Copyright (C) 1991,1996 Free Software Foundation | ||
| 7 | * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) | ||
| 8 | * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
| 9 | */ | ||
| 10 | |||
| 11 | #define LO_MAGIC 0x01010101 | ||
| 12 | #define HI_MAGIC 0x80808080 | ||
| 13 | |||
| 14 | 10: | ||
| 15 | ldub [%o0], %o5 | ||
| 16 | cmp %o5, 0 | ||
| 17 | be 1f | ||
| 18 | add %o0, 1, %o0 | ||
| 19 | andcc %o0, 3, %g0 | ||
| 20 | be 4f | ||
| 21 | or %o4, %lo(HI_MAGIC), %o3 | ||
| 22 | 11: | ||
| 23 | ldub [%o0], %o5 | ||
| 24 | cmp %o5, 0 | ||
| 25 | be 2f | ||
| 26 | add %o0, 1, %o0 | ||
| 27 | andcc %o0, 3, %g0 | ||
| 28 | be 5f | ||
| 29 | sethi %hi(LO_MAGIC), %o4 | ||
