diff options
Diffstat (limited to 'arch/x86/kernel/signal_64.c')
-rw-r--r-- | arch/x86/kernel/signal_64.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index 827179c5b32a..3a76702dc3f1 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c | |||
@@ -289,10 +289,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
289 | see include/asm-x86_64/uaccess.h for details. */ | 289 | see include/asm-x86_64/uaccess.h for details. */ |
290 | set_fs(USER_DS); | 290 | set_fs(USER_DS); |
291 | 291 | ||
292 | regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF); | ||
293 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
294 | ptrace_notify(SIGTRAP); | ||
295 | |||
296 | return 0; | 292 | return 0; |
297 | 293 | ||
298 | give_sigsegv: | 294 | give_sigsegv: |
@@ -380,6 +376,21 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
380 | ret = setup_rt_frame(sig, ka, info, oldset, regs); | 376 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |
381 | 377 | ||
382 | if (ret == 0) { | 378 | if (ret == 0) { |
379 | /* | ||
380 | * Clear the direction flag as per the ABI for function entry. | ||
381 | */ | ||
382 | regs->flags &= ~X86_EFLAGS_DF; | ||
383 | |||
384 | /* | ||
385 | * Clear TF when entering the signal handler, but | ||
386 | * notify any tracer that was single-stepping it. | ||
387 | * The tracer may want to single-step inside the | ||
388 | * handler too. | ||
389 | */ | ||
390 | regs->flags &= ~X86_EFLAGS_TF; | ||
391 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
392 | ptrace_notify(SIGTRAP); | ||
393 | |||
383 | spin_lock_irq(¤t->sighand->siglock); | 394 | spin_lock_irq(¤t->sighand->siglock); |
384 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 395 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
385 | if (!(ka->sa.sa_flags & SA_NODEFER)) | 396 | if (!(ka->sa.sa_flags & SA_NODEFER)) |