linux/arch/powerpc
Gustavo Romero 1c200e63d0 powerpc/tm: Fix endianness flip on trap
Currently it's possible that a thread on PPC64 LE has its endianness
flipped inadvertently to Big-Endian resulting in a crash once the process
is back from the signal handler.

If giveup_all() is called when regs->msr has the bits MSR.FP and MSR.VEC
disabled (and hence MSR.VSX disabled too) it returns without calling
check_if_tm_restore_required() which copies regs->msr to ckpt_regs->msr if
the process caught a signal whilst in transactional mode. Then once in
setup_tm_sigcontexts() MSR from ckpt_regs.msr is used, but since
check_if_tm_restore_required() was not called previuosly, gp_regs[PT_MSR]
gets a copy of invalid MSR bits as MSR in ckpt_regs was not updated from
regs->msr and so is zeroed. Later when leaving the signal handler once in
sys_rt_sigreturn() the TS bits of gp_regs[PT_MSR] are checked to determine
if restore_tm_sigcontexts() must be called to pull in the correct MSR state
into the user context. Because TS bits are zeroed
restore_tm_sigcontexts() is never called and MSR restored from the user
context on returning from the signal handler has the MSR.LE (the endianness
bit) forced to zero (Big-Endian). That leads, for instance, to 'nop' being
treated as an illegal instruction in the following sequence:

	tbegin.
	beq	1f
	trap
	tend.
1:	nop

on PPC64 LE machines and the process dies just after returning from the
signal handler.

PPC64 BE is also affected but in a subtle way since forcing Big-Endian on
a BE machine does not change the endianness.

This commit fixes the issue described above by ensuring that once in
setup_tm_sigcontexts() the MSR used is from regs->msr instead of from
ckpt_regs->msr and by ensuring that we pull in only the MSR.FP, MSR.VEC,
and MSR.VSX bits from ckpt_regs->msr.

The fix was tested both on LE and BE machines and no regression regarding
the powerpc/tm selftests was observed.

Signed-off-by: Gustavo Romero <gromero@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2018-01-22 05:48:36 +11:00
..
boot powerpc/boot/dts: Remove leading 0x and 0s from bindings notation 2018-01-21 23:37:45 +11:00
configs powerpc: Add aacraid and nvme to powernv_defconfig 2018-01-16 23:47:15 +11:00
crypto License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
include powerpc/xive: Properly use static keyword for inline function 2018-01-21 23:37:43 +11:00
kernel powerpc/tm: Fix endianness flip on trap 2018-01-22 05:48:36 +11:00
kvm powerpc: Use octal numbers for file permissions 2018-01-22 05:48:33 +11:00
lib Merge branch 'fixes' into next 2018-01-21 23:21:14 +11:00
math-emu License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
mm powerpc/radix: Remove trace_tlbie call from radix__flush_tlb_all 2018-01-22 05:48:35 +11:00
net powerpc updates for 4.15 2017-11-16 12:47:46 -08:00
oprofile treewide: setup_timer() -> timer_setup() 2017-11-21 15:57:07 -08:00
perf Merge branch 'fixes' into next 2018-01-21 23:21:14 +11:00
platforms powerpc/powernv: Add ppc_pci_reset_phbs parameter to issue a PHB reset 2018-01-22 05:48:35 +11:00
purgatory License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
sysdev powerpc: Use octal numbers for file permissions 2018-01-22 05:48:33 +11:00
tools License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xmon powerpc/xmon: Do not compute/store the major opcode 2018-01-21 23:37:43 +11:00
Kconfig Merge branch 'fixes' into next 2018-01-21 23:21:14 +11:00
Kconfig.debug powerpc: Add new kconfig CONFIG_PPC_IRQ_SOFT_MASK_DEBUG 2018-01-19 22:37:03 +11:00
Makefile powerpc/modules: Fix alignment of .toc section in kernel modules 2017-12-11 13:03:35 +11:00
Makefile.postlink License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00