aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/signal.c')
-rw-r--r--arch/powerpc/kernel/signal.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index cf12eae02de5..457e97aa2945 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -13,10 +13,12 @@
13#include <linux/signal.h> 13#include <linux/signal.h>
14#include <linux/uprobes.h> 14#include <linux/uprobes.h>
15#include <linux/key.h> 15#include <linux/key.h>
16#include <linux/context_tracking.h>
16#include <asm/hw_breakpoint.h> 17#include <asm/hw_breakpoint.h>
17#include <asm/uaccess.h> 18#include <asm/uaccess.h>
18#include <asm/unistd.h> 19#include <asm/unistd.h>
19#include <asm/debug.h> 20#include <asm/debug.h>
21#include <asm/tm.h>
20 22
21#include "signal.h" 23#include "signal.h"
22 24
@@ -24,18 +26,18 @@
24 * through debug.exception-trace sysctl. 26 * through debug.exception-trace sysctl.
25 */ 27 */
26 28
27int show_unhandled_signals = 0; 29int show_unhandled_signals = 1;
28 30
29/* 31/*
30 * Allocate space for the signal frame 32 * Allocate space for the signal frame
31 */ 33 */
32void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, 34void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp,
33 size_t frame_size, int is_32) 35 size_t frame_size, int is_32)
34{ 36{
35 unsigned long oldsp, newsp; 37 unsigned long oldsp, newsp;
36 38
37 /* Default to using normal stack */ 39 /* Default to using normal stack */
38 oldsp = get_clean_sp(regs, is_32); 40 oldsp = get_clean_sp(sp, is_32);
39 41
40 /* Check for alt stack */ 42 /* Check for alt stack */
41 if ((ka->sa.sa_flags & SA_ONSTACK) && 43 if ((ka->sa.sa_flags & SA_ONSTACK) &&
@@ -159,6 +161,8 @@ static int do_signal(struct pt_regs *regs)
159 161
160void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) 162void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
161{ 163{
164 user_exit();
165
162 if (thread_info_flags & _TIF_UPROBE) 166 if (thread_info_flags & _TIF_UPROBE)
163 uprobe_notify_resume(regs); 167 uprobe_notify_resume(regs);
164 168
@@ -169,4 +173,41 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
169 clear_thread_flag(TIF_NOTIFY_RESUME); 173 clear_thread_flag(TIF_NOTIFY_RESUME);
170 tracehook_notify_resume(regs); 174 tracehook_notify_resume(regs);
171 } 175 }
176
177 user_enter();
178}
179
180unsigned long get_tm_stackpointer(struct pt_regs *regs)
181{
182 /* When in an active transaction that takes a signal, we need to be
183 * careful with the stack. It's possible that the stack has moved back
184 * up after the tbegin. The obvious case here is when the tbegin is
185 * called inside a function that returns before a tend. In this case,
186 * the stack is part of the checkpointed transactional memory state.
187 * If we write over this non transactionally or in suspend, we are in
188 * trouble because if we get a tm abort, the program counter and stack
189 * pointer will be back at the tbegin but our in memory stack won't be
190 * valid anymore.
191 *
192 * To avoid this, when taking a signal in an active transaction, we
193 * need to use the stack pointer from the checkpointed state, rather
194 * than the speculated state. This ensures that the signal context
195 * (written tm suspended) will be written below the stack required for
196 * the rollback. The transaction is aborted becuase of the treclaim,
197 * so any memory written between the tbegin and the signal will be
198 * rolled back anyway.
199 *
200 * For signals taken in non-TM or suspended mode, we use the
201 * normal/non-checkpointed stack pointer.
202 */
203
204#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
205 if (MSR_TM_ACTIVE(regs->msr)) {
206 tm_enable();
207 tm_reclaim(&current->thread, regs->msr, TM_CAUSE_SIGNAL);
208 if (MSR_TM_TRANSACTIONAL(regs->msr))
209 return current->thread.ckpt_regs.gpr[1];
210 }
211#endif
212 return regs->gpr[1];
172} 213}