diff options
| author | Paul Mackerras <paulus@samba.org> | 2004-12-16 17:19:57 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-12-16 17:19:57 -0800 |
| commit | 44e0a901c266f940ab4bd4c37b10f0af5de4e03b (patch) | |
| tree | 549fc38fd23539bcf001b20f8c7665bafb81e36c /include | |
| parent | b832c33597ae7acc7448614e305733aa98713b82 (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.h | 2 | ||||
| -rw-r--r-- | include/asm-ppc64/thread_info.h | 2 |
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 | \ |
