]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.20-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 11 Jan 2019 07:10:32 +0000 (08:10 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 11 Jan 2019 07:10:32 +0000 (08:10 +0100)
added patches:
powerpc-tm-set-msr-just-prior-to-recheckpoint.patch
revert-powerpc-tm-unset-msr-if-not-recheckpointing.patch

queue-4.20/powerpc-tm-set-msr-just-prior-to-recheckpoint.patch [new file with mode: 0644]
queue-4.20/revert-powerpc-tm-unset-msr-if-not-recheckpointing.patch [new file with mode: 0644]
queue-4.20/series

diff --git a/queue-4.20/powerpc-tm-set-msr-just-prior-to-recheckpoint.patch b/queue-4.20/powerpc-tm-set-msr-just-prior-to-recheckpoint.patch
new file mode 100644 (file)
index 0000000..fbf5897
--- /dev/null
@@ -0,0 +1,189 @@
+From e1c3743e1a20647c53b719dbf28b48f45d23f2cd Mon Sep 17 00:00:00 2001
+From: Breno Leitao <leitao@debian.org>
+Date: Wed, 21 Nov 2018 17:21:09 -0200
+Subject: powerpc/tm: Set MSR[TS] just prior to recheckpoint
+
+From: Breno Leitao <leitao@debian.org>
+
+commit e1c3743e1a20647c53b719dbf28b48f45d23f2cd upstream.
+
+On a signal handler return, the user could set a context with MSR[TS] bits
+set, and these bits would be copied to task regs->msr.
+
+At restore_tm_sigcontexts(), after current task regs->msr[TS] bits are set,
+several __get_user() are called and then a recheckpoint is executed.
+
+This is a problem since a page fault (in kernel space) could happen when
+calling __get_user(). If it happens, the process MSR[TS] bits were
+already set, but recheckpoint was not executed, and SPRs are still invalid.
+
+The page fault can cause the current process to be de-scheduled, with
+MSR[TS] active and without tm_recheckpoint() being called.  More
+importantly, without TEXASR[FS] bit set also.
+
+Since TEXASR might not have the FS bit set, and when the process is
+scheduled back, it will try to reclaim, which will be aborted because of
+the CPU is not in the suspended state, and, then, recheckpoint. This
+recheckpoint will restore thread->texasr into TEXASR SPR, which might be
+zero, hitting a BUG_ON().
+
+       kernel BUG at /build/linux-sf3Co9/linux-4.9.30/arch/powerpc/kernel/tm.S:434!
+       cpu 0xb: Vector: 700 (Program Check) at [c00000041f1576d0]
+           pc: c000000000054550: restore_gprs+0xb0/0x180
+           lr: 0000000000000000
+           sp: c00000041f157950
+          msr: 8000000100021033
+         current = 0xc00000041f143000
+         paca    = 0xc00000000fb86300   softe: 0        irq_happened: 0x01
+           pid   = 1021, comm = kworker/11:1
+       kernel BUG at /build/linux-sf3Co9/linux-4.9.30/arch/powerpc/kernel/tm.S:434!
+       Linux version 4.9.0-3-powerpc64le (debian-kernel@lists.debian.org) (gcc version 6.3.0 20170516 (Debian 6.3.0-18) ) #1 SMP Debian 4.9.30-2+deb9u2 (2017-06-26)
+       enter ? for help
+       [c00000041f157b30] c00000000001bc3c tm_recheckpoint.part.11+0x6c/0xa0
+       [c00000041f157b70] c00000000001d184 __switch_to+0x1e4/0x4c0
+       [c00000041f157bd0] c00000000082eeb8 __schedule+0x2f8/0x990
+       [c00000041f157cb0] c00000000082f598 schedule+0x48/0xc0
+       [c00000041f157ce0] c0000000000f0d28 worker_thread+0x148/0x610
+       [c00000041f157d80] c0000000000f96b0 kthread+0x120/0x140
+       [c00000041f157e30] c00000000000c0e0 ret_from_kernel_thread+0x5c/0x7c
+
+This patch simply delays the MSR[TS] set, so, if there is any page fault in
+the __get_user() section, it does not have regs->msr[TS] set, since the TM
+structures are still invalid, thus avoiding doing TM operations for
+in-kernel exceptions and possible process reschedule.
+
+With this patch, the MSR[TS] will only be set just before recheckpointing
+and setting TEXASR[FS] = 1, thus avoiding an interrupt with TM registers in
+invalid state.
+
+Other than that, if CONFIG_PREEMPT is set, there might be a preemption just
+after setting MSR[TS] and before tm_recheckpoint(), thus, this block must
+be atomic from a preemption perspective, thus, calling
+preempt_disable/enable() on this code.
+
+It is not possible to move tm_recheckpoint to happen earlier, because it is
+required to get the checkpointed registers from userspace, with
+__get_user(), thus, the only way to avoid this undesired behavior is
+delaying the MSR[TS] set.
+
+The 32-bits signal handler seems to be safe this current issue, but, it
+might be exposed to the preemption issue, thus, disabling preemption in
+this chunk of code.
+
+Changes from v2:
+ * Run the critical section with preempt_disable.
+
+Fixes: 87b4e5393af7 ("powerpc/tm: Fix return of active 64bit signals")
+Cc: stable@vger.kernel.org (v3.9+)
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/signal_32.c |   20 +++++++++++++++++-
+ arch/powerpc/kernel/signal_64.c |   44 +++++++++++++++++++++++++++-------------
+ 2 files changed, 49 insertions(+), 15 deletions(-)
+
+--- a/arch/powerpc/kernel/signal_32.c
++++ b/arch/powerpc/kernel/signal_32.c
+@@ -848,7 +848,23 @@ static long restore_tm_user_regs(struct
+       /* If TM bits are set to the reserved value, it's an invalid context */
+       if (MSR_TM_RESV(msr_hi))
+               return 1;
+-      /* Pull in the MSR TM bits from the user context */
++
++      /*
++       * Disabling preemption, since it is unsafe to be preempted
++       * with MSR[TS] set without recheckpointing.
++       */
++      preempt_disable();
++
++      /*
++       * CAUTION:
++       * After regs->MSR[TS] being updated, make sure that get_user(),
++       * put_user() or similar functions are *not* called. These
++       * functions can generate page faults which will cause the process
++       * to be de-scheduled with MSR[TS] set but without calling
++       * tm_recheckpoint(). This can cause a bug.
++       *
++       * Pull in the MSR TM bits from the user context
++       */
+       regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr_hi & MSR_TS_MASK);
+       /* Now, recheckpoint.  This loads up all of the checkpointed (older)
+        * registers, including FP and V[S]Rs.  After recheckpointing, the
+@@ -873,6 +889,8 @@ static long restore_tm_user_regs(struct
+       }
+ #endif
++      preempt_enable();
++
+       return 0;
+ }
+ #endif
+--- a/arch/powerpc/kernel/signal_64.c
++++ b/arch/powerpc/kernel/signal_64.c
+@@ -467,20 +467,6 @@ static long restore_tm_sigcontexts(struc
+       if (MSR_TM_RESV(msr))
+               return -EINVAL;
+-      /* pull in MSR TS bits from user context */
+-      regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);
+-
+-      /*
+-       * Ensure that TM is enabled in regs->msr before we leave the signal
+-       * handler. It could be the case that (a) user disabled the TM bit
+-       * through the manipulation of the MSR bits in uc_mcontext or (b) the
+-       * TM bit was disabled because a sufficient number of context switches
+-       * happened whilst in the signal handler and load_tm overflowed,
+-       * disabling the TM bit. In either case we can end up with an illegal
+-       * TM state leading to a TM Bad Thing when we return to userspace.
+-       */
+-      regs->msr |= MSR_TM;
+-
+       /* pull in MSR LE from user context */
+       regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
+@@ -572,6 +558,34 @@ static long restore_tm_sigcontexts(struc
+       tm_enable();
+       /* Make sure the transaction is marked as failed */
+       tsk->thread.tm_texasr |= TEXASR_FS;
++
++      /*
++       * Disabling preemption, since it is unsafe to be preempted
++       * with MSR[TS] set without recheckpointing.
++       */
++      preempt_disable();
++
++      /* pull in MSR TS bits from user context */
++      regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);
++
++      /*
++       * Ensure that TM is enabled in regs->msr before we leave the signal
++       * handler. It could be the case that (a) user disabled the TM bit
++       * through the manipulation of the MSR bits in uc_mcontext or (b) the
++       * TM bit was disabled because a sufficient number of context switches
++       * happened whilst in the signal handler and load_tm overflowed,
++       * disabling the TM bit. In either case we can end up with an illegal
++       * TM state leading to a TM Bad Thing when we return to userspace.
++       *
++       * CAUTION:
++       * After regs->MSR[TS] being updated, make sure that get_user(),
++       * put_user() or similar functions are *not* called. These
++       * functions can generate page faults which will cause the process
++       * to be de-scheduled with MSR[TS] set but without calling
++       * tm_recheckpoint(). This can cause a bug.
++       */
++      regs->msr |= MSR_TM;
++
+       /* This loads the checkpointed FP/VEC state, if used */
+       tm_recheckpoint(&tsk->thread);
+@@ -585,6 +599,8 @@ static long restore_tm_sigcontexts(struc
+               regs->msr |= MSR_VEC;
+       }
++      preempt_enable();
++
+       return err;
+ }
+ #endif
diff --git a/queue-4.20/revert-powerpc-tm-unset-msr-if-not-recheckpointing.patch b/queue-4.20/revert-powerpc-tm-unset-msr-if-not-recheckpointing.patch
new file mode 100644 (file)
index 0000000..2715e2c
--- /dev/null
@@ -0,0 +1,96 @@
+From 4d64ec7617fc66c8101f0774fc8b2b5599a46b8c Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Fri, 11 Jan 2019 08:05:32 +0100
+Subject: Revert "powerpc/tm: Unset MSR[TS] if not recheckpointing"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+This reverts commit d412deb85a4aada382352a8202beb7af8921cd53 which is
+commit 6f5b9f018f4c7686fd944d920209d1382d320e4e upstream.
+
+It breaks the powerpc build, so drop it from the tree until a fix goes
+upstream.
+
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Cc: Breno Leitao <leitao@debian.org>
+Cc: Michal Suchánek <msuchanek@suse.de>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Christoph Biedl <linux-kernel.bfrz@manchmal.in-ulm.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/kernel/signal_32.c |   18 +++++-------------
+ arch/powerpc/kernel/signal_64.c |   20 ++++----------------
+ 2 files changed, 9 insertions(+), 29 deletions(-)
+
+--- a/arch/powerpc/kernel/signal_32.c
++++ b/arch/powerpc/kernel/signal_32.c
+@@ -1140,11 +1140,11 @@ SYSCALL_DEFINE0(rt_sigreturn)
+ {
+       struct rt_sigframe __user *rt_sf;
+       struct pt_regs *regs = current_pt_regs();
+-      int tm_restore = 0;
+ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       struct ucontext __user *uc_transact;
+       unsigned long msr_hi;
+       unsigned long tmp;
++      int tm_restore = 0;
+ #endif
+       /* Always make any pending restarted system calls return -EINTR */
+       current->restart_block.fn = do_no_restart_syscall;
+@@ -1192,19 +1192,11 @@ SYSCALL_DEFINE0(rt_sigreturn)
+                               goto bad;
+               }
+       }
+-      if (!tm_restore) {
+-              /*
+-               * Unset regs->msr because ucontext MSR TS is not
+-               * set, and recheckpoint was not called. This avoid
+-               * hitting a TM Bad thing at RFID
+-               */
+-              regs->msr &= ~MSR_TS_MASK;
+-      }
+-      /* Fall through, for non-TM restore */
+-#endif
+       if (!tm_restore)
+-              if (do_setcontext(&rt_sf->uc, regs, 1))
+-                      goto bad;
++              /* Fall through, for non-TM restore */
++#endif
++      if (do_setcontext(&rt_sf->uc, regs, 1))
++              goto bad;
+       /*
+        * It's not clear whether or why it is desirable to save the
+--- a/arch/powerpc/kernel/signal_64.c
++++ b/arch/powerpc/kernel/signal_64.c
+@@ -740,23 +740,11 @@ SYSCALL_DEFINE0(rt_sigreturn)
+                                          &uc_transact->uc_mcontext))
+                       goto badframe;
+       }
+-#endif
++      else
+       /* Fall through, for non-TM restore */
+-      if (!MSR_TM_ACTIVE(msr)) {
+-              /*
+-               * Unset MSR[TS] on the thread regs since MSR from user
+-               * context does not have MSR active, and recheckpoint was
+-               * not called since restore_tm_sigcontexts() was not called
+-               * also.
+-               *
+-               * If not unsetting it, the code can RFID to userspace with
+-               * MSR[TS] set, but without CPU in the proper state,
+-               * causing a TM bad thing.
+-               */
+-              current->thread.regs->msr &= ~MSR_TS_MASK;
+-              if (restore_sigcontext(current, NULL, 1, &uc->uc_mcontext))
+-                      goto badframe;
+-      }
++#endif
++      if (restore_sigcontext(current, NULL, 1, &uc->uc_mcontext))
++              goto badframe;
+       if (restore_altstack(&uc->uc_stack))
+               goto badframe;
index 3330b660506993a42802c04dcb135753b503b1d6..87a839de810fe34a8c43312198a28dbbd879bf92 100644 (file)
@@ -38,3 +38,5 @@ pci-pm-allow-runtime-pm-without-callback-functions.patch
 lockd-show-pid-of-lockd-for-remote-locks.patch
 xprtrdma-yet-another-double-dma-unmap.patch
 nfsd4-zero-length-write-should-succeed.patch
+revert-powerpc-tm-unset-msr-if-not-recheckpointing.patch
+powerpc-tm-set-msr-just-prior-to-recheckpoint.patch