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