summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2004-12-16 17:19:57 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-16 17:19:57 -0800
commit44e0a901c266f940ab4bd4c37b10f0af5de4e03b (patch)
tree549fc38fd23539bcf001b20f8c7665bafb81e36c /include
parentb832c33597ae7acc7448614e305733aa98713b82 (diff)
[PATCH] ppc64: fix single-stepping into/out of signal handlers
This is the second of 3 patches from David Woodhouse which fix various problems with signal handling on ppc64. The problem that this patch fixes is that a process being single-stepped will execute one instruction too many in certain cases: when a signal is delivered, when a signal handler returns, and when a system call instruction is single-stepped. This patch fixes it by checking if the process is being single-stepped in the syscall exit path and on signal delivery, and stopping it if so. To avoid slowing down the syscall exit path in the normal case, we use a bit in the thread_info flags, which can be tested along with the other bits we already test in the syscall exit path. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
-rw-r--r--include/asm-ppc64/ptrace-common.h2
-rw-r--r--include/asm-ppc64/thread_info.h2
2 files changed, 4 insertions, 0 deletions
diff --git a/include/asm-ppc64/ptrace-common.h b/include/asm-ppc64/ptrace-common.h
index 3dbd3e5847b3..af03547f9c7e 100644
--- a/include/asm-ppc64/ptrace-common.h
+++ b/include/asm-ppc64/ptrace-common.h
@@ -58,6 +58,7 @@ static inline void set_single_step(struct task_struct *task)
struct pt_regs *regs = task->thread.regs;
if (regs != NULL)
regs->msr |= MSR_SE;
+ set_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
}
static inline void clear_single_step(struct task_struct *task)
@@ -65,6 +66,7 @@ static inline void clear_single_step(struct task_struct *task)
struct pt_regs *regs = task->thread.regs;
if (regs != NULL)
regs->msr &= ~MSR_SE;
+ clear_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
}
#endif /* _PPC64_PTRACE_COMMON_H */
diff --git a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h
index 6a8a4c4c334d..595d67ef4b6f 100644
--- a/include/asm-ppc64/thread_info.h
+++ b/include/asm-ppc64/thread_info.h
@@ -97,6 +97,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_RUN_LIGHT 6 /* iSeries run light */
#define TIF_ABI_PENDING 7 /* 32/64 bit switch needed */
#define TIF_SYSCALL_AUDIT 8 /* syscall auditing active */
+#define TIF_SINGLESTEP 9 /* singlestepping active */
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -108,6 +109,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_RUN_LIGHT (1<<TIF_RUN_LIGHT)
#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
#define _TIF_USER_WORK_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \