提交 fee55450 编写于 作者: M Michael Neuling 提交者: Benjamin Herrenschmidt

powerpc/tm: Fix 32 bit non-rt signals

Currently sys_sigreturn() is TM unaware.  Therefore, if we take a 32 bit signal
without SIGINFO (non RT) inside a transaction, on signal return we don't
restore the signal frame correctly.

This checks if the signal frame being restoring is an active transaction, and
if so, it copies the additional state to ptregs so it can be restored.
Signed-off-by: NMichael Neuling <mikey@neuling.org>
cc: stable@vger.kernel.org (v3.9+)
Signed-off-by: NBenjamin Herrenschmidt <benh@kernel.crashing.org>
上级 1d25f11f
...@@ -1494,16 +1494,22 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, ...@@ -1494,16 +1494,22 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
struct pt_regs *regs) struct pt_regs *regs)
{ {
struct sigframe __user *sf;
struct sigcontext __user *sc; struct sigcontext __user *sc;
struct sigcontext sigctx; struct sigcontext sigctx;
struct mcontext __user *sr; struct mcontext __user *sr;
void __user *addr; void __user *addr;
sigset_t set; sigset_t set;
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
struct mcontext __user *mcp, *tm_mcp;
unsigned long msr_hi;
#endif
/* Always make any pending restarted system calls return -EINTR */ /* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall; current_thread_info()->restart_block.fn = do_no_restart_syscall;
sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE); sf = (struct sigframe __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
sc = &sf->sctx;
addr = sc; addr = sc;
if (copy_from_user(&sigctx, sc, sizeof(sigctx))) if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
goto badframe; goto badframe;
...@@ -1520,11 +1526,25 @@ long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, ...@@ -1520,11 +1526,25 @@ long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
#endif #endif
set_current_blocked(&set); set_current_blocked(&set);
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
mcp = (struct mcontext __user *)&sf->mctx;
tm_mcp = (struct mcontext __user *)&sf->mctx_transact;
if (__get_user(msr_hi, &tm_mcp->mc_gregs[PT_MSR]))
goto badframe;
if (MSR_TM_ACTIVE(msr_hi<<32)) {
if (!cpu_has_feature(CPU_FTR_TM))
goto badframe;
if (restore_tm_user_regs(regs, mcp, tm_mcp))
goto badframe;
} else
#endif
{
sr = (struct mcontext __user *)from_user_ptr(sigctx.regs); sr = (struct mcontext __user *)from_user_ptr(sigctx.regs);
addr = sr; addr = sr;
if (!access_ok(VERIFY_READ, sr, sizeof(*sr)) if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
|| restore_user_regs(regs, sr, 1)) || restore_user_regs(regs, sr, 1))
goto badframe; goto badframe;
}
set_thread_flag(TIF_RESTOREALL); set_thread_flag(TIF_RESTOREALL);
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册