diff options
author | Roland McGrath <roland@redhat.com> | 2008-07-09 04:33:14 -0400 |
---|---|---|
committer | Roland McGrath <roland@redhat.com> | 2008-07-16 15:15:16 -0400 |
commit | 64f097331928b01d704047c1dbc738bb6d2a9bf9 (patch) | |
tree | 402fe071f26a9bbdbffdc98c2f592ff9eeb6a404 | |
parent | 6718d0d6da2749d3bff522e6057e97e6aa85e4d1 (diff) |
x86 ptrace: unify TIF_SINGLESTEP
This unifies the treatment of TIF_SINGLESTEP on i386 and x86_64.
The bit is now excluded from _TIF_WORK_MASK on i386 as it has been
on x86_64. This means the do_notify_resume() path using it is never
used, so TIF_SINGLESTEP is not cleared on returning to user mode.
Both now leave TIF_SINGLESTEP set when returning to user, so that
it's already set on an int $0x80 system call entry. This removes
the need for testing TF on the system_call path. Doing it this way
fixes the regression for PTRACE_SINGLESTEP into a sigreturn syscall,
introduced by commit 1e2e99f0e4aa6363e8515ed17011c210c8f1b52a.
The clear_TF_reenable case that sets TIF_SINGLESTEP can only happen
on a non-exception kernel entry, i.e. sysenter/syscall instruction.
That will always get to the syscall exit tracing path.
Signed-off-by: Roland McGrath <roland@redhat.com>
-rw-r--r-- | arch/x86/kernel/entry_32.S | 4 | ||||
-rw-r--r-- | arch/x86/kernel/signal_32.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/signal_64.c | 6 | ||||
-rw-r--r-- | include/asm-x86/thread_info.h | 4 |
4 files changed, 2 insertions, 18 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 6bc07f0f1202..0ad987d02b72 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -383,10 +383,6 @@ syscall_exit: | |||
383 | # setting need_resched or sigpending | 383 | # setting need_resched or sigpending |
384 | # between sampling and the iret | 384 | # between sampling and the iret |
385 | TRACE_IRQS_OFF | 385 | TRACE_IRQS_OFF |
386 | testl $X86_EFLAGS_TF,PT_EFLAGS(%esp) # If tracing set singlestep flag on exit | ||
387 | jz no_singlestep | ||
388 | orl $_TIF_SINGLESTEP,TI_flags(%ebp) | ||
389 | no_singlestep: | ||
390 | movl TI_flags(%ebp), %ecx | 386 | movl TI_flags(%ebp), %ecx |
391 | testw $_TIF_ALLWORK_MASK, %cx # current->work | 387 | testw $_TIF_ALLWORK_MASK, %cx # current->work |
392 | jne syscall_exit_work | 388 | jne syscall_exit_work |
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c index d92373630963..295b5f5c9389 100644 --- a/arch/x86/kernel/signal_32.c +++ b/arch/x86/kernel/signal_32.c | |||
@@ -657,12 +657,6 @@ static void do_signal(struct pt_regs *regs) | |||
657 | void | 657 | void |
658 | do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) | 658 | do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) |
659 | { | 659 | { |
660 | /* Pending single-step? */ | ||
661 | if (thread_info_flags & _TIF_SINGLESTEP) { | ||
662 | regs->flags |= X86_EFLAGS_TF; | ||
663 | clear_thread_flag(TIF_SINGLESTEP); | ||
664 | } | ||
665 | |||
666 | /* deal with pending signal delivery */ | 660 | /* deal with pending signal delivery */ |
667 | if (thread_info_flags & _TIF_SIGPENDING) | 661 | if (thread_info_flags & _TIF_SIGPENDING) |
668 | do_signal(regs); | 662 | do_signal(regs); |
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index e53b267662e7..bf87684474f1 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c | |||
@@ -487,12 +487,6 @@ static void do_signal(struct pt_regs *regs) | |||
487 | void do_notify_resume(struct pt_regs *regs, void *unused, | 487 | void do_notify_resume(struct pt_regs *regs, void *unused, |
488 | __u32 thread_info_flags) | 488 | __u32 thread_info_flags) |
489 | { | 489 | { |
490 | /* Pending single-step? */ | ||
491 | if (thread_info_flags & _TIF_SINGLESTEP) { | ||
492 | regs->flags |= X86_EFLAGS_TF; | ||
493 | clear_thread_flag(TIF_SINGLESTEP); | ||
494 | } | ||
495 | |||
496 | #ifdef CONFIG_X86_MCE | 490 | #ifdef CONFIG_X86_MCE |
497 | /* notify userspace of pending MCEs */ | 491 | /* notify userspace of pending MCEs */ |
498 | if (thread_info_flags & _TIF_MCE_NOTIFY) | 492 | if (thread_info_flags & _TIF_MCE_NOTIFY) |
diff --git a/include/asm-x86/thread_info.h b/include/asm-x86/thread_info.h index 895339d2bc0b..fb8d3cdf143e 100644 --- a/include/asm-x86/thread_info.h +++ b/include/asm-x86/thread_info.h | |||
@@ -124,7 +124,7 @@ struct thread_info { | |||
124 | /* work to do on interrupt/exception return */ | 124 | /* work to do on interrupt/exception return */ |
125 | #define _TIF_WORK_MASK \ | 125 | #define _TIF_WORK_MASK \ |
126 | (0x0000FFFF & \ | 126 | (0x0000FFFF & \ |
127 | ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP| \ | 127 | ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT| \ |
128 | _TIF_SECCOMP|_TIF_SYSCALL_EMU)) | 128 | _TIF_SECCOMP|_TIF_SYSCALL_EMU)) |
129 | 129 | ||
130 | /* work to do on any return to user space */ | 130 | /* work to do on any return to user space */ |
@@ -132,7 +132,7 @@ struct thread_info { | |||
132 | 132 | ||
133 | /* Only used for 64 bit */ | 133 | /* Only used for 64 bit */ |
134 | #define _TIF_DO_NOTIFY_MASK \ | 134 | #define _TIF_DO_NOTIFY_MASK \ |
135 | (_TIF_SIGPENDING|_TIF_SINGLESTEP|_TIF_MCE_NOTIFY|_TIF_HRTICK_RESCHED) | 135 | (_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_HRTICK_RESCHED) |
136 | 136 | ||
137 | /* flags to check in __switch_to() */ | 137 | /* flags to check in __switch_to() */ |
138 | #define _TIF_WORK_CTXSW \ | 138 | #define _TIF_WORK_CTXSW \ |