]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/mips/kernel/signal32.c
Merge remote-tracking branch 'metag/for-next'
[karo-tx-linux.git] / arch / mips / kernel / signal32.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 1991, 1992  Linus Torvalds
7  * Copyright (C) 1994 - 2000, 2006  Ralf Baechle
8  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9  */
10 #include <linux/cache.h>
11 #include <linux/compat.h>
12 #include <linux/sched.h>
13 #include <linux/mm.h>
14 #include <linux/smp.h>
15 #include <linux/kernel.h>
16 #include <linux/signal.h>
17 #include <linux/syscalls.h>
18 #include <linux/errno.h>
19 #include <linux/wait.h>
20 #include <linux/ptrace.h>
21 #include <linux/suspend.h>
22 #include <linux/compiler.h>
23 #include <linux/uaccess.h>
24
25 #include <asm/abi.h>
26 #include <asm/asm.h>
27 #include <asm/compat-signal.h>
28 #include <linux/bitops.h>
29 #include <asm/cacheflush.h>
30 #include <asm/sim.h>
31 #include <asm/ucontext.h>
32 #include <asm/fpu.h>
33 #include <asm/war.h>
34 #include <asm/vdso.h>
35 #include <asm/dsp.h>
36
37 #include "signal-common.h"
38
39 /*
40  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
41  */
42 #define __NR_O32_restart_syscall        4253
43
44 /* 32-bit compatibility types */
45
46 typedef unsigned int __sighandler32_t;
47 typedef void (*vfptr_t)(void);
48
49 struct ucontext32 {
50         u32                 uc_flags;
51         s32                 uc_link;
52         compat_stack_t      uc_stack;
53         struct sigcontext32 uc_mcontext;
54         compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
55 };
56
57 struct sigframe32 {
58         u32 sf_ass[4];          /* argument save space for o32 */
59         u32 sf_pad[2];          /* Was: signal trampoline */
60         struct sigcontext32 sf_sc;
61         compat_sigset_t sf_mask;
62 };
63
64 struct rt_sigframe32 {
65         u32 rs_ass[4];                  /* argument save space for o32 */
66         u32 rs_pad[2];                  /* Was: signal trampoline */
67         compat_siginfo_t rs_info;
68         struct ucontext32 rs_uc;
69 };
70
71 static int setup_sigcontext32(struct pt_regs *regs,
72                               struct sigcontext32 __user *sc)
73 {
74         int err = 0;
75         int i;
76
77         err |= __put_user(regs->cp0_epc, &sc->sc_pc);
78
79         err |= __put_user(0, &sc->sc_regs[0]);
80         for (i = 1; i < 32; i++)
81                 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
82
83         err |= __put_user(regs->hi, &sc->sc_mdhi);
84         err |= __put_user(regs->lo, &sc->sc_mdlo);
85         if (cpu_has_dsp) {
86                 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
87                 err |= __put_user(mfhi1(), &sc->sc_hi1);
88                 err |= __put_user(mflo1(), &sc->sc_lo1);
89                 err |= __put_user(mfhi2(), &sc->sc_hi2);
90                 err |= __put_user(mflo2(), &sc->sc_lo2);
91                 err |= __put_user(mfhi3(), &sc->sc_hi3);
92                 err |= __put_user(mflo3(), &sc->sc_lo3);
93         }
94
95         /*
96          * Save FPU state to signal context.  Signal handler
97          * will "inherit" current FPU state.
98          */
99         err |= protected_save_fp_context(sc);
100
101         return err;
102 }
103
104 static int restore_sigcontext32(struct pt_regs *regs,
105                                 struct sigcontext32 __user *sc)
106 {
107         int err = 0;
108         s32 treg;
109         int i;
110
111         /* Always make any pending restarted system calls return -EINTR */
112         current->restart_block.fn = do_no_restart_syscall;
113
114         err |= __get_user(regs->cp0_epc, &sc->sc_pc);
115         err |= __get_user(regs->hi, &sc->sc_mdhi);
116         err |= __get_user(regs->lo, &sc->sc_mdlo);
117         if (cpu_has_dsp) {
118                 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
119                 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
120                 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
121                 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
122                 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
123                 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
124                 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
125         }
126
127         for (i = 1; i < 32; i++)
128                 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
129
130         return err ?: protected_restore_fp_context(sc);
131 }
132
133 /*
134  * Atomically swap in the new signal mask, and wait for a signal.
135  */
136
137 asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
138 {
139         return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
140 }
141
142 SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
143         struct compat_sigaction __user *, oact)
144 {
145         struct k_sigaction new_ka, old_ka;
146         int ret;
147         int err = 0;
148
149         if (act) {
150                 old_sigset_t mask;
151                 s32 handler;
152
153                 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
154                         return -EFAULT;
155                 err |= __get_user(handler, &act->sa_handler);
156                 new_ka.sa.sa_handler = (void __user *)(s64)handler;
157                 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
158                 err |= __get_user(mask, &act->sa_mask.sig[0]);
159                 if (err)
160                         return -EFAULT;
161
162                 siginitset(&new_ka.sa.sa_mask, mask);
163         }
164
165         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
166
167         if (!ret && oact) {
168                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
169                         return -EFAULT;
170                 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
171                 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
172                                   &oact->sa_handler);
173                 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
174                 err |= __put_user(0, &oact->sa_mask.sig[1]);
175                 err |= __put_user(0, &oact->sa_mask.sig[2]);
176                 err |= __put_user(0, &oact->sa_mask.sig[3]);
177                 if (err)
178                         return -EFAULT;
179         }
180
181         return ret;
182 }
183
184 int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
185 {
186         int err;
187
188         if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
189                 return -EFAULT;
190
191         /* If you change siginfo_t structure, please be sure
192            this code is fixed accordingly.
193            It should never copy any pad contained in the structure
194            to avoid security leaks, but must copy the generic
195            3 ints plus the relevant union member.
196            This routine must convert siginfo from 64bit to 32bit as well
197            at the same time.  */
198         err = __put_user(from->si_signo, &to->si_signo);
199         err |= __put_user(from->si_errno, &to->si_errno);
200         err |= __put_user((short)from->si_code, &to->si_code);
201         if (from->si_code < 0)
202                 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
203         else {
204                 switch (from->si_code >> 16) {
205                 case __SI_TIMER >> 16:
206                         err |= __put_user(from->si_tid, &to->si_tid);
207                         err |= __put_user(from->si_overrun, &to->si_overrun);
208                         err |= __put_user(from->si_int, &to->si_int);
209                         break;
210                 case __SI_CHLD >> 16:
211                         err |= __put_user(from->si_utime, &to->si_utime);
212                         err |= __put_user(from->si_stime, &to->si_stime);
213                         err |= __put_user(from->si_status, &to->si_status);
214                 default:
215                         err |= __put_user(from->si_pid, &to->si_pid);
216                         err |= __put_user(from->si_uid, &to->si_uid);
217                         break;
218                 case __SI_FAULT >> 16:
219                         err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
220                         break;
221                 case __SI_POLL >> 16:
222                         err |= __put_user(from->si_band, &to->si_band);
223                         err |= __put_user(from->si_fd, &to->si_fd);
224                         break;
225                 case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
226                 case __SI_MESGQ >> 16:
227                         err |= __put_user(from->si_pid, &to->si_pid);
228                         err |= __put_user(from->si_uid, &to->si_uid);
229                         err |= __put_user(from->si_int, &to->si_int);
230                         break;
231                 }
232         }
233         return err;
234 }
235
236 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
237 {
238         if (copy_from_user(to, from, 3*sizeof(int)) ||
239             copy_from_user(to->_sifields._pad,
240                            from->_sifields._pad, SI_PAD_SIZE32))
241                 return -EFAULT;
242
243         return 0;
244 }
245
246 asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
247 {
248         struct sigframe32 __user *frame;
249         sigset_t blocked;
250         int sig;
251
252         frame = (struct sigframe32 __user *) regs.regs[29];
253         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
254                 goto badframe;
255         if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
256                 goto badframe;
257
258         set_current_blocked(&blocked);
259
260         sig = restore_sigcontext32(&regs, &frame->sf_sc);
261         if (sig < 0)
262                 goto badframe;
263         else if (sig)
264                 force_sig(sig, current);
265
266         /*
267          * Don't let your children do this ...
268          */
269         __asm__ __volatile__(
270                 "move\t$29, %0\n\t"
271                 "j\tsyscall_exit"
272                 :/* no outputs */
273                 :"r" (&regs));
274         /* Unreached */
275
276 badframe:
277         force_sig(SIGSEGV, current);
278 }
279
280 asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
281 {
282         struct rt_sigframe32 __user *frame;
283         sigset_t set;
284         int sig;
285
286         frame = (struct rt_sigframe32 __user *) regs.regs[29];
287         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
288                 goto badframe;
289         if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
290                 goto badframe;
291
292         set_current_blocked(&set);
293
294         sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
295         if (sig < 0)
296                 goto badframe;
297         else if (sig)
298                 force_sig(sig, current);
299
300         if (compat_restore_altstack(&frame->rs_uc.uc_stack))
301                 goto badframe;
302
303         /*
304          * Don't let your children do this ...
305          */
306         __asm__ __volatile__(
307                 "move\t$29, %0\n\t"
308                 "j\tsyscall_exit"
309                 :/* no outputs */
310                 :"r" (&regs));
311         /* Unreached */
312
313 badframe:
314         force_sig(SIGSEGV, current);
315 }
316
317 static int setup_frame_32(void *sig_return, struct ksignal *ksig,
318                           struct pt_regs *regs, sigset_t *set)
319 {
320         struct sigframe32 __user *frame;
321         int err = 0;
322
323         frame = get_sigframe(ksig, regs, sizeof(*frame));
324         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
325                 return -EFAULT;
326
327         err |= setup_sigcontext32(regs, &frame->sf_sc);
328         err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
329
330         if (err)
331                 return -EFAULT;
332
333         /*
334          * Arguments to signal handler:
335          *
336          *   a0 = signal number
337          *   a1 = 0 (should be cause)
338          *   a2 = pointer to struct sigcontext
339          *
340          * $25 and c0_epc point to the signal handler, $29 points to the
341          * struct sigframe.
342          */
343         regs->regs[ 4] = ksig->sig;
344         regs->regs[ 5] = 0;
345         regs->regs[ 6] = (unsigned long) &frame->sf_sc;
346         regs->regs[29] = (unsigned long) frame;
347         regs->regs[31] = (unsigned long) sig_return;
348         regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
349
350         DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
351                current->comm, current->pid,
352                frame, regs->cp0_epc, regs->regs[31]);
353
354         return 0;
355 }
356
357 static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig,
358                              struct pt_regs *regs, sigset_t *set)
359 {
360         struct rt_sigframe32 __user *frame;
361         int err = 0;
362
363         frame = get_sigframe(ksig, regs, sizeof(*frame));
364         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
365                 return -EFAULT;
366
367         /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
368         err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
369
370         /* Create the ucontext.  */
371         err |= __put_user(0, &frame->rs_uc.uc_flags);
372         err |= __put_user(0, &frame->rs_uc.uc_link);
373         err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
374         err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
375         err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
376
377         if (err)
378                 return -EFAULT;
379
380         /*
381          * Arguments to signal handler:
382          *
383          *   a0 = signal number
384          *   a1 = 0 (should be cause)
385          *   a2 = pointer to ucontext
386          *
387          * $25 and c0_epc point to the signal handler, $29 points to
388          * the struct rt_sigframe32.
389          */
390         regs->regs[ 4] = ksig->sig;
391         regs->regs[ 5] = (unsigned long) &frame->rs_info;
392         regs->regs[ 6] = (unsigned long) &frame->rs_uc;
393         regs->regs[29] = (unsigned long) frame;
394         regs->regs[31] = (unsigned long) sig_return;
395         regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
396
397         DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
398                current->comm, current->pid,
399                frame, regs->cp0_epc, regs->regs[31]);
400
401         return 0;
402 }
403
404 /*
405  * o32 compatibility on 64-bit kernels, without DSP ASE
406  */
407 struct mips_abi mips_abi_32 = {
408         .setup_frame    = setup_frame_32,
409         .signal_return_offset =
410                 offsetof(struct mips_vdso, o32_signal_trampoline),
411         .setup_rt_frame = setup_rt_frame_32,
412         .rt_signal_return_offset =
413                 offsetof(struct mips_vdso, o32_rt_signal_trampoline),
414         .restart        = __NR_O32_restart_syscall,
415
416         .off_sc_fpregs = offsetof(struct sigcontext32, sc_fpregs),
417         .off_sc_fpc_csr = offsetof(struct sigcontext32, sc_fpc_csr),
418         .off_sc_used_math = offsetof(struct sigcontext32, sc_used_math),
419 };