Skip to content

Commit

Permalink
Blackfin: fix single stepping over system calls
Browse files Browse the repository at this point in the history
On Blackfin systems, the hardware single step exception triggers before
the system call exception, so we need to save this info to process it
later on.  Otherwise, single stepping in userspace misses a few insns
right after the system call.

This is based a bit on the SuperH code added in commit 4b505db.

Reported-by: Roland McGrath <roland@redhat.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
  • Loading branch information
Mike Frysinger committed Mar 9, 2010
1 parent e8f263d commit 600482c
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 3 deletions.
2 changes: 2 additions & 0 deletions arch/blackfin/include/asm/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 */

Expand Down
11 changes: 9 additions & 2 deletions arch/blackfin/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
3 changes: 2 additions & 1 deletion arch/blackfin/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions arch/blackfin/mach-common/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down

0 comments on commit 600482c

Please sign in to comment.