linux-stable/arch
Breno Leitao b57b508bdc powerpc/tm: Set MSR[TS] just prior to recheckpoint
commit e1c3743e1a 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: 87b4e5393a ("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>
2019-01-13 10:01:06 +01:00
..
alpha arch/alpha, termios: implement BOTHER, IBSHIFT and termios2 2018-11-21 09:24:10 +01:00
arc ARC: io.h: Implement reads{x}()/writes{x}() 2018-12-21 14:13:12 +01:00
arm ARM: dts: imx7d-nitrogen7: Fix the description of the Wifi clock 2019-01-13 10:00:56 +01:00
arm64 arm64: relocatable: fix inconsistencies in linker script and options 2019-01-13 10:01:06 +01:00
blackfin
c6x
cris bug.h: work around GCC PR82365 in BUG() 2018-05-30 07:52:00 +02:00
frv
h8300 h8300: remove extraneous __BIG_ENDIAN definition 2018-03-28 18:24:38 +02:00
hexagon hexagon: modify ffs() and fls() to return int 2018-10-10 08:54:25 +02:00
ia64 ia64/err-inject: Use get_user_pages_fast() 2018-05-30 07:52:11 +02:00
m32r m32r: fix endianness constraints 2018-02-28 10:19:44 +01:00
m68k m68k: fix "bad page state" oops on ColdFire boot 2018-08-24 13:09:11 +02:00
metag .gitignore: move *.dtb and *.dtb.S patterns to the top-level .gitignore 2018-02-13 10:19:46 +01:00
microblaze microblaze: Fix simpleImage format generation 2018-08-03 07:50:40 +02:00
mips MIPS: Only include mmzone.h when CONFIG_NEED_MULTIPLE_NODES=y 2019-01-09 17:14:53 +01:00
mn10300 mn10300/misalignment: Use SIGSEGV SEGV_MAPERR to report a failed user copy 2018-02-16 20:23:11 +01:00
nios2 .gitignore: move *.dtb and *.dtb.S patterns to the top-level .gitignore 2018-02-13 10:19:46 +01:00
openrisc openrisc: entry: Fix delay slot exception detection 2018-08-24 13:09:11 +02:00
parisc parisc: Fix exported address of os_hpmc handler 2018-11-13 11:14:46 -08:00
powerpc powerpc/tm: Set MSR[TS] just prior to recheckpoint 2019-01-13 10:01:06 +01:00
s390 s390/pci: fix sleeping in atomic during hotplug 2019-01-09 17:14:48 +01:00
score
sh sh: fix build failure for J2 cpu with SMP disabled 2018-06-21 04:02:54 +09:00
sparc sparc64: Make proc_id signed. 2018-11-13 11:14:50 -08:00
tile
um um: Give start_idle_thread() a return code 2018-11-27 16:10:46 +01:00
unicore32 kmemcheck: stop using GFP_NOTRACK and SLAB_NOTRACK 2018-02-22 15:42:23 +01:00
x86 x86/dump_pagetables: Fix LDT remap address marker 2019-01-13 10:00:58 +01:00
xtensa xtensa: fix coprocessor part of ptrace_{get,set}xregs 2018-12-05 19:41:23 +01:00
.gitignore
Kconfig compiler.h: Allow arch-specific asm/compiler.h 2018-11-04 14:52:46 +01:00