diff options
author | Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com> | 2008-11-24 21:24:11 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-25 23:11:54 -0500 |
commit | e5fa2d063cf2ca38eae5fb3469315db669d5c041 (patch) | |
tree | ce3deacf11e47bed1066dfa8039a2aa38e117126 | |
parent | bfeb91a9435889ef4fe7bfbb4b673f625e69e790 (diff) |
x86: signal: unify signal_{32|64}.c, prepare
Impact: cleanup
Add #ifdef directive for 32-bit only code.
Signed-off-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/kernel/signal_32.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/signal_64.c | 116 |
2 files changed, 121 insertions, 1 deletions
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c index e9f71298e746..b1f4d34e0a38 100644 --- a/arch/x86/kernel/signal_32.c +++ b/arch/x86/kernel/signal_32.c | |||
@@ -1,8 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 1991, 1992 Linus Torvalds | 2 | * Copyright (C) 1991, 1992 Linus Torvalds |
3 | * Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs | ||
3 | * | 4 | * |
4 | * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson | 5 | * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson |
5 | * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes | 6 | * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes |
7 | * 2000-2002 x86-64 support by Andi Kleen | ||
6 | */ | 8 | */ |
7 | 9 | ||
8 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
@@ -481,6 +483,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
481 | } | 483 | } |
482 | #endif /* CONFIG_X86_32 */ | 484 | #endif /* CONFIG_X86_32 */ |
483 | 485 | ||
486 | #ifdef CONFIG_X86_32 | ||
484 | /* | 487 | /* |
485 | * Atomically swap in the new signal mask, and wait for a signal. | 488 | * Atomically swap in the new signal mask, and wait for a signal. |
486 | */ | 489 | */ |
@@ -535,6 +538,7 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, | |||
535 | 538 | ||
536 | return ret; | 539 | return ret; |
537 | } | 540 | } |
541 | #endif /* CONFIG_X86_32 */ | ||
538 | 542 | ||
539 | #ifdef CONFIG_X86_32 | 543 | #ifdef CONFIG_X86_32 |
540 | asmlinkage int sys_sigaltstack(unsigned long bx) | 544 | asmlinkage int sys_sigaltstack(unsigned long bx) |
@@ -561,6 +565,7 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | |||
561 | /* | 565 | /* |
562 | * Do a signal return; undo the signal stack. | 566 | * Do a signal return; undo the signal stack. |
563 | */ | 567 | */ |
568 | #ifdef CONFIG_X86_32 | ||
564 | asmlinkage unsigned long sys_sigreturn(unsigned long __unused) | 569 | asmlinkage unsigned long sys_sigreturn(unsigned long __unused) |
565 | { | 570 | { |
566 | struct sigframe __user *frame; | 571 | struct sigframe __user *frame; |
@@ -603,6 +608,7 @@ badframe: | |||
603 | 608 | ||
604 | return 0; | 609 | return 0; |
605 | } | 610 | } |
611 | #endif /* CONFIG_X86_32 */ | ||
606 | 612 | ||
607 | static long do_rt_sigreturn(struct pt_regs *regs) | 613 | static long do_rt_sigreturn(struct pt_regs *regs) |
608 | { | 614 | { |
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index 2da7e6e60807..b1f4d34e0a38 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c | |||
@@ -54,12 +54,24 @@ | |||
54 | err |= __get_user(regs->x, &sc->x); \ | 54 | err |= __get_user(regs->x, &sc->x); \ |
55 | } | 55 | } |
56 | 56 | ||
57 | #define COPY_SEG(seg) { \ | ||
58 | unsigned short tmp; \ | ||
59 | err |= __get_user(tmp, &sc->seg); \ | ||
60 | regs->seg = tmp; \ | ||
61 | } | ||
62 | |||
57 | #define COPY_SEG_CPL3(seg) { \ | 63 | #define COPY_SEG_CPL3(seg) { \ |
58 | unsigned short tmp; \ | 64 | unsigned short tmp; \ |
59 | err |= __get_user(tmp, &sc->seg); \ | 65 | err |= __get_user(tmp, &sc->seg); \ |
60 | regs->seg = tmp | 3; \ | 66 | regs->seg = tmp | 3; \ |
61 | } | 67 | } |
62 | 68 | ||
69 | #define GET_SEG(seg) { \ | ||
70 | unsigned short tmp; \ | ||
71 | err |= __get_user(tmp, &sc->seg); \ | ||
72 | loadsegment(seg, tmp); \ | ||
73 | } | ||
74 | |||
63 | static int | 75 | static int |
64 | restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, | 76 | restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, |
65 | unsigned long *pax) | 77 | unsigned long *pax) |
@@ -472,6 +484,63 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
472 | #endif /* CONFIG_X86_32 */ | 484 | #endif /* CONFIG_X86_32 */ |
473 | 485 | ||
474 | #ifdef CONFIG_X86_32 | 486 | #ifdef CONFIG_X86_32 |
487 | /* | ||
488 | * Atomically swap in the new signal mask, and wait for a signal. | ||
489 | */ | ||
490 | asmlinkage int | ||
491 | sys_sigsuspend(int history0, int history1, old_sigset_t mask) | ||
492 | { | ||
493 | mask &= _BLOCKABLE; | ||
494 | spin_lock_irq(¤t->sighand->siglock); | ||
495 | current->saved_sigmask = current->blocked; | ||
496 | siginitset(¤t->blocked, mask); | ||
497 | recalc_sigpending(); | ||
498 | spin_unlock_irq(¤t->sighand->siglock); | ||
499 | |||
500 | current->state = TASK_INTERRUPTIBLE; | ||
501 | schedule(); | ||
502 | set_restore_sigmask(); | ||
503 | |||
504 | return -ERESTARTNOHAND; | ||
505 | } | ||
506 | |||
507 | asmlinkage int | ||
508 | sys_sigaction(int sig, const struct old_sigaction __user *act, | ||
509 | struct old_sigaction __user *oact) | ||
510 | { | ||
511 | struct k_sigaction new_ka, old_ka; | ||
512 | int ret; | ||
513 | |||
514 | if (act) { | ||
515 | old_sigset_t mask; | ||
516 | |||
517 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | ||
518 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | ||
519 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) | ||
520 | return -EFAULT; | ||
521 | |||
522 | __get_user(new_ka.sa.sa_flags, &act->sa_flags); | ||
523 | __get_user(mask, &act->sa_mask); | ||
524 | siginitset(&new_ka.sa.sa_mask, mask); | ||
525 | } | ||
526 | |||
527 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | ||
528 | |||
529 | if (!ret && oact) { | ||
530 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | ||
531 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | ||
532 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) | ||
533 | return -EFAULT; | ||
534 | |||
535 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | ||
536 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
537 | } | ||
538 | |||
539 | return ret; | ||
540 | } | ||
541 | #endif /* CONFIG_X86_32 */ | ||
542 | |||
543 | #ifdef CONFIG_X86_32 | ||
475 | asmlinkage int sys_sigaltstack(unsigned long bx) | 544 | asmlinkage int sys_sigaltstack(unsigned long bx) |
476 | { | 545 | { |
477 | /* | 546 | /* |
@@ -496,6 +565,51 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | |||
496 | /* | 565 | /* |
497 | * Do a signal return; undo the signal stack. | 566 | * Do a signal return; undo the signal stack. |
498 | */ | 567 | */ |
568 | #ifdef CONFIG_X86_32 | ||
569 | asmlinkage unsigned long sys_sigreturn(unsigned long __unused) | ||
570 | { | ||
571 | struct sigframe __user *frame; | ||
572 | struct pt_regs *regs; | ||
573 | unsigned long ax; | ||
574 | sigset_t set; | ||
575 | |||
576 | regs = (struct pt_regs *) &__unused; | ||
577 | frame = (struct sigframe __user *)(regs->sp - 8); | ||
578 | |||
579 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | ||
580 | goto badframe; | ||
581 | if (__get_user(set.sig[0], &frame->sc.oldmask) || (_NSIG_WORDS > 1 | ||
582 | && __copy_from_user(&set.sig[1], &frame->extramask, | ||
583 | sizeof(frame->extramask)))) | ||
584 | goto badframe; | ||
585 | |||
586 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
587 | spin_lock_irq(¤t->sighand->siglock); | ||
588 | current->blocked = set; | ||
589 | recalc_sigpending(); | ||
590 | spin_unlock_irq(¤t->sighand->siglock); | ||
591 | |||
592 | if (restore_sigcontext(regs, &frame->sc, &ax)) | ||
593 | goto badframe; | ||
594 | return ax; | ||
595 | |||
596 | badframe: | ||
597 | if (show_unhandled_signals && printk_ratelimit()) { | ||
598 | printk("%s%s[%d] bad frame in sigreturn frame:" | ||
599 | "%p ip:%lx sp:%lx oeax:%lx", | ||
600 | task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG, | ||
601 | current->comm, task_pid_nr(current), frame, regs->ip, | ||
602 | regs->sp, regs->orig_ax); | ||
603 | print_vma_addr(" in ", regs->ip); | ||
604 | printk(KERN_CONT "\n"); | ||
605 | } | ||
606 | |||
607 | force_sig(SIGSEGV, current); | ||
608 | |||
609 | return 0; | ||
610 | } | ||
611 | #endif /* CONFIG_X86_32 */ | ||
612 | |||
499 | static long do_rt_sigreturn(struct pt_regs *regs) | 613 | static long do_rt_sigreturn(struct pt_regs *regs) |
500 | { | 614 | { |
501 | struct rt_sigframe __user *frame; | 615 | struct rt_sigframe __user *frame; |
@@ -542,7 +656,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) | |||
542 | #endif /* CONFIG_X86_32 */ | 656 | #endif /* CONFIG_X86_32 */ |
543 | 657 | ||
544 | /* | 658 | /* |
545 | * OK, we're invoking a handler | 659 | * OK, we're invoking a handler: |
546 | */ | 660 | */ |
547 | static int signr_convert(int sig) | 661 | static int signr_convert(int sig) |
548 | { | 662 | { |