aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/signal_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/signal_64.c')
-rw-r--r--arch/x86/kernel/signal_64.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 827179c5b32a..ccb2a4560c2d 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -285,14 +285,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
285 even if the handler happens to be interrupting 32-bit code. */ 285 even if the handler happens to be interrupting 32-bit code. */
286 regs->cs = __USER_CS; 286 regs->cs = __USER_CS;
287 287
288 /* This, by contrast, has nothing to do with segment registers -
289 see include/asm-x86_64/uaccess.h for details. */
290 set_fs(USER_DS);
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; 288 return 0;
297 289
298give_sigsegv: 290give_sigsegv:
@@ -380,6 +372,28 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
380 ret = setup_rt_frame(sig, ka, info, oldset, regs); 372 ret = setup_rt_frame(sig, ka, info, oldset, regs);
381 373
382 if (ret == 0) { 374 if (ret == 0) {
375 /*
376 * This has nothing to do with segment registers,
377 * despite the name. This magic affects uaccess.h
378 * macros' behavior. Reset it to the normal setting.
379 */
380 set_fs(USER_DS);
381
382 /*
383 * Clear the direction flag as per the ABI for function entry.
384 */
385 regs->flags &= ~X86_EFLAGS_DF;
386
387 /*
388 * Clear TF when entering the signal handler, but
389 * notify any tracer that was single-stepping it.
390 * The tracer may want to single-step inside the
391 * handler too.
392 */
393 regs->flags &= ~X86_EFLAGS_TF;
394 if (test_thread_flag(TIF_SINGLESTEP))
395 ptrace_notify(SIGTRAP);
396
383 spin_lock_irq(&current->sighand->siglock); 397 spin_lock_irq(&current->sighand->siglock);
384 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 398 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
385 if (!(ka->sa.sa_flags & SA_NODEFER)) 399 if (!(ka->sa.sa_flags & SA_NODEFER))