aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-11-09 23:51:47 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2013-02-14 09:21:17 -0500
commit235b80226b986dabcbba844968f7807866bd0bfe (patch)
tree834a02573bcb1986c0b5e73af8fc8bd7d16dbffb /arch/x86/kernel
parent08f739570de697dc06b949ba3be33acdda21498c (diff)
x86: convert to ksignal
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/signal.c117
1 files changed, 54 insertions, 63 deletions
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index d5b1f8a912ff..69562992e457 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -278,7 +278,7 @@ static const struct {
278}; 278};
279 279
280static int 280static int
281__setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, 281__setup_frame(int sig, struct ksignal *ksig, sigset_t *set,
282 struct pt_regs *regs) 282 struct pt_regs *regs)
283{ 283{
284 struct sigframe __user *frame; 284 struct sigframe __user *frame;
@@ -286,7 +286,7 @@ __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
286 int err = 0; 286 int err = 0;
287 void __user *fpstate = NULL; 287 void __user *fpstate = NULL;
288 288
289 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); 289 frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fpstate);
290 290
291 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 291 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
292 return -EFAULT; 292 return -EFAULT;
@@ -307,8 +307,8 @@ __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
307 restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn); 307 restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
308 else 308 else
309 restorer = &frame->retcode; 309 restorer = &frame->retcode;
310 if (ka->sa.sa_flags & SA_RESTORER) 310 if (ksig->ka.sa.sa_flags & SA_RESTORER)
311 restorer = ka->sa.sa_restorer; 311 restorer = ksig->ka.sa.sa_restorer;
312 312
313 /* Set up to return from userspace. */ 313 /* Set up to return from userspace. */
314 err |= __put_user(restorer, &frame->pretcode); 314 err |= __put_user(restorer, &frame->pretcode);
@@ -327,7 +327,7 @@ __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
327 327
328 /* Set up registers for signal handler */ 328 /* Set up registers for signal handler */
329 regs->sp = (unsigned long)frame; 329 regs->sp = (unsigned long)frame;
330 regs->ip = (unsigned long)ka->sa.sa_handler; 330 regs->ip = (unsigned long)ksig->ka.sa.sa_handler;
331 regs->ax = (unsigned long)sig; 331 regs->ax = (unsigned long)sig;
332 regs->dx = 0; 332 regs->dx = 0;
333 regs->cx = 0; 333 regs->cx = 0;
@@ -340,7 +340,7 @@ __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
340 return 0; 340 return 0;
341} 341}
342 342
343static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 343static int __setup_rt_frame(int sig, struct ksignal *ksig,
344 sigset_t *set, struct pt_regs *regs) 344 sigset_t *set, struct pt_regs *regs)
345{ 345{
346 struct rt_sigframe __user *frame; 346 struct rt_sigframe __user *frame;
@@ -348,7 +348,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
348 int err = 0; 348 int err = 0;
349 void __user *fpstate = NULL; 349 void __user *fpstate = NULL;
350 350
351 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); 351 frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fpstate);
352 352
353 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 353 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
354 return -EFAULT; 354 return -EFAULT;
@@ -368,8 +368,8 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
368 368
369 /* Set up to return from userspace. */ 369 /* Set up to return from userspace. */
370 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn); 370 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
371 if (ka->sa.sa_flags & SA_RESTORER) 371 if (ksig->ka.sa.sa_flags & SA_RESTORER)
372 restorer = ka->sa.sa_restorer; 372 restorer = ksig->ka.sa.sa_restorer;
373 put_user_ex(restorer, &frame->pretcode); 373 put_user_ex(restorer, &frame->pretcode);
374 374
375 /* 375 /*
@@ -382,7 +382,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
382 put_user_ex(*((u64 *)&rt_retcode), (u64 *)frame->retcode); 382 put_user_ex(*((u64 *)&rt_retcode), (u64 *)frame->retcode);
383 } put_user_catch(err); 383 } put_user_catch(err);
384 384
385 err |= copy_siginfo_to_user(&frame->info, info); 385 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
386 err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate, 386 err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
387 regs, set->sig[0]); 387 regs, set->sig[0]);
388 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 388 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
@@ -392,7 +392,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
392 392
393 /* Set up registers for signal handler */ 393 /* Set up registers for signal handler */
394 regs->sp = (unsigned long)frame; 394 regs->sp = (unsigned long)frame;
395 regs->ip = (unsigned long)ka->sa.sa_handler; 395 regs->ip = (unsigned long)ksig->ka.sa.sa_handler;
396 regs->ax = (unsigned long)sig; 396 regs->ax = (unsigned long)sig;
397 regs->dx = (unsigned long)&frame->info; 397 regs->dx = (unsigned long)&frame->info;
398 regs->cx = (unsigned long)&frame->uc; 398 regs->cx = (unsigned long)&frame->uc;
@@ -405,20 +405,20 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
405 return 0; 405 return 0;
406} 406}
407#else /* !CONFIG_X86_32 */ 407#else /* !CONFIG_X86_32 */
408static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 408static int __setup_rt_frame(int sig, struct ksignal *ksig,
409 sigset_t *set, struct pt_regs *regs) 409 sigset_t *set, struct pt_regs *regs)
410{ 410{
411 struct rt_sigframe __user *frame; 411 struct rt_sigframe __user *frame;
412 void __user *fp = NULL; 412 void __user *fp = NULL;
413 int err = 0; 413 int err = 0;
414 414
415 frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe), &fp); 415 frame = get_sigframe(&ksig->ka, regs, sizeof(struct rt_sigframe), &fp);
416 416
417 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 417 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
418 return -EFAULT; 418 return -EFAULT;
419 419
420 if (ka->sa.sa_flags & SA_SIGINFO) { 420 if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
421 if (copy_siginfo_to_user(&frame->info, info)) 421 if (copy_siginfo_to_user(&frame->info, &ksig->info))
422 return -EFAULT; 422 return -EFAULT;
423 } 423 }
424 424
@@ -434,8 +434,8 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
434 /* Set up to return from userspace. If provided, use a stub 434 /* Set up to return from userspace. If provided, use a stub
435 already in userspace. */ 435 already in userspace. */
436 /* x86-64 should always use SA_RESTORER. */ 436 /* x86-64 should always use SA_RESTORER. */
437 if (ka->sa.sa_flags & SA_RESTORER) { 437 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
438 put_user_ex(ka->sa.sa_restorer, &frame->pretcode); 438 put_user_ex(ksig->ka.sa.sa_restorer, &frame->pretcode);
439 } else { 439 } else {
440 /* could use a vstub here */ 440 /* could use a vstub here */
441 err |= -EFAULT; 441 err |= -EFAULT;
@@ -457,7 +457,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
457 next argument after the signal number on the stack. */ 457 next argument after the signal number on the stack. */
458 regs->si = (unsigned long)&frame->info; 458 regs->si = (unsigned long)&frame->info;
459 regs->dx = (unsigned long)&frame->uc; 459 regs->dx = (unsigned long)&frame->uc;
460 regs->ip = (unsigned long) ka->sa.sa_handler; 460 regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
461 461
462 regs->sp = (unsigned long)frame; 462 regs->sp = (unsigned long)frame;
463 463
@@ -469,8 +469,8 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
469} 469}
470#endif /* CONFIG_X86_32 */ 470#endif /* CONFIG_X86_32 */
471 471
472static int x32_setup_rt_frame(int sig, struct k_sigaction *ka, 472static int x32_setup_rt_frame(struct ksignal *ksig,
473 siginfo_t *info, compat_sigset_t *set, 473 compat_sigset_t *set,
474 struct pt_regs *regs) 474 struct pt_regs *regs)
475{ 475{
476#ifdef CONFIG_X86_X32_ABI 476#ifdef CONFIG_X86_X32_ABI
@@ -479,13 +479,13 @@ static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
479 int err = 0; 479 int err = 0;
480 void __user *fpstate = NULL; 480 void __user *fpstate = NULL;
481 481
482 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); 482 frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fpstate);
483 483
484 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 484 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
485 return -EFAULT; 485 return -EFAULT;
486 486
487 if (ka->sa.sa_flags & SA_SIGINFO) { 487 if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
488 if (copy_siginfo_to_user32(&frame->info, info)) 488 if (copy_siginfo_to_user32(&frame->info, &ksig->info))
489 return -EFAULT; 489 return -EFAULT;
490 } 490 }
491 491
@@ -499,8 +499,8 @@ static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
499 err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp); 499 err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
500 put_user_ex(0, &frame->uc.uc__pad0); 500 put_user_ex(0, &frame->uc.uc__pad0);
501 501
502 if (ka->sa.sa_flags & SA_RESTORER) { 502 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
503 restorer = ka->sa.sa_restorer; 503 restorer = ksig->ka.sa.sa_restorer;
504 } else { 504 } else {
505 /* could use a vstub here */ 505 /* could use a vstub here */
506 restorer = NULL; 506 restorer = NULL;
@@ -518,10 +518,10 @@ static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
518 518
519 /* Set up registers for signal handler */ 519 /* Set up registers for signal handler */
520 regs->sp = (unsigned long) frame; 520 regs->sp = (unsigned long) frame;
521 regs->ip = (unsigned long) ka->sa.sa_handler; 521 regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
522 522
523 /* We use the x32 calling convention here... */ 523 /* We use the x32 calling convention here... */
524 regs->di = sig; 524 regs->di = ksig->sig;
525 regs->si = (unsigned long) &frame->info; 525 regs->si = (unsigned long) &frame->info;
526 regs->dx = (unsigned long) &frame->uc; 526 regs->dx = (unsigned long) &frame->uc;
527 527
@@ -611,30 +611,29 @@ static int signr_convert(int sig)
611} 611}
612 612
613static int 613static int
614setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 614setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
615 struct pt_regs *regs)
616{ 615{
617 int usig = signr_convert(sig); 616 int usig = signr_convert(ksig->sig);
618 sigset_t *set = sigmask_to_save(); 617 sigset_t *set = sigmask_to_save();
619 compat_sigset_t *cset = (compat_sigset_t *) set; 618 compat_sigset_t *cset = (compat_sigset_t *) set;
620 619
621 /* Set up the stack frame */ 620 /* Set up the stack frame */
622 if (is_ia32_frame()) { 621 if (is_ia32_frame()) {
623 if (ka->sa.sa_flags & SA_SIGINFO) 622 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
624 return ia32_setup_rt_frame(usig, ka, info, cset, regs); 623 return ia32_setup_rt_frame(usig, ksig, cset, regs);
625 else 624 else
626 return ia32_setup_frame(usig, ka, cset, regs); 625 return ia32_setup_frame(usig, ksig, cset, regs);
627 } else if (is_x32_frame()) { 626 } else if (is_x32_frame()) {
628 return x32_setup_rt_frame(usig, ka, info, cset, regs); 627 return x32_setup_rt_frame(ksig, cset, regs);
629 } else { 628 } else {
630 return __setup_rt_frame(sig, ka, info, set, regs); 629 return __setup_rt_frame(ksig->sig, ksig, set, regs);
631 } 630 }
632} 631}
633 632
634static void 633static void
635handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 634handle_signal(struct ksignal *ksig, struct pt_regs *regs)
636 struct pt_regs *regs)
637{ 635{
636 bool failed;
638 /* Are we from a system call? */ 637 /* Are we from a system call? */
639 if (syscall_get_nr(current, regs) >= 0) { 638 if (syscall_get_nr(current, regs) >= 0) {
640 /* If so, check system call restarting.. */ 639 /* If so, check system call restarting.. */
@@ -645,7 +644,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
645 break; 644 break;
646 645
647 case -ERESTARTSYS: 646 case -ERESTARTSYS:
648 if (!(ka->sa.sa_flags & SA_RESTART)) { 647 if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
649 regs->ax = -EINTR; 648 regs->ax = -EINTR;
650 break; 649 break;
651 } 650 }
@@ -665,26 +664,21 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
665 likely(test_and_clear_thread_flag(TIF_FORCED_TF))) 664 likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
666 regs->flags &= ~X86_EFLAGS_TF; 665 regs->flags &= ~X86_EFLAGS_TF;
667 666
668 if (setup_rt_frame(sig, ka, info, regs) < 0) { 667 failed = (setup_rt_frame(ksig, regs) < 0);
669 force_sigsegv(sig, current); 668 if (!failed) {
670 return; 669 /*
670 * Clear the direction flag as per the ABI for function entry.
671 */
672 regs->flags &= ~X86_EFLAGS_DF;
673 /*
674 * Clear TF when entering the signal handler, but
675 * notify any tracer that was single-stepping it.
676 * The tracer may want to single-step inside the
677 * handler too.
678 */
679 regs->flags &= ~X86_EFLAGS_TF;
671 } 680 }
672 681 signal_setup_done(failed, ksig, test_thread_flag(TIF_SINGLESTEP));
673 /*
674 * Clear the direction flag as per the ABI for function entry.
675 */
676 regs->flags &= ~X86_EFLAGS_DF;
677
678 /*
679 * Clear TF when entering the signal handler, but
680 * notify any tracer that was single-stepping it.
681 * The tracer may want to single-step inside the
682 * handler too.
683 */
684 regs->flags &= ~X86_EFLAGS_TF;
685
686 signal_delivered(sig, info, ka, regs,
687 test_thread_flag(TIF_SINGLESTEP));
688} 682}
689 683
690#ifdef CONFIG_X86_32 684#ifdef CONFIG_X86_32
@@ -701,14 +695,11 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
701 */ 695 */
702static void do_signal(struct pt_regs *regs) 696static void do_signal(struct pt_regs *regs)
703{ 697{
704 struct k_sigaction ka; 698 struct ksignal ksig;
705 siginfo_t info;
706 int signr;
707 699
708 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 700 if (get_signal(&ksig)) {
709 if (signr > 0) {
710 /* Whee! Actually deliver the signal. */ 701 /* Whee! Actually deliver the signal. */
711 handle_signal(signr, &info, &ka, regs); 702 handle_signal(&ksig, regs);
712 return; 703 return;
713 } 704 }
714 705