Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d765ff23 authored by Paul Mackerras's avatar Paul Mackerras Committed by Benjamin Herrenschmidt
Browse files

powerpc: Fix 32-bit frames for signals delivered when transactional



Commit d31626f7 ("powerpc: Don't corrupt transactional state when
using FP/VMX in kernel") introduced a bug where the uc_link and uc_regs
fields of the ucontext_t that is created to hold the transactional
values of the registers in a 32-bit signal frame didn't get set
correctly.  The reason is that we now clear the MSR_TS bits in the MSR
in save_tm_user_regs(), before the code that sets uc_link and uc_regs.
To fix this, we move the setting of uc_link and uc_regs into the same
if statement that selects whether to call save_tm_user_regs() or
save_user_regs().

Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 67bfa0ee
Loading
Loading
Loading
Loading
+7 −12
Original line number Diff line number Diff line
@@ -1022,29 +1022,24 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
	tm_frame = &rt_sf->uc_transact.uc_mcontext;
	if (MSR_TM_ACTIVE(regs->msr)) {
		if (__put_user((unsigned long)&rt_sf->uc_transact,
			       &rt_sf->uc.uc_link) ||
		    __put_user((unsigned long)tm_frame,
			       &rt_sf->uc_transact.uc_regs))
			goto badframe;
		if (save_tm_user_regs(regs, frame, tm_frame, sigret))
			goto badframe;
	}
	else
#endif
	{
		if (__put_user(0, &rt_sf->uc.uc_link))
			goto badframe;
		if (save_user_regs(regs, frame, tm_frame, sigret, 1))
			goto badframe;
	}
	regs->link = tramp;

#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
	if (MSR_TM_ACTIVE(regs->msr)) {
		if (__put_user((unsigned long)&rt_sf->uc_transact,
			       &rt_sf->uc.uc_link)
		    || __put_user((unsigned long)tm_frame, &rt_sf->uc_transact.uc_regs))
			goto badframe;
	}
	else
#endif
		if (__put_user(0, &rt_sf->uc.uc_link))
			goto badframe;

	current->thread.fp_state.fpscr = 0;	/* turn off all fp exceptions */

	/* create a stack frame for the caller of the handler */