Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[MIPS] signals: Share even more code.

native and compat do_signal and handle_signal are identical and can easily
be unified.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

+35 -164
-33
arch/mips/kernel/process.c
··· 26 26 #include <linux/completion.h> 27 27 #include <linux/kallsyms.h> 28 28 29 - #include <asm/abi.h> 30 29 #include <asm/bootinfo.h> 31 30 #include <asm/cpu.h> 32 31 #include <asm/dsp.h> ··· 64 65 preempt_disable(); 65 66 } 66 67 } 67 - 68 - /* 69 - * Native o32 and N64 ABI without DSP ASE 70 - */ 71 - struct mips_abi mips_abi = { 72 - .do_signal = do_signal, 73 - #ifdef CONFIG_TRAD_SIGNALS 74 - .setup_frame = setup_frame, 75 - #endif 76 - .setup_rt_frame = setup_rt_frame 77 - }; 78 - 79 - #ifdef CONFIG_MIPS32_O32 80 - /* 81 - * o32 compatibility on 64-bit kernels, without DSP ASE 82 - */ 83 - struct mips_abi mips_abi_32 = { 84 - .do_signal = do_signal32, 85 - .setup_frame = setup_frame_32, 86 - .setup_rt_frame = setup_rt_frame_32 87 - }; 88 - #endif /* CONFIG_MIPS32_O32 */ 89 - 90 - #ifdef CONFIG_MIPS32_N32 91 - /* 92 - * N32 on 64-bit kernels, without DSP ASE 93 - */ 94 - struct mips_abi mips_abi_n32 = { 95 - .do_signal = do_signal, 96 - .setup_rt_frame = setup_rt_frame_n32 97 - }; 98 - #endif /* CONFIG_MIPS32_N32 */ 99 68 100 69 asmlinkage void ret_from_fork(void); 101 70
+13 -5
arch/mips/kernel/signal.c
··· 398 398 } 399 399 400 400 #ifdef CONFIG_TRAD_SIGNALS 401 - int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, 401 + static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, 402 402 int signr, sigset_t *set) 403 403 { 404 404 struct sigframe __user *frame; ··· 443 443 } 444 444 #endif 445 445 446 - int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, 446 + static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, 447 447 int signr, sigset_t *set, siginfo_t *info) 448 448 { 449 449 struct rt_sigframe __user *frame; ··· 501 501 return -EFAULT; 502 502 } 503 503 504 + struct mips_abi mips_abi = { 505 + #ifdef CONFIG_TRAD_SIGNALS 506 + .setup_frame = setup_frame, 507 + #endif 508 + .setup_rt_frame = setup_rt_frame, 509 + .restart = __NR_restart_syscall 510 + }; 511 + 504 512 static int handle_signal(unsigned long sig, siginfo_t *info, 505 513 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) 506 514 { ··· 547 539 return ret; 548 540 } 549 541 550 - void do_signal(struct pt_regs *regs) 542 + static void do_signal(struct pt_regs *regs) 551 543 { 552 544 struct k_sigaction ka; 553 545 sigset_t *oldset; ··· 597 589 regs->cp0_epc -= 8; 598 590 } 599 591 if (regs->regs[2] == ERESTART_RESTARTBLOCK) { 600 - regs->regs[2] = __NR_restart_syscall; 592 + regs->regs[2] = current->thread.abi->restart; 601 593 regs->regs[7] = regs->regs[26]; 602 594 regs->cp0_epc -= 4; 603 595 } ··· 623 615 { 624 616 /* deal with pending signal delivery */ 625 617 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 626 - current->thread.abi->do_signal(regs); 618 + do_signal(regs); 627 619 }
+11 -107
arch/mips/kernel/signal32.c
··· 104 104 */ 105 105 #define __NR_O32_sigreturn 4119 106 106 #define __NR_O32_rt_sigreturn 4193 107 - #define __NR_O32_restart_syscall 4253 107 + #define __NR_O32_restart_syscall 4253 108 108 109 109 /* 32-bit compatibility types */ 110 110 ··· 598 598 force_sig(SIGSEGV, current); 599 599 } 600 600 601 - int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 601 + static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 602 602 int signr, sigset_t *set) 603 603 { 604 604 struct sigframe32 __user *frame; ··· 644 644 return -EFAULT; 645 645 } 646 646 647 - int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 647 + static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 648 648 int signr, sigset_t *set, siginfo_t *info) 649 649 { 650 650 struct rt_sigframe32 __user *frame; ··· 704 704 return -EFAULT; 705 705 } 706 706 707 - static inline int handle_signal(unsigned long sig, siginfo_t *info, 708 - struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs) 709 - { 710 - int ret; 711 - 712 - switch (regs->regs[0]) { 713 - case ERESTART_RESTARTBLOCK: 714 - case ERESTARTNOHAND: 715 - regs->regs[2] = EINTR; 716 - break; 717 - case ERESTARTSYS: 718 - if (!(ka->sa.sa_flags & SA_RESTART)) { 719 - regs->regs[2] = EINTR; 720 - break; 721 - } 722 - /* fallthrough */ 723 - case ERESTARTNOINTR: /* Userland will reload $v0. */ 724 - regs->regs[7] = regs->regs[26]; 725 - regs->cp0_epc -= 8; 726 - } 727 - 728 - regs->regs[0] = 0; /* Don't deal with this again. */ 729 - 730 - if (ka->sa.sa_flags & SA_SIGINFO) 731 - ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info); 732 - else 733 - ret = current->thread.abi->setup_frame(ka, regs, sig, oldset); 734 - 735 - spin_lock_irq(&current->sighand->siglock); 736 - sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 737 - if (!(ka->sa.sa_flags & SA_NODEFER)) 738 - sigaddset(&current->blocked,sig); 739 - recalc_sigpending(); 740 - spin_unlock_irq(&current->sighand->siglock); 741 - 742 - return ret; 743 - } 744 - 745 - void do_signal32(struct pt_regs *regs) 746 - { 747 - struct k_sigaction ka; 748 - sigset_t *oldset; 749 - siginfo_t info; 750 - int signr; 751 - 752 - /* 753 - * We want the common case to go fast, which is why we may in certain 754 - * cases get here from kernel mode. Just return without doing anything 755 - * if so. 756 - */ 757 - if (!user_mode(regs)) 758 - return; 759 - 760 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) 761 - oldset = &current->saved_sigmask; 762 - else 763 - oldset = &current->blocked; 764 - 765 - signr = get_signal_to_deliver(&info, &ka, regs, NULL); 766 - if (signr > 0) { 767 - /* Whee! Actually deliver the signal. */ 768 - if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { 769 - /* 770 - * A signal was successfully delivered; the saved 771 - * sigmask will have been stored in the signal frame, 772 - * and will be restored by sigreturn, so we can simply 773 - * clear the TIF_RESTORE_SIGMASK flag. 774 - */ 775 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) 776 - clear_thread_flag(TIF_RESTORE_SIGMASK); 777 - } 778 - 779 - return; 780 - } 781 - 782 - /* 783 - * Who's code doesn't conform to the restartable syscall convention 784 - * dies here!!! The li instruction, a single machine instruction, 785 - * must directly be followed by the syscall instruction. 786 - */ 787 - if (regs->regs[0]) { 788 - if (regs->regs[2] == ERESTARTNOHAND || 789 - regs->regs[2] == ERESTARTSYS || 790 - regs->regs[2] == ERESTARTNOINTR) { 791 - regs->regs[7] = regs->regs[26]; 792 - regs->cp0_epc -= 8; 793 - } 794 - if (regs->regs[2] == ERESTART_RESTARTBLOCK) { 795 - regs->regs[2] = __NR_O32_restart_syscall; 796 - regs->regs[7] = regs->regs[26]; 797 - regs->cp0_epc -= 4; 798 - } 799 - regs->regs[0] = 0; /* Don't deal with this again. */ 800 - } 801 - 802 - /* 803 - * If there's no signal to deliver, we just put the saved sigmask 804 - * back 805 - */ 806 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 807 - clear_thread_flag(TIF_RESTORE_SIGMASK); 808 - sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 809 - } 810 - } 707 + /* 708 + * o32 compatibility on 64-bit kernels, without DSP ASE 709 + */ 710 + struct mips_abi mips_abi_32 = { 711 + .setup_frame = setup_frame_32, 712 + .setup_rt_frame = setup_rt_frame_32, 713 + .restart = __NR_O32_restart_syscall 714 + }; 811 715 812 716 asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, 813 717 struct sigaction32 __user *oact,
+7 -1
arch/mips/kernel/signal_n32.c
··· 29 29 #include <linux/compat.h> 30 30 #include <linux/bitops.h> 31 31 32 + #include <asm/abi.h> 32 33 #include <asm/asm.h> 33 34 #include <asm/cacheflush.h> 34 35 #include <asm/compat-signal.h> ··· 170 169 force_sig(SIGSEGV, current); 171 170 } 172 171 173 - int setup_rt_frame_n32(struct k_sigaction * ka, 172 + static int setup_rt_frame_n32(struct k_sigaction * ka, 174 173 struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) 175 174 { 176 175 struct rt_sigframe_n32 __user *frame; ··· 229 228 force_sigsegv(signr, current); 230 229 return -EFAULT; 231 230 } 231 + 232 + struct mips_abi mips_abi_n32 = { 233 + .setup_rt_frame = setup_rt_frame_n32, 234 + .restart = __NR_N32_restart_syscall 235 + };
+1 -1
include/asm-mips/abi.h
··· 13 13 #include <asm/siginfo.h> 14 14 15 15 struct mips_abi { 16 - void (* const do_signal)(struct pt_regs *regs); 17 16 int (* const setup_frame)(struct k_sigaction * ka, 18 17 struct pt_regs *regs, int signr, 19 18 sigset_t *set); 20 19 int (* const setup_rt_frame)(struct k_sigaction * ka, 21 20 struct pt_regs *regs, int signr, 22 21 sigset_t *set, siginfo_t *info); 22 + const unsigned long restart; 23 23 }; 24 24 25 25 #endif /* _ASM_ABI_H */
+3
include/asm-mips/compat-signal.h
··· 5 5 #include <linux/compat.h> 6 6 #include <linux/compiler.h> 7 7 8 + #include <asm/signal.h> 9 + #include <asm/siginfo.h> 10 + 8 11 #include <asm/uaccess.h> 9 12 10 13 static inline int __copy_conv_sigset_to_user(compat_sigset_t __user *d,
-17
include/asm-mips/signal.h
··· 137 137 138 138 #define ptrace_signal_deliver(regs, cookie) do { } while (0) 139 139 140 - struct pt_regs; 141 - extern void do_signal(struct pt_regs *regs); 142 - extern void do_signal32(struct pt_regs *regs); 143 - 144 - extern int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, 145 - int signr, sigset_t *set); 146 - extern int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, 147 - int signr, sigset_t *set, siginfo_t *info); 148 - 149 - extern int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 150 - int signr, sigset_t *set); 151 - extern int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 152 - int signr, sigset_t *set, siginfo_t *info); 153 - 154 - extern int setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs, 155 - int signr, sigset_t *set, siginfo_t *info); 156 - 157 140 #endif /* __KERNEL__ */ 158 141 159 142 #endif /* _ASM_SIGNAL_H */