From: Greg Kroah-Hartman Date: Sat, 5 Aug 2017 02:54:37 +0000 (-0700) Subject: 3.18-stable patches X-Git-Tag: v4.12.5~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f395c747fa0236d670c11845f49d619c25741150;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: tile-add-asm-word-at-a-time.h-and-enable-support-functions.patch word-at-a-time.h-support-zero_bytemask-on-alpha-and-tile.patch --- diff --git a/queue-3.18/series b/queue-3.18/series index 404c73c63fc..30819e62407 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -48,3 +48,5 @@ asoc-tlv320aic3x-mark-the-reset-register-as-volatile.patch spi-dw-make-debugfs-name-unique-between-instances.patch vlan-propagate-mac-address-to-vlans.patch xfrm-don-t-use-sk_family-for-socket-policy-lookups.patch +tile-add-asm-word-at-a-time.h-and-enable-support-functions.patch +word-at-a-time.h-support-zero_bytemask-on-alpha-and-tile.patch diff --git a/queue-3.18/tile-add-asm-word-at-a-time.h-and-enable-support-functions.patch b/queue-3.18/tile-add-asm-word-at-a-time.h-and-enable-support-functions.patch new file mode 100644 index 00000000000..0ff68a1f685 --- /dev/null +++ b/queue-3.18/tile-add-asm-word-at-a-time.h-and-enable-support-functions.patch @@ -0,0 +1,280 @@ +From 5bf6c07a1843813d0065feaaecba622d49148d7e Mon Sep 17 00:00:00 2001 +From: Chris Metcalf +Date: Thu, 30 Apr 2015 15:12:42 -0400 +Subject: tile: add and enable support functions + +From: Chris Metcalf + +commit 5bf6c07a1843813d0065feaaecba622d49148d7e upstream. + +This change enables the generic strncpy_from_user() and strnlen_user() +using word-at-a-time.h. The tile implementation is trivial since +both tilepro and tilegx have SIMD operations that do byte-wise +comparisons against immediate zero for each byte, and return an +0x01 byte in each position where there is a 0x00 byte. + +Signed-off-by: Chris Metcalf +Signed-off-by: Greg Kroah-Hartman + +--- + arch/tile/Kconfig | 2 + + arch/tile/include/asm/uaccess.h | 66 +++++---------------------------- + arch/tile/include/asm/word-at-a-time.h | 36 ++++++++++++++++++ + arch/tile/lib/exports.c | 2 - + arch/tile/lib/usercopy_32.S | 46 ----------------------- + arch/tile/lib/usercopy_64.S | 46 ----------------------- + 6 files changed, 48 insertions(+), 150 deletions(-) + +--- a/arch/tile/Kconfig ++++ b/arch/tile/Kconfig +@@ -27,6 +27,8 @@ config TILE + select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE + select HAVE_DEBUG_STACKOVERFLOW + select ARCH_WANT_FRAME_POINTERS ++ select GENERIC_STRNCPY_FROM_USER ++ select GENERIC_STRNLEN_USER + + # FIXME: investigate whether we need/want these options. + # select HAVE_IOREMAP_PROT +--- a/arch/tile/include/asm/uaccess.h ++++ b/arch/tile/include/asm/uaccess.h +@@ -65,6 +65,13 @@ static inline int is_arch_mappable_range + #endif + + /* ++ * Note that using this definition ignores is_arch_mappable_range(), ++ * so on tilepro code that uses user_addr_max() is constrained not ++ * to reference the tilepro user-interrupt region. ++ */ ++#define user_addr_max() (current_thread_info()->addr_limit.seg) ++ ++/* + * Test whether a block of memory is a valid user space address. + * Returns 0 if the range is valid, nonzero otherwise. + */ +@@ -462,62 +469,9 @@ copy_in_user(void __user *to, const void + #endif + + +-/** +- * 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. +- */ +-extern long strnlen_user_asm(const char __user *str, long n); +-static inline long __must_check strnlen_user(const char __user *str, long n) +-{ +- might_fault(); +- return strnlen_user_asm(str, n); +-} +-#define strlen_user(str) strnlen_user(str, LONG_MAX) +- +-/** +- * 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. +- */ +-extern long strncpy_from_user_asm(char *dst, const char __user *src, long); +-static inline long __must_check __strncpy_from_user( +- char *dst, const char __user *src, long count) +-{ +- might_fault(); +- return strncpy_from_user_asm(dst, src, count); +-} +-static inline long __must_check 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; +-} ++extern long strnlen_user(const char __user *str, long n); ++extern long strlen_user(const char __user *str); ++extern long strncpy_from_user(char *dst, const char __user *src, long); + + /** + * clear_user: - Zero a block of memory in user space. +--- /dev/null ++++ b/arch/tile/include/asm/word-at-a-time.h +@@ -0,0 +1,36 @@ ++#ifndef _ASM_WORD_AT_A_TIME_H ++#define _ASM_WORD_AT_A_TIME_H ++ ++#include ++ ++struct word_at_a_time { /* unused */ }; ++#define WORD_AT_A_TIME_CONSTANTS {} ++ ++/* Generate 0x01 byte values for non-zero bytes using a SIMD instruction. */ ++static inline unsigned long has_zero(unsigned long val, unsigned long *data, ++ const struct word_at_a_time *c) ++{ ++#ifdef __tilegx__ ++ unsigned long mask = __insn_v1cmpeqi(val, 0); ++#else /* tilepro */ ++ unsigned long mask = __insn_seqib(val, 0); ++#endif ++ *data = mask; ++ return mask; ++} ++ ++/* These operations are both nops. */ ++#define prep_zero_mask(val, data, c) (data) ++#define create_zero_mask(data) (data) ++ ++/* And this operation just depends on endianness. */ ++static inline long find_zero(unsigned long mask) ++{ ++#ifdef __BIG_ENDIAN ++ return __builtin_clzl(mask) >> 3; ++#else ++ return __builtin_ctzl(mask) >> 3; ++#endif ++} ++ ++#endif /* _ASM_WORD_AT_A_TIME_H */ +--- a/arch/tile/lib/exports.c ++++ b/arch/tile/lib/exports.c +@@ -18,8 +18,6 @@ + + /* arch/tile/lib/usercopy.S */ + #include +-EXPORT_SYMBOL(strnlen_user_asm); +-EXPORT_SYMBOL(strncpy_from_user_asm); + EXPORT_SYMBOL(clear_user_asm); + EXPORT_SYMBOL(flush_user_asm); + EXPORT_SYMBOL(finv_user_asm); +--- a/arch/tile/lib/usercopy_32.S ++++ b/arch/tile/lib/usercopy_32.S +@@ -20,52 +20,6 @@ + /* Access user memory, but use MMU to avoid propagating kernel exceptions. */ + + /* +- * strnlen_user_asm takes the pointer in r0, and the length bound in r1. +- * It returns the length, including the terminating NUL, or zero on exception. +- * If length is greater than the bound, returns one plus the bound. +- */ +-STD_ENTRY(strnlen_user_asm) +- { bz r1, 2f; addi r3, r0, -1 } /* bias down to include NUL */ +-1: { lb_u r4, r0; addi r1, r1, -1 } +- bz r4, 2f +- { bnzt r1, 1b; addi r0, r0, 1 } +-2: { sub r0, r0, r3; jrp lr } +- STD_ENDPROC(strnlen_user_asm) +- .pushsection .fixup,"ax" +-strnlen_user_fault: +- { move r0, zero; jrp lr } +- ENDPROC(strnlen_user_fault) +- .section __ex_table,"a" +- .align 4 +- .word 1b, strnlen_user_fault +- .popsection +- +-/* +- * strncpy_from_user_asm takes the kernel target pointer in r0, +- * the userspace source pointer in r1, and the length bound (including +- * the trailing NUL) in r2. On success, it returns the string length +- * (not including the trailing NUL), or -EFAULT on failure. +- */ +-STD_ENTRY(strncpy_from_user_asm) +- { bz r2, 2f; move r3, r0 } +-1: { lb_u r4, r1; addi r1, r1, 1; addi r2, r2, -1 } +- { sb r0, r4; addi r0, r0, 1 } +- bz r4, 2f +- bnzt r2, 1b +- { sub r0, r0, r3; jrp lr } +-2: addi r0, r0, -1 /* don't count the trailing NUL */ +- { sub r0, r0, r3; jrp lr } +- STD_ENDPROC(strncpy_from_user_asm) +- .pushsection .fixup,"ax" +-strncpy_from_user_fault: +- { movei r0, -EFAULT; jrp lr } +- ENDPROC(strncpy_from_user_fault) +- .section __ex_table,"a" +- .align 4 +- .word 1b, strncpy_from_user_fault +- .popsection +- +-/* + * clear_user_asm takes the user target address in r0 and the + * number of bytes to zero in r1. + * It returns the number of uncopiable bytes (hopefully zero) in r0. +--- a/arch/tile/lib/usercopy_64.S ++++ b/arch/tile/lib/usercopy_64.S +@@ -20,52 +20,6 @@ + /* Access user memory, but use MMU to avoid propagating kernel exceptions. */ + + /* +- * strnlen_user_asm takes the pointer in r0, and the length bound in r1. +- * It returns the length, including the terminating NUL, or zero on exception. +- * If length is greater than the bound, returns one plus the bound. +- */ +-STD_ENTRY(strnlen_user_asm) +- { beqz r1, 2f; addi r3, r0, -1 } /* bias down to include NUL */ +-1: { ld1u r4, r0; addi r1, r1, -1 } +- beqz r4, 2f +- { bnezt r1, 1b; addi r0, r0, 1 } +-2: { sub r0, r0, r3; jrp lr } +- STD_ENDPROC(strnlen_user_asm) +- .pushsection .fixup,"ax" +-strnlen_user_fault: +- { move r0, zero; jrp lr } +- ENDPROC(strnlen_user_fault) +- .section __ex_table,"a" +- .align 8 +- .quad 1b, strnlen_user_fault +- .popsection +- +-/* +- * strncpy_from_user_asm takes the kernel target pointer in r0, +- * the userspace source pointer in r1, and the length bound (including +- * the trailing NUL) in r2. On success, it returns the string length +- * (not including the trailing NUL), or -EFAULT on failure. +- */ +-STD_ENTRY(strncpy_from_user_asm) +- { beqz r2, 2f; move r3, r0 } +-1: { ld1u r4, r1; addi r1, r1, 1; addi r2, r2, -1 } +- { st1 r0, r4; addi r0, r0, 1 } +- beqz r4, 2f +- bnezt r2, 1b +- { sub r0, r0, r3; jrp lr } +-2: addi r0, r0, -1 /* don't count the trailing NUL */ +- { sub r0, r0, r3; jrp lr } +- STD_ENDPROC(strncpy_from_user_asm) +- .pushsection .fixup,"ax" +-strncpy_from_user_fault: +- { movei r0, -EFAULT; jrp lr } +- ENDPROC(strncpy_from_user_fault) +- .section __ex_table,"a" +- .align 8 +- .quad 1b, strncpy_from_user_fault +- .popsection +- +-/* + * clear_user_asm takes the user target address in r0 and the + * number of bytes to zero in r1. + * It returns the number of uncopiable bytes (hopefully zero) in r0. diff --git a/queue-3.18/word-at-a-time.h-support-zero_bytemask-on-alpha-and-tile.patch b/queue-3.18/word-at-a-time.h-support-zero_bytemask-on-alpha-and-tile.patch new file mode 100644 index 00000000000..d96b8f118dc --- /dev/null +++ b/queue-3.18/word-at-a-time.h-support-zero_bytemask-on-alpha-and-tile.patch @@ -0,0 +1,52 @@ +From c753bf34c94e5ac901e625e52f47320eeec4de2d Mon Sep 17 00:00:00 2001 +From: Chris Metcalf +Date: Tue, 6 Oct 2015 14:20:45 -0400 +Subject: word-at-a-time.h: support zero_bytemask() on alpha and tile + +From: Chris Metcalf + +commit c753bf34c94e5ac901e625e52f47320eeec4de2d upstream. + +Both alpha and tile needed implementations of zero_bytemask. + +The alpha version is untested. + +Signed-off-by: Chris Metcalf +Signed-off-by: Greg Kroah-Hartman + +--- + arch/alpha/include/asm/word-at-a-time.h | 2 ++ + arch/tile/include/asm/word-at-a-time.h | 8 +++++++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +--- a/arch/alpha/include/asm/word-at-a-time.h ++++ b/arch/alpha/include/asm/word-at-a-time.h +@@ -52,4 +52,6 @@ static inline unsigned long find_zero(un + #endif + } + ++#define zero_bytemask(mask) ((2ul << (find_zero(mask) * 8)) - 1) ++ + #endif /* _ASM_WORD_AT_A_TIME_H */ +--- a/arch/tile/include/asm/word-at-a-time.h ++++ b/arch/tile/include/asm/word-at-a-time.h +@@ -6,7 +6,7 @@ + struct word_at_a_time { /* unused */ }; + #define WORD_AT_A_TIME_CONSTANTS {} + +-/* Generate 0x01 byte values for non-zero bytes using a SIMD instruction. */ ++/* Generate 0x01 byte values for zero bytes using a SIMD instruction. */ + static inline unsigned long has_zero(unsigned long val, unsigned long *data, + const struct word_at_a_time *c) + { +@@ -33,4 +33,10 @@ static inline long find_zero(unsigned lo + #endif + } + ++#ifdef __BIG_ENDIAN ++#define zero_bytemask(mask) (~1ul << (63 - __builtin_clzl(mask))) ++#else ++#define zero_bytemask(mask) ((2ul << __builtin_ctzl(mask)) - 1) ++#endif ++ + #endif /* _ASM_WORD_AT_A_TIME_H */