Commit 52a150d8 authored by Linus Torvalds's avatar Linus Torvalds

Handle single-stepping over fast system calls without polluting

the fast case with a pushf/popf, by having the kernel debug trap
set the TIF_SINGLESTEP flag and causing the return path to dtrt.
parent dd0f2bdf
...@@ -609,6 +609,11 @@ __attribute__((regparm(3))) ...@@ -609,6 +609,11 @@ __attribute__((regparm(3)))
void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
__u32 thread_info_flags) __u32 thread_info_flags)
{ {
/* Pending single-step? */
if (thread_info_flags & _TIF_SINGLESTEP) {
regs->eflags |= TF_MASK;
clear_thread_flag(TIF_SINGLESTEP);
}
/* deal with pending signal delivery */ /* deal with pending signal delivery */
if (thread_info_flags & _TIF_SIGPENDING) if (thread_info_flags & _TIF_SIGPENDING)
do_signal(regs,oldset); do_signal(regs,oldset);
......
...@@ -54,19 +54,18 @@ static int __init sysenter_setup(void) ...@@ -54,19 +54,18 @@ static int __init sysenter_setup(void)
0xc3 /* ret */ 0xc3 /* ret */
}; };
static const char sysent[] = { static const char sysent[] = {
0x9c, /* pushf */
0x51, /* push %ecx */ 0x51, /* push %ecx */
0x52, /* push %edx */ 0x52, /* push %edx */
0x55, /* push %ebp */ 0x55, /* push %ebp */
0x89, 0xe5, /* movl %esp,%ebp */ 0x89, 0xe5, /* movl %esp,%ebp */
0x0f, 0x34, /* sysenter */ 0x0f, 0x34, /* sysenter */
0x00, /* align return point */
/* System call restart point is here! (SYSENTER_RETURN - 2) */ /* System call restart point is here! (SYSENTER_RETURN - 2) */
0xeb, 0xfa, /* jmp to "movl %esp,%ebp" */ 0xeb, 0xfa, /* jmp to "movl %esp,%ebp" */
/* System call normal return point is here! (SYSENTER_RETURN in entry.S) */ /* System call normal return point is here! (SYSENTER_RETURN in entry.S) */
0x5d, /* pop %ebp */ 0x5d, /* pop %ebp */
0x5a, /* pop %edx */ 0x5a, /* pop %edx */
0x59, /* pop %ecx */ 0x59, /* pop %ecx */
0x9d, /* popf - restore TF */
0xc3 /* ret */ 0xc3 /* ret */
}; };
unsigned long page = get_zeroed_page(GFP_ATOMIC); unsigned long page = get_zeroed_page(GFP_ATOMIC);
......
...@@ -605,7 +605,7 @@ asmlinkage void do_debug(struct pt_regs * regs, long error_code) ...@@ -605,7 +605,7 @@ asmlinkage void do_debug(struct pt_regs * regs, long error_code)
* interface. * interface.
*/ */
if ((regs->xcs & 3) == 0) if ((regs->xcs & 3) == 0)
goto clear_TF; goto clear_TF_reenable;
if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE) if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
goto clear_TF; goto clear_TF;
} }
...@@ -637,6 +637,8 @@ asmlinkage void do_debug(struct pt_regs * regs, long error_code) ...@@ -637,6 +637,8 @@ asmlinkage void do_debug(struct pt_regs * regs, long error_code)
handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
return; return;
clear_TF_reenable:
set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
clear_TF: clear_TF:
regs->eflags &= ~TF_MASK; regs->eflags &= ~TF_MASK;
return; return;
......
...@@ -109,6 +109,7 @@ static inline struct thread_info *current_thread_info(void) ...@@ -109,6 +109,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ #define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
#define TIF_SIGPENDING 2 /* signal pending */ #define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
...@@ -116,6 +117,7 @@ static inline struct thread_info *current_thread_info(void) ...@@ -116,6 +117,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_USEDFPU (1<<TIF_USEDFPU) #define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment