]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 Jun 2019 15:40:51 +0000 (23:40 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 Jun 2019 15:40:51 +0000 (23:40 +0800)
added patches:
powerpc-mm-64s-hash-reallocate-context-ids-on-fork.patch

queue-5.1/nds32-avoid-iex-status-being-incorrectly-modified.patch [deleted file]
queue-5.1/powerpc-mm-64s-hash-reallocate-context-ids-on-fork.patch [new file with mode: 0644]
queue-5.1/series

diff --git a/queue-5.1/nds32-avoid-iex-status-being-incorrectly-modified.patch b/queue-5.1/nds32-avoid-iex-status-being-incorrectly-modified.patch
deleted file mode 100644 (file)
index 7bab325..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-From 7f214592e69ae8ea788b0a1413191e9de05190d3 Mon Sep 17 00:00:00 2001
-From: Vincent Chen <vincentc@andestech.com>
-Date: Mon, 20 May 2019 09:21:12 +0800
-Subject: nds32: Avoid IEX status being incorrectly modified
-
-[ Upstream commit ed32949e0acb73e7bc054bb02e0453d4d561ceda ]
-
-In order for kernel to capture each denormalized output, the UDF
-trapping enable bit is always raised in $fpcsr. Because underflow case will
-issue not an underflow exception but also an inexact exception, it causes
-that the IEX, IEX cumulative exception, flag in $fpcsr to be raised in each
-denormalized output handling. To make the emulation transparent to the
-user, the emulator needs to clear the IEX flag in $fpcsr if the result is a
-denormalized number. However, if the IEX flag has been raised before this
-floating point emulation, this cleanup may be incorrect. To avoid the IEX
-flags in $fpcsr be raised in each denormalized output handling, the IEX
-trap shall be always enabled.
-
-Signed-off-by: Vincent Chen <vincentc@andestech.com>
-Acked-by: Greentime Hu <greentime@andestech.com>
-Signed-off-by: Greentime Hu <greentime@andestech.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/nds32/include/asm/bitfield.h            |  2 +-
- arch/nds32/include/asm/fpu.h                 |  2 +-
- arch/nds32/include/asm/syscalls.h            |  2 +-
- arch/nds32/include/uapi/asm/fp_udfiex_crtl.h | 16 ++++++++++++
- arch/nds32/include/uapi/asm/sigcontext.h     | 24 ++++++++++++------
- arch/nds32/include/uapi/asm/udftrap.h        | 13 ----------
- arch/nds32/include/uapi/asm/unistd.h         |  4 +--
- arch/nds32/kernel/fpu.c                      | 15 +++++------
- arch/nds32/kernel/sys_nds32.c                | 26 +++++++++++---------
- 9 files changed, 58 insertions(+), 46 deletions(-)
- create mode 100644 arch/nds32/include/uapi/asm/fp_udfiex_crtl.h
- delete mode 100644 arch/nds32/include/uapi/asm/udftrap.h
-
-diff --git a/arch/nds32/include/asm/bitfield.h b/arch/nds32/include/asm/bitfield.h
-index 7414fcbbab4e..03bbb6d27828 100644
---- a/arch/nds32/include/asm/bitfield.h
-+++ b/arch/nds32/include/asm/bitfield.h
-@@ -937,7 +937,7 @@
- #define FPCSR_mskDNIT           ( 0x1  << FPCSR_offDNIT )
- #define FPCSR_mskRIT          ( 0x1  << FPCSR_offRIT )
- #define FPCSR_mskALL          (FPCSR_mskIVO | FPCSR_mskDBZ | FPCSR_mskOVF | FPCSR_mskUDF | FPCSR_mskIEX)
--#define FPCSR_mskALLE_NO_UDFE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE | FPCSR_mskIEXE)
-+#define FPCSR_mskALLE_NO_UDF_IEXE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE)
- #define FPCSR_mskALLE         (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE | FPCSR_mskUDFE | FPCSR_mskIEXE)
- #define FPCSR_mskALLT           (FPCSR_mskIVOT | FPCSR_mskDBZT | FPCSR_mskOVFT | FPCSR_mskUDFT | FPCSR_mskIEXT |FPCSR_mskDNIT | FPCSR_mskRIT)
-diff --git a/arch/nds32/include/asm/fpu.h b/arch/nds32/include/asm/fpu.h
-index 019f1bcfc5ee..8294ed4aaa2c 100644
---- a/arch/nds32/include/asm/fpu.h
-+++ b/arch/nds32/include/asm/fpu.h
-@@ -36,7 +36,7 @@ extern int do_fpuemu(struct pt_regs *regs, struct fpu_struct *fpu);
-  * enabled by default and kerenl will re-execute it by fpu emulator
-  * when getting underflow exception.
-  */
--#define FPCSR_INIT  FPCSR_mskUDFE
-+#define FPCSR_INIT  (FPCSR_mskUDFE | FPCSR_mskIEXE)
- #else
- #define FPCSR_INIT  0x0UL
- #endif
-diff --git a/arch/nds32/include/asm/syscalls.h b/arch/nds32/include/asm/syscalls.h
-index da32101b455d..b9c9becce5d6 100644
---- a/arch/nds32/include/asm/syscalls.h
-+++ b/arch/nds32/include/asm/syscalls.h
-@@ -7,7 +7,7 @@
- asmlinkage long sys_cacheflush(unsigned long addr, unsigned long len, unsigned int op);
- asmlinkage long sys_fadvise64_64_wrapper(int fd, int advice, loff_t offset, loff_t len);
- asmlinkage long sys_rt_sigreturn_wrapper(void);
--asmlinkage long sys_udftrap(int option);
-+asmlinkage long sys_fp_udfiex_crtl(int cmd, int act);
- #include <asm-generic/syscalls.h>
-diff --git a/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h b/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h
-new file mode 100644
-index 000000000000..d54a5d6c6538
---- /dev/null
-+++ b/arch/nds32/include/uapi/asm/fp_udfiex_crtl.h
-@@ -0,0 +1,16 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/* Copyright (C) 2005-2019 Andes Technology Corporation */
-+#ifndef       _FP_UDF_IEX_CRTL_H
-+#define       _FP_UDF_IEX_CRTL_H
-+
-+/*
-+ * The cmd list of sys_fp_udfiex_crtl()
-+ */
-+/* Disable UDF or IEX trap based on the content of parameter act */
-+#define DISABLE_UDF_IEX_TRAP  0
-+/* Enable UDF or IEX trap based on the content of parameter act */
-+#define ENABLE_UDF_IEX_TRAP   1
-+/* Get current status of UDF and IEX trap */
-+#define GET_UDF_IEX_TRAP      2
-+
-+#endif /* _FP_UDF_IEX_CRTL_H */
-diff --git a/arch/nds32/include/uapi/asm/sigcontext.h b/arch/nds32/include/uapi/asm/sigcontext.h
-index 58afc416473e..b53634033e32 100644
---- a/arch/nds32/include/uapi/asm/sigcontext.h
-+++ b/arch/nds32/include/uapi/asm/sigcontext.h
-@@ -13,14 +13,24 @@ struct fpu_struct {
-       unsigned long long fd_regs[32];
-       unsigned long fpcsr;
-       /*
--       * UDF_trap is used to recognize whether underflow trap is enabled
--       * or not. When UDF_trap == 1, this process will be traped and then
--       * get a SIGFPE signal when encountering an underflow exception.
--       * UDF_trap is only modified through setfputrap syscall. Therefore,
--       * UDF_trap needn't be saved or loaded to context in each context
--       * switch.
-+       * When CONFIG_SUPPORT_DENORMAL_ARITHMETIC is defined, kernel prevents
-+       * hardware from treating the denormalized output as an underflow case
-+       * and rounding it to a normal number. Hence kernel enables the UDF and
-+       * IEX trap in the fpcsr register to step in the calculation.
-+       * However, the UDF and IEX trap enable bit in $fpcsr also lose
-+       * their use.
-+       *
-+       * UDF_IEX_trap replaces the feature of UDF and IEX trap enable bit in
-+       * $fpcsr to control the trap of underflow and inexact. The bit filed
-+       * of UDF_IEX_trap is the same as $fpcsr, 10th bit is used to enable UDF
-+       * exception trapping and 11th bit is used to enable IEX exception
-+       * trapping.
-+       *
-+       * UDF_IEX_trap is only modified through fp_udfiex_crtl syscall.
-+       * Therefore, UDF_IEX_trap needn't be saved and restored in each
-+       * context switch.
-        */
--      unsigned long UDF_trap;
-+      unsigned long UDF_IEX_trap;
- };
- struct zol_struct {
-diff --git a/arch/nds32/include/uapi/asm/udftrap.h b/arch/nds32/include/uapi/asm/udftrap.h
-deleted file mode 100644
-index 433f79d679c0..000000000000
---- a/arch/nds32/include/uapi/asm/udftrap.h
-+++ /dev/null
-@@ -1,13 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0 */
--/* Copyright (C) 2005-2018 Andes Technology Corporation */
--#ifndef       _ASM_SETFPUTRAP
--#define       _ASM_SETFPUTRAP
--
--/*
-- * Options for setfputrap system call
-- */
--#define       DISABLE_UDFTRAP 0       /* disable underflow exception trap */
--#define       ENABLE_UDFTRAP  1       /* enable undeflos exception trap */
--#define       GET_UDFTRAP     2       /* only get undeflos exception trap status */
--
--#endif /* _ASM_CACHECTL */
-diff --git a/arch/nds32/include/uapi/asm/unistd.h b/arch/nds32/include/uapi/asm/unistd.h
-index 4ec8f543103f..6b9ff90e3ae5 100644
---- a/arch/nds32/include/uapi/asm/unistd.h
-+++ b/arch/nds32/include/uapi/asm/unistd.h
-@@ -11,6 +11,6 @@
- /* Additional NDS32 specific syscalls. */
- #define __NR_cacheflush               (__NR_arch_specific_syscall)
--#define __NR_udftrap          (__NR_arch_specific_syscall + 1)
-+#define __NR_fp_udfiex_crtl   (__NR_arch_specific_syscall + 1)
- __SYSCALL(__NR_cacheflush, sys_cacheflush)
--__SYSCALL(__NR_udftrap, sys_udftrap)
-+__SYSCALL(__NR_fp_udfiex_crtl, sys_fp_udfiex_crtl)
-diff --git a/arch/nds32/kernel/fpu.c b/arch/nds32/kernel/fpu.c
-index fddd40c7a16f..cf0b8760f261 100644
---- a/arch/nds32/kernel/fpu.c
-+++ b/arch/nds32/kernel/fpu.c
-@@ -14,7 +14,7 @@ const struct fpu_struct init_fpuregs = {
-       .fd_regs = {[0 ... 31] = sNAN64},
-       .fpcsr = FPCSR_INIT,
- #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
--      .UDF_trap = 0
-+      .UDF_IEX_trap = 0
- #endif
- };
-@@ -178,7 +178,7 @@ inline void do_fpu_context_switch(struct pt_regs *regs)
-               /* First time FPU user.  */
-               load_fpu(&init_fpuregs);
- #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
--              current->thread.fpu.UDF_trap = init_fpuregs.UDF_trap;
-+              current->thread.fpu.UDF_IEX_trap = init_fpuregs.UDF_IEX_trap;
- #endif
-               set_used_math();
-       }
-@@ -206,7 +206,7 @@ inline void handle_fpu_exception(struct pt_regs *regs)
-       unsigned int fpcsr;
-       int si_code = 0, si_signo = SIGFPE;
- #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
--      unsigned long redo_except = FPCSR_mskDNIT|FPCSR_mskUDFT;
-+      unsigned long redo_except = FPCSR_mskDNIT|FPCSR_mskUDFT|FPCSR_mskIEXT;
- #else
-       unsigned long redo_except = FPCSR_mskDNIT;
- #endif
-@@ -215,21 +215,18 @@ inline void handle_fpu_exception(struct pt_regs *regs)
-       fpcsr = current->thread.fpu.fpcsr;
-       if (fpcsr & redo_except) {
--#if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
--              if (fpcsr & FPCSR_mskUDFT)
--                      current->thread.fpu.fpcsr &= ~FPCSR_mskIEX;
--#endif
-               si_signo = do_fpuemu(regs, &current->thread.fpu);
-               fpcsr = current->thread.fpu.fpcsr;
--              if (!si_signo)
-+              if (!si_signo) {
-+                      current->thread.fpu.fpcsr &= ~(redo_except);
-                       goto done;
-+              }
-       } else if (fpcsr & FPCSR_mskRIT) {
-               if (!user_mode(regs))
-                       do_exit(SIGILL);
-               si_signo = SIGILL;
-       }
--
-       switch (si_signo) {
-       case SIGFPE:
-               fill_sigfpe_signo(fpcsr, &si_code);
-diff --git a/arch/nds32/kernel/sys_nds32.c b/arch/nds32/kernel/sys_nds32.c
-index 0835277636ce..cb2d1e219bb3 100644
---- a/arch/nds32/kernel/sys_nds32.c
-+++ b/arch/nds32/kernel/sys_nds32.c
-@@ -6,8 +6,8 @@
- #include <asm/cachectl.h>
- #include <asm/proc-fns.h>
--#include <asm/udftrap.h>
- #include <asm/fpu.h>
-+#include <asm/fp_udfiex_crtl.h>
- SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
-              unsigned long, prot, unsigned long, flags,
-@@ -51,31 +51,33 @@ SYSCALL_DEFINE3(cacheflush, unsigned int, start, unsigned int, end, int, cache)
-       return 0;
- }
--SYSCALL_DEFINE1(udftrap, int, option)
-+SYSCALL_DEFINE2(fp_udfiex_crtl, unsigned int, cmd, unsigned int, act)
- {
- #if IS_ENABLED(CONFIG_SUPPORT_DENORMAL_ARITHMETIC)
--      int old_udftrap;
-+      int old_udf_iex;
-       if (!used_math()) {
-               load_fpu(&init_fpuregs);
--              current->thread.fpu.UDF_trap = init_fpuregs.UDF_trap;
-+              current->thread.fpu.UDF_IEX_trap = init_fpuregs.UDF_IEX_trap;
-               set_used_math();
-       }
--      old_udftrap = current->thread.fpu.UDF_trap;
--      switch (option) {
--      case DISABLE_UDFTRAP:
--              current->thread.fpu.UDF_trap = 0;
-+      old_udf_iex = current->thread.fpu.UDF_IEX_trap;
-+      act &= (FPCSR_mskUDFE | FPCSR_mskIEXE);
-+
-+      switch (cmd) {
-+      case DISABLE_UDF_IEX_TRAP:
-+              current->thread.fpu.UDF_IEX_trap &= ~act;
-               break;
--      case ENABLE_UDFTRAP:
--              current->thread.fpu.UDF_trap = FPCSR_mskUDFE;
-+      case ENABLE_UDF_IEX_TRAP:
-+              current->thread.fpu.UDF_IEX_trap |= act;
-               break;
--      case GET_UDFTRAP:
-+      case GET_UDF_IEX_TRAP:
-               break;
-       default:
-               return -EINVAL;
-       }
--      return old_udftrap;
-+      return old_udf_iex;
- #else
-       return -ENOTSUPP;
- #endif
--- 
-2.20.1
-
diff --git a/queue-5.1/powerpc-mm-64s-hash-reallocate-context-ids-on-fork.patch b/queue-5.1/powerpc-mm-64s-hash-reallocate-context-ids-on-fork.patch
new file mode 100644 (file)
index 0000000..095578b
--- /dev/null
@@ -0,0 +1,140 @@
+From ca72d88378b2f2444d3ec145dd442d449d3fefbc Mon Sep 17 00:00:00 2001
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 12 Jun 2019 23:35:07 +1000
+Subject: powerpc/mm/64s/hash: Reallocate context ids on fork
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit ca72d88378b2f2444d3ec145dd442d449d3fefbc upstream.
+
+When using the Hash Page Table (HPT) MMU, userspace memory mappings
+are managed at two levels. Firstly in the Linux page tables, much like
+other architectures, and secondly in the SLB (Segment Lookaside
+Buffer) and HPT. It's the SLB and HPT that are actually used by the
+hardware to do translations.
+
+As part of the series adding support for 4PB user virtual address
+space using the hash MMU, we added support for allocating multiple
+"context ids" per process, one for each 512TB chunk of address space.
+These are tracked in an array called extended_id in the mm_context_t
+of a process that has done a mapping above 512TB.
+
+If such a process forks (ie. clone(2) without CLONE_VM set) it's mm is
+copied, including the mm_context_t, and then init_new_context() is
+called to reinitialise parts of the mm_context_t as appropriate to
+separate the address spaces of the two processes.
+
+The key step in ensuring the two processes have separate address
+spaces is to allocate a new context id for the process, this is done
+at the beginning of hash__init_new_context(). If we didn't allocate a
+new context id then the two processes would share mappings as far as
+the SLB and HPT are concerned, even though their Linux page tables
+would be separate.
+
+For mappings above 512TB, which use the extended_id array, we
+neglected to allocate new context ids on fork, meaning the parent and
+child use the same ids and therefore share those mappings even though
+they're supposed to be separate. This can lead to the parent seeing
+writes done by the child, which is essentially memory corruption.
+
+There is an additional exposure which is that if the child process
+exits, all its context ids are freed, including the context ids that
+are still in use by the parent for mappings above 512TB. One or more
+of those ids can then be reallocated to a third process, that process
+can then read/write to the parent's mappings above 512TB. Additionally
+if the freed id is used for the third process's primary context id,
+then the parent is able to read/write to the third process's mappings
+*below* 512TB.
+
+All of these are fundamental failures to enforce separation between
+processes. The only mitigating factor is that the bug only occurs if a
+process creates mappings above 512TB, and most applications still do
+not create such mappings.
+
+Only machines using the hash page table MMU are affected, eg. PowerPC
+970 (G5), PA6T, Power5/6/7/8/9. By default Power9 bare metal machines
+(powernv) use the Radix MMU and are not affected, unless the machine
+has been explicitly booted in HPT mode (using disable_radix on the
+kernel command line). KVM guests on Power9 may be affected if the host
+or guest is configured to use the HPT MMU. LPARs under PowerVM on
+Power9 are affected as they always use the HPT MMU. Kernels built with
+PAGE_SIZE=4K are not affected.
+
+The fix is relatively simple, we need to reallocate context ids for
+all extended mappings on fork.
+
+Fixes: f384796c40dc ("powerpc/mm: Add support for handling > 512TB address in SLB miss")
+Cc: stable@vger.kernel.org # v4.17+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/mm/mmu_context_book3s64.c |   46 ++++++++++++++++++++++++++++++---
+ 1 file changed, 42 insertions(+), 4 deletions(-)
+
+--- a/arch/powerpc/mm/mmu_context_book3s64.c
++++ b/arch/powerpc/mm/mmu_context_book3s64.c
+@@ -55,14 +55,48 @@ EXPORT_SYMBOL_GPL(hash__alloc_context_id
+ void slb_setup_new_exec(void);
++static int realloc_context_ids(mm_context_t *ctx)
++{
++      int i, id;
++
++      /*
++       * id 0 (aka. ctx->id) is special, we always allocate a new one, even if
++       * there wasn't one allocated previously (which happens in the exec
++       * case where ctx is newly allocated).
++       *
++       * We have to be a bit careful here. We must keep the existing ids in
++       * the array, so that we can test if they're non-zero to decide if we
++       * need to allocate a new one. However in case of error we must free the
++       * ids we've allocated but *not* any of the existing ones (or risk a
++       * UAF). That's why we decrement i at the start of the error handling
++       * loop, to skip the id that we just tested but couldn't reallocate.
++       */
++      for (i = 0; i < ARRAY_SIZE(ctx->extended_id); i++) {
++              if (i == 0 || ctx->extended_id[i]) {
++                      id = hash__alloc_context_id();
++                      if (id < 0)
++                              goto error;
++
++                      ctx->extended_id[i] = id;
++              }
++      }
++
++      /* The caller expects us to return id */
++      return ctx->id;
++
++error:
++      for (i--; i >= 0; i--) {
++              if (ctx->extended_id[i])
++                      ida_free(&mmu_context_ida, ctx->extended_id[i]);
++      }
++
++      return id;
++}
++
+ static int hash__init_new_context(struct mm_struct *mm)
+ {
+       int index;
+-      index = hash__alloc_context_id();
+-      if (index < 0)
+-              return index;
+-
+       /*
+        * The old code would re-promote on fork, we don't do that when using
+        * slices as it could cause problem promoting slices that have been
+@@ -80,6 +114,10 @@ static int hash__init_new_context(struct
+       if (mm->context.id == 0)
+               slice_init_new_context_exec(mm);
++      index = realloc_context_ids(&mm->context);
++      if (index < 0)
++              return index;
++
+       subpage_prot_init_new_context(mm);
+       pkey_mm_init(mm);
index 626dccf738e55df3b3f6ed3103fef1f5bf172310..d8c2a8ebc9237059ebc00681b28c1894508caf9b 100644 (file)
@@ -59,7 +59,6 @@ kselftest-cgroup-fix-unexpected-testing-failure-on-t.patch-32330
 kselftest-cgroup-fix-incorrect-test_core-skip.patch
 userfaultfd-selftest-fix-compiler-warning.patch
 selftests-vm-install-test_vmalloc.sh-for-run_vmtests.patch
-nds32-avoid-iex-status-being-incorrectly-modified.patch
 net-dsa-mv88e6xxx-avoid-error-message-on-remove-from.patch
 net-hns-fix-loopback-test-failed-at-copper-ports.patch
 mdesc-fix-a-missing-check-bug-in-get_vdev_port_node_.patch
@@ -119,3 +118,4 @@ mac80211-handle-deauthentication-disassociation-from-tdls-peer.patch
 nl80211-fix-station_info-pertid-memory-leak.patch
 mac80211-do-not-use-stack-memory-with-scatterlist-for-gmac.patch
 x86-resctrl-don-t-stop-walking-closids-when-a-locksetup-group-is-found.patch
+powerpc-mm-64s-hash-reallocate-context-ids-on-fork.patch