[buildroot] disable sstrip when using musl
[openwrt/svn-archive/archive.git] / target / linux / ubicom32 / files / arch / ubicom32 / kernel / signal.c
1 /*
2 * arch/ubicom32/kernel/signal.c
3 * Ubicom32 architecture signal handling implementation.
4 *
5 * (C) Copyright 2009, Ubicom, Inc.
6 * Copyright (C) 1991, 1992 Linus Torvalds
7 * Linux/m68k support by Hamish Macdonald
8 * 68060 fixes by Jesper Skov
9 * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab
10 * mathemu support by Roman Zippel
11 * ++roman (07/09/96): implemented signal stacks
12 *
13 * This file is part of the Ubicom32 Linux Kernel Port.
14 *
15 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
16 * it and/or modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation, either version 2 of the
18 * License, or (at your option) any later version.
19 *
20 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
21 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
22 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
23 * the GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with the Ubicom32 Linux Kernel Port. If not,
27 * see <http://www.gnu.org/licenses/>.
28 *
29 * Ubicom32 implementation derived from (with many thanks):
30 * arch/m68knommu
31 * arch/blackfin
32 * arch/parisc
33 *
34 * mathemu support by Roman Zippel
35 * (Note: fpstate in the signal context is completely ignored for the emulator
36 * and the internal floating point format is put on stack)
37 *
38 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
39 * Atari :-) Current limitation: Only one sigstack can be active at one time.
40 * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
41 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
42 * signal handlers!
43 */
44
45 #include <linux/module.h>
46 #include <linux/sched.h>
47 #include <linux/mm.h>
48 #include <linux/kernel.h>
49 #include <linux/signal.h>
50 #include <linux/syscalls.h>
51 #include <linux/errno.h>
52 #include <linux/wait.h>
53 #include <linux/ptrace.h>
54 #include <linux/unistd.h>
55 #include <linux/stddef.h>
56 #include <linux/highuid.h>
57 #include <linux/tty.h>
58 #include <linux/personality.h>
59 #include <linux/binfmts.h>
60
61 #include <asm/setup.h>
62 #include <asm/uaccess.h>
63 #include <asm/pgtable.h>
64 #include <asm/traps.h>
65 #include <asm/ucontext.h>
66
67 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
68
69 /*
70 * asm signal return handlers.
71 */
72 void ret_from_user_signal(void);
73 void ret_from_user_rt_signal(void);
74 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
75
76 /*
77 * Common signal suspend implementation
78 */
79 static int signal_suspend(sigset_t *saveset, struct pt_regs *regs)
80 {
81 regs->dn[0] = -EINTR;
82 while (1) {
83 current->state = TASK_INTERRUPTIBLE;
84 schedule();
85 if (!do_signal(saveset, regs)) {
86 continue;
87 }
88 /*
89 * If the current frame type is a signal trampoline we are
90 * actually going to call the signal handler so we return the
91 * desired d0 as the return value.
92 */
93 if (regs->frame_type == UBICOM32_FRAME_TYPE_SIGTRAMP) {
94 return regs->dn[0];
95 }
96 return -EINTR;
97 }
98 /*
99 * Should never get here
100 */
101 BUG();
102 return 0;
103 }
104
105 /*
106 * Atomically swap in the new signal mask, and wait for a signal.
107 */
108 asmlinkage int do_sigsuspend(struct pt_regs *regs)
109 {
110 old_sigset_t mask = regs->dn[0];
111 sigset_t saveset;
112
113 mask &= _BLOCKABLE;
114 spin_lock_irq(&current->sighand->siglock);
115 saveset = current->blocked;
116 siginitset(&current->blocked, mask);
117 recalc_sigpending();
118 spin_unlock_irq(&current->sighand->siglock);
119
120 /*
121 * Call common handler
122 */
123 return signal_suspend(&saveset, regs);
124 }
125
126 asmlinkage int
127 do_rt_sigsuspend(struct pt_regs *regs)
128 {
129 sigset_t *unewset = (sigset_t *)regs->dn[0];
130 size_t sigsetsize = (size_t)regs->dn[1];
131 sigset_t saveset, newset;
132
133 /* XXX: Don't preclude handling different sized sigset_t's. */
134 if (sigsetsize != sizeof(sigset_t))
135 return -EINVAL;
136
137 if (copy_from_user(&newset, unewset, sizeof(newset)))
138 return -EFAULT;
139 sigdelsetmask(&newset, ~_BLOCKABLE);
140
141 spin_lock_irq(&current->sighand->siglock);
142 saveset = current->blocked;
143 current->blocked = newset;
144 recalc_sigpending();
145 spin_unlock_irq(&current->sighand->siglock);
146
147 /*
148 * Call common handler
149 */
150 return signal_suspend(&saveset, regs);
151 }
152
153 asmlinkage int
154 sys_sigaction(int sig, const struct old_sigaction *act,
155 struct old_sigaction *oact)
156 {
157 struct k_sigaction new_ka, old_ka;
158 int ret;
159
160 if (act) {
161 old_sigset_t mask;
162 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
163 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
164 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
165 return -EFAULT;
166 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
167 __get_user(mask, &act->sa_mask);
168 siginitset(&new_ka.sa.sa_mask, mask);
169 }
170
171 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
172
173 if (!ret && oact) {
174 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
175 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
176 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
177 return -EFAULT;
178 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
179 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
180 }
181
182 return ret;
183 }
184
185 asmlinkage int
186 do_sys_sigaltstack(struct pt_regs *regs)
187 {
188 const stack_t *uss = (stack_t *) regs->dn[0];
189 stack_t *uoss = (stack_t *)regs->dn[1];
190 return do_sigaltstack(uss, uoss, regs->an[7]);
191 }
192
193 /*
194 * fdpic_func_descriptor describes sa_handler when the application is FDPIC
195 */
196 struct fdpic_func_descriptor {
197 unsigned long text;
198 unsigned long GOT;
199 };
200
201 /*
202 * rt_sigframe is stored on the user stack immediately before (above)
203 * the signal handlers stack.
204 */
205 struct rt_sigframe
206 {
207 unsigned long syscall_number; /* This holds __NR_rt_sigreturn. */
208 unsigned long restore_all_regs; /* This field gets set to 1 if the frame
209 * type is TRAP or INTERRUPT. */
210 siginfo_t *info;
211 struct ucontext uc;
212 int sig;
213 void *pretcode;
214 };
215
216 /*
217 * Do a signal return; undo the signal stack.
218 */
219 asmlinkage int do_sigreturn(unsigned long __unused)
220 {
221 BUG();
222 return 0;
223 }
224
225 asmlinkage int do_rt_sigreturn(struct pt_regs *regs)
226 {
227 unsigned long usp = regs->an[7];
228 struct rt_sigframe *frame = (struct rt_sigframe *)(usp);
229 sigset_t set;
230
231 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
232 goto badframe;
233 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
234 goto badframe;
235
236 sigdelsetmask(&set, ~_BLOCKABLE);
237 spin_lock_irq(&current->sighand->siglock);
238 current->blocked = set;
239 recalc_sigpending();
240 spin_unlock_irq(&current->sighand->siglock);
241
242 if (copy_from_user(regs, &frame->uc.uc_mcontext, sizeof(struct pt_regs)))
243 goto badframe;
244 return regs->dn[0];
245
246 badframe:
247 force_sig(SIGSEGV, current);
248 return 0;
249 }
250
251 static inline void *
252 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
253 {
254 unsigned long usp;
255
256 /* Default to using normal stack. */
257 usp = regs->an[7];
258
259 /* This is the X/Open sanctioned signal stack switching. */
260 if (ka->sa.sa_flags & SA_ONSTACK) {
261 if (!sas_ss_flags(usp))
262 usp = current->sas_ss_sp + current->sas_ss_size;
263 }
264 return (void *)((usp - frame_size) & ~0x3);
265 }
266
267 /*
268 * signal_trampoline: Defined in ubicom32_syscall.S
269 */
270 asmlinkage void signal_trampoline(void)__attribute__((naked));
271
272 static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
273 sigset_t *set, struct pt_regs *regs)
274 {
275 struct rt_sigframe *frame;
276 int err = 0;
277
278 frame = (struct rt_sigframe *) get_sigframe(ka, regs, sizeof(*frame));
279
280 /*
281 * The 'err |=' have been may criticized as bad code style, but I
282 * strongly suspect that we want this code to be fast. So for
283 * now it stays as is.
284 */
285 err |= __put_user( ( (current_thread_info()->exec_domain)
286 && (current_thread_info()->exec_domain->signal_invmap)
287 && (sig < 32) )
288 ? current_thread_info()->exec_domain->signal_invmap[sig]
289 : sig, &frame->sig);
290 err |= __put_user(info, &frame->info);
291
292 /* Create the ucontext. */
293 err |= __put_user(0, &frame->uc.uc_flags);
294 err |= __put_user(0, &frame->uc.uc_link);
295 err |= __put_user((void *)current->sas_ss_sp,
296 &frame->uc.uc_stack.ss_sp);
297 err |= __put_user(sas_ss_flags(regs->an[7]),
298 &frame->uc.uc_stack.ss_flags);
299 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
300 err |= __put_user(__NR_rt_sigreturn, &frame->syscall_number);
301 if ((regs->frame_type == UBICOM32_FRAME_TYPE_TRAP) ||
302 (regs->frame_type == UBICOM32_FRAME_TYPE_INTERRUPT)) {
303 err |= __put_user(1, &frame->restore_all_regs);
304 } else {
305 err |= __put_user(0, &frame->restore_all_regs);
306 }
307 err |= copy_to_user (&frame->uc.uc_mcontext.sc_regs, regs, sizeof(struct pt_regs));
308 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
309
310 if (err)
311 goto give_sigsegv;
312
313 /*
314 * Set up registers for signal handler NOTE: Do not modify dn[14], it
315 * contains the userspace tls pointer, so it important that it carries
316 * over to the signal handler.
317 */
318 regs->an[7] = (unsigned long)frame;
319 regs->pc = (unsigned long) signal_trampoline;
320 regs->an[5] = (unsigned long) signal_trampoline;
321 regs->dn[0] = sig;
322 regs->dn[1] = (unsigned long) frame->info;
323 regs->dn[2] = (unsigned int) &frame->uc;
324
325 /*
326 * If this is FDPIC then the signal handler is actually a function
327 * descriptor.
328 */
329 if (current->personality & FDPIC_FUNCPTRS) {
330 struct fdpic_func_descriptor __user *funcptr =
331 (struct fdpic_func_descriptor *) ka->sa.sa_handler;
332 err |= __get_user(regs->dn[3], &funcptr->text);
333 err |= __get_user(regs->an[0], &funcptr->GOT);
334 if (err)
335 goto give_sigsegv;
336
337 /*
338 * The funcdesc must be in a3 as this is required for the lazy
339 * resolver in ld.so, if the application is not FDPIC a3 is not
340 * used.
341 */
342 regs->an[3] = (unsigned long) funcptr;
343
344 } else {
345 regs->dn[3] = (unsigned long)ka->sa.sa_handler;
346 regs->an[0] = 0;
347 }
348
349 regs->frame_type = UBICOM32_FRAME_TYPE_SIGTRAMP;
350
351 return;
352
353 give_sigsegv:
354 /* user space exception */
355 force_sigsegv(sig, current);
356 }
357
358 static inline void
359 handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
360 {
361 switch (regs->dn[0]) {
362 case -ERESTARTNOHAND:
363 if (!has_handler)
364 goto do_restart;
365 regs->dn[0] = -EINTR;
366 break;
367
368 case -ERESTARTSYS:
369 if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
370 regs->dn[0] = -EINTR;
371 break;
372 }
373 /* fallthrough */
374 case -ERESTARTNOINTR:
375 do_restart:
376 regs->dn[0] = regs->original_dn_0;
377 regs->pc -= 8;
378 regs->an[5] -= 8;
379 break;
380 }
381 }
382
383 /*
384 * OK, we're invoking a handler
385 */
386 static void
387 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
388 sigset_t *oldset, struct pt_regs *regs)
389 {
390 /* are we from a system call? */
391 if (regs->frame_type == -1)
392 /* If so, check system call restarting.. */
393 handle_restart(regs, ka, 1);
394
395 /* set up the stack frame */
396 setup_rt_frame(sig, ka, info, oldset, regs);
397
398 if (ka->sa.sa_flags & SA_ONESHOT)
399 ka->sa.sa_handler = SIG_DFL;
400
401 spin_lock_irq(&current->sighand->siglock);
402 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
403 if (!(ka->sa.sa_flags & SA_NODEFER))
404 sigaddset(&current->blocked,sig);
405 recalc_sigpending();
406 spin_unlock_irq(&current->sighand->siglock);
407 }
408
409 /*
410 * Note that 'init' is a special process: it doesn't get signals it doesn't
411 * want to handle. Thus you cannot kill init even with a SIGKILL even by
412 * mistake.
413 */
414 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
415 {
416 struct k_sigaction ka;
417 siginfo_t info;
418 int signr;
419
420 /*
421 * We want the common case to go fast, which
422 * is why we may in certain cases get here from
423 * kernel mode. Just return without doing anything
424 * if so.
425 */
426 if (!user_mode(regs))
427 return 1;
428
429 if (!oldset)
430 oldset = &current->blocked;
431
432 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
433 if (signr > 0) {
434 /* Whee! Actually deliver the signal. */
435 handle_signal(signr, &ka, &info, oldset, regs);
436 return 1;
437 }
438
439 /* Did we come from a system call? */
440 if (regs->frame_type == -1) {
441 /* Restart the system call - no handlers present */
442 handle_restart(regs, NULL, 0);
443 }
444
445 return 0;
446 }
447
448 /*
449 * sys_sigreturn()
450 * Return handler for signal clean-up.
451 *
452 * NOTE: Ubicom32 does not use this syscall. Instead we rely
453 * on do_rt_sigreturn().
454 */
455 asmlinkage long sys_sigreturn(void)
456 {
457 return -ENOSYS;
458 }