]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Aug 2017 02:54:37 +0000 (19:54 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Aug 2017 02:54:37 +0000 (19:54 -0700)
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

queue-3.18/series
queue-3.18/tile-add-asm-word-at-a-time.h-and-enable-support-functions.patch [new file with mode: 0644]
queue-3.18/word-at-a-time.h-support-zero_bytemask-on-alpha-and-tile.patch [new file with mode: 0644]

index 404c73c63fc6a83d7186a5b527f8ca2ce39f27ff..30819e624071a49281b78c2f1d74b6e50d789790 100644 (file)
@@ -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 (file)
index 0000000..0ff68a1
--- /dev/null
@@ -0,0 +1,280 @@
+From 5bf6c07a1843813d0065feaaecba622d49148d7e Mon Sep 17 00:00:00 2001
+From: Chris Metcalf <cmetcalf@ezchip.com>
+Date: Thu, 30 Apr 2015 15:12:42 -0400
+Subject: tile: add <asm/word-at-a-time.h> and enable support functions
+
+From: Chris Metcalf <cmetcalf@ezchip.com>
+
+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 <cmetcalf@ezchip.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <asm/byteorder.h>
++
++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 <linux/uaccess.h>
+-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 (file)
index 0000000..d96b8f1
--- /dev/null
@@ -0,0 +1,52 @@
+From c753bf34c94e5ac901e625e52f47320eeec4de2d Mon Sep 17 00:00:00 2001
+From: Chris Metcalf <cmetcalf@ezchip.com>
+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 <cmetcalf@ezchip.com>
+
+commit c753bf34c94e5ac901e625e52f47320eeec4de2d upstream.
+
+Both alpha and tile needed implementations of zero_bytemask.
+
+The alpha version is untested.
+
+Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 */