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.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 56b72fb67f9b..1c83e5124c65 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -311,6 +311,35 @@ give_sigsegv:
311} 311}
312 312
313/* 313/*
314 * Return -1L or the syscall number that @regs is executing.
315 */
316static long current_syscall(struct pt_regs *regs)
317{
318 /*
319 * We always sign-extend a -1 value being set here,
320 * so this is always either -1L or a syscall number.
321 */
322 return regs->orig_ax;
323}
324
325/*
326 * Return a value that is -EFOO if the system call in @regs->orig_ax
327 * returned an error. This only works for @regs from @current.
328 */
329static long current_syscall_ret(struct pt_regs *regs)
330{
331#ifdef CONFIG_IA32_EMULATION
332 if (test_thread_flag(TIF_IA32))
333 /*
334 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
335 * and will match correctly in comparisons.
336 */
337 return (int) regs->ax;
338#endif
339 return regs->ax;
340}
341
342/*
314 * OK, we're invoking a handler 343 * OK, we're invoking a handler
315 */ 344 */
316 345
@@ -327,9 +356,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
327#endif 356#endif
328 357
329 /* Are we from a system call? */ 358 /* Are we from a system call? */
330 if ((long)regs->orig_ax >= 0) { 359 if (current_syscall(regs) >= 0) {
331 /* If so, check system call restarting.. */ 360 /* If so, check system call restarting.. */
332 switch (regs->ax) { 361 switch (current_syscall_ret(regs)) {
333 case -ERESTART_RESTARTBLOCK: 362 case -ERESTART_RESTARTBLOCK:
334 case -ERESTARTNOHAND: 363 case -ERESTARTNOHAND:
335 regs->ax = -EINTR; 364 regs->ax = -EINTR;
@@ -426,10 +455,9 @@ static void do_signal(struct pt_regs *regs)
426 } 455 }
427 456
428 /* Did we come from a system call? */ 457 /* Did we come from a system call? */
429 if ((long)regs->orig_ax >= 0) { 458 if (current_syscall(regs) >= 0) {
430 /* Restart the system call - no handlers present */ 459 /* Restart the system call - no handlers present */
431 long res = regs->ax; 460 switch (current_syscall_ret(regs)) {
432 switch (res) {
433 case -ERESTARTNOHAND: 461 case -ERESTARTNOHAND:
434 case -ERESTARTSYS: 462 case -ERESTARTSYS:
435 case -ERESTARTNOINTR: 463 case -ERESTARTNOINTR: