aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/kernel
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2010-09-29 23:28:59 -0400
committerGeert Uytterhoeven <geert@linux-m68k.org>2011-01-07 08:01:33 -0500
commite68847fee706c6fe74c9afc3288c3adfc131b1fa (patch)
tree5012dca75c9977a55274484512846cb924afe195 /arch/m68k/kernel
parent35fc157baf56db846afaeb5c730fa47e351cf0d2 (diff)
m68k: Switch to saner sigsuspend()
and saner do_signal() arguments, while we are at it Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Diffstat (limited to 'arch/m68k/kernel')
-rw-r--r--arch/m68k/kernel/entry.S19
-rw-r--r--arch/m68k/kernel/signal.c64
2 files changed, 22 insertions, 61 deletions
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 6360c437dcf5..3a15a03297a7 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -174,9 +174,8 @@ do_signal_return:
174 subql #4,%sp | dummy return address 174 subql #4,%sp | dummy return address
175 SAVE_SWITCH_STACK 175 SAVE_SWITCH_STACK
176 pea %sp@(SWITCH_STACK_SIZE) 176 pea %sp@(SWITCH_STACK_SIZE)
177 clrl %sp@-
178 bsrl do_signal 177 bsrl do_signal
179 addql #8,%sp 178 addql #4,%sp
180 RESTORE_SWITCH_STACK 179 RESTORE_SWITCH_STACK
181 addql #4,%sp 180 addql #4,%sp
182 tstl %d0 181 tstl %d0
@@ -290,22 +289,6 @@ ENTRY(sys_vfork)
290 RESTORE_SWITCH_STACK 289 RESTORE_SWITCH_STACK
291 rts 290 rts
292 291
293ENTRY(sys_sigsuspend)
294 SAVE_SWITCH_STACK
295 pea %sp@(SWITCH_STACK_SIZE)
296 jbsr do_sigsuspend
297 addql #4,%sp
298 RESTORE_SWITCH_STACK
299 rts
300
301ENTRY(sys_rt_sigsuspend)
302 SAVE_SWITCH_STACK
303 pea %sp@(SWITCH_STACK_SIZE)
304 jbsr do_rt_sigsuspend
305 addql #4,%sp
306 RESTORE_SWITCH_STACK
307 rts
308
309ENTRY(sys_sigreturn) 292ENTRY(sys_sigreturn)
310 SAVE_SWITCH_STACK 293 SAVE_SWITCH_STACK
311 jbsr do_sigreturn 294 jbsr do_sigreturn
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index c776c813d856..fa8200d03de2 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -51,8 +51,6 @@
51 51
52#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 52#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
53 53
54asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
55
56const int frame_extra_sizes[16] = { 54const int frame_extra_sizes[16] = {
57 [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ 55 [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */
58 [2] = sizeof(((struct frame *)0)->un.fmt2), 56 [2] = sizeof(((struct frame *)0)->un.fmt2),
@@ -74,51 +72,21 @@ const int frame_extra_sizes[16] = {
74/* 72/*
75 * Atomically swap in the new signal mask, and wait for a signal. 73 * Atomically swap in the new signal mask, and wait for a signal.
76 */ 74 */
77asmlinkage int do_sigsuspend(struct pt_regs *regs) 75asmlinkage int
76sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)
78{ 77{
79 old_sigset_t mask = regs->d3;
80 sigset_t saveset;
81
82 mask &= _BLOCKABLE; 78 mask &= _BLOCKABLE;
83 saveset = current->blocked; 79 spin_lock_irq(&current->sighand->siglock);
80 current->saved_sigmask = current->blocked;
84 siginitset(&current->blocked, mask); 81 siginitset(&current->blocked, mask);
85 recalc_sigpending(); 82 recalc_sigpending();
83 spin_unlock_irq(&current->sighand->siglock);
86 84
87 regs->d0 = -EINTR; 85 current->state = TASK_INTERRUPTIBLE;
88 while (1) { 86 schedule();
89 current->state = TASK_INTERRUPTIBLE; 87 set_restore_sigmask();
90 schedule();
91 if (do_signal(&saveset, regs))
92 return -EINTR;
93 }
94}
95
96asmlinkage int
97do_rt_sigsuspend(struct pt_regs *regs)
98{
99 sigset_t __user *unewset = (sigset_t __user *)regs->d1;
100 size_t sigsetsize = (size_t)regs->d2;
101 sigset_t saveset, newset;
102
103 /* XXX: Don't preclude handling different sized sigset_t's. */
104 if (sigsetsize != sizeof(sigset_t))
105 return -EINVAL;
106
107 if (copy_from_user(&newset, unewset, sizeof(newset)))
108 return -EFAULT;
109 sigdelsetmask(&newset, ~_BLOCKABLE);
110
111 saveset = current->blocked;
112 current->blocked = newset;
113 recalc_sigpending();
114 88
115 regs->d0 = -EINTR; 89 return -ERESTARTNOHAND;
116 while (1) {
117 current->state = TASK_INTERRUPTIBLE;
118 schedule();
119 if (do_signal(&saveset, regs))
120 return -EINTR;
121 }
122} 90}
123 91
124asmlinkage int 92asmlinkage int
@@ -1017,21 +985,25 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
1017 * want to handle. Thus you cannot kill init even with a SIGKILL even by 985 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1018 * mistake. 986 * mistake.
1019 */ 987 */
1020asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) 988asmlinkage int do_signal(struct pt_regs *regs)
1021{ 989{
1022 siginfo_t info; 990 siginfo_t info;
1023 struct k_sigaction ka; 991 struct k_sigaction ka;
1024 int signr; 992 int signr;
993 sigset_t *oldset;
1025 994
1026 current->thread.esp0 = (unsigned long) regs; 995 current->thread.esp0 = (unsigned long) regs;
1027 996
1028 if (!oldset) 997 if (test_thread_flag(TIF_RESTORE_SIGMASK))
998 oldset = &current->saved_sigmask;
999 else
1029 oldset = &current->blocked; 1000 oldset = &current->blocked;
1030 1001
1031 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 1002 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
1032 if (signr > 0) { 1003 if (signr > 0) {
1033 /* Whee! Actually deliver the signal. */ 1004 /* Whee! Actually deliver the signal. */
1034 handle_signal(signr, &ka, &info, oldset, regs); 1005 handle_signal(signr, &ka, &info, oldset, regs);
1006 clear_thread_flag(TIF_RESTORE_SIGMASK);
1035 return 1; 1007 return 1;
1036 } 1008 }
1037 1009
@@ -1040,5 +1012,11 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
1040 /* Restart the system call - no handlers present */ 1012 /* Restart the system call - no handlers present */
1041 handle_restart(regs, NULL, 0); 1013 handle_restart(regs, NULL, 0);
1042 1014
1015 /* If there's no signal to deliver, we just restore the saved mask. */
1016 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
1017 clear_thread_flag(TIF_RESTORE_SIGMASK);
1018 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
1019 }
1020
1043 return 0; 1021 return 0;
1044} 1022}