diff options
Diffstat (limited to 'arch/x86/kernel/signal_64.c')
-rw-r--r-- | arch/x86/kernel/signal_64.c | 30 |
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 | ||
298 | give_sigsegv: | 290 | give_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(¤t->sighand->siglock); | 397 | spin_lock_irq(¤t->sighand->siglock); |
384 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 398 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
385 | if (!(ka->sa.sa_flags & SA_NODEFER)) | 399 | if (!(ka->sa.sa_flags & SA_NODEFER)) |