summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/blackfin/include/asm/thread_info.h2
-rw-r--r--arch/blackfin/kernel/ptrace.c11
-rw-r--r--arch/blackfin/kernel/signal.c3
-rw-r--r--arch/blackfin/mach-common/entry.S2
4 files changed, 15 insertions, 3 deletions
diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h
index 0149c92ceeb0..e9a5614cdbb1 100644
--- a/arch/blackfin/include/asm/thread_info.h
+++ b/arch/blackfin/include/asm/thread_info.h
@@ -103,6 +103,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_FREEZE 6 /* is freezing for suspend */
#define TIF_IRQ_SYNC 7 /* sync pipeline stage */
#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */
+#define TIF_SINGLESTEP 9
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -113,6 +114,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_FREEZE (1<<TIF_FREEZE)
#define _TIF_IRQ_SYNC (1<<TIF_IRQ_SYNC)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
+#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index 0618b8287e34..43eb969405d1 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -220,12 +220,16 @@ void user_enable_single_step(struct task_struct *child)
{
struct pt_regs *regs = task_pt_regs(child);
regs->syscfg |= SYSCFG_SSSTEP;
+
+ set_tsk_thread_flag(child, TIF_SINGLESTEP);
}
void user_disable_single_step(struct task_struct *child)
{
struct pt_regs *regs = task_pt_regs(child);
regs->syscfg &= ~SYSCFG_SSSTEP;
+
+ clear_tsk_thread_flag(child, TIF_SINGLESTEP);
}
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -401,6 +405,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
asmlinkage void syscall_trace_leave(struct pt_regs *regs)
{
- if (test_thread_flag(TIF_SYSCALL_TRACE))
- tracehook_report_syscall_exit(regs, 0);
+ int step;
+
+ step = test_thread_flag(TIF_SINGLESTEP);
+ if (step || test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall_exit(regs, step);
}
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index e60990c0a1f0..28d6f28c058c 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -306,7 +306,8 @@ asmlinkage void do_signal(struct pt_regs *regs)
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
- tracehook_signal_handler(signr, &info, &ka, regs, 1);
+ tracehook_signal_handler(signr, &info, &ka, regs,
+ test_thread_flag(TIF_SINGLESTEP));
}
return;
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 0df5b834d34e..0a9e458d0f7e 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -642,6 +642,8 @@ ENTRY(_system_call)
r7 = [p2+TI_FLAGS];
CC = BITTST(r7,TIF_SYSCALL_TRACE);
if CC JUMP _sys_trace;
+ CC = BITTST(r7,TIF_SINGLESTEP);
+ if CC JUMP _sys_trace;
/* Execute the appropriate system call */