ARM: Kirkwood: Remove mach-kirkwood
[cascardo/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/msa.h>
34 #include <asm/war.h>
35 #include <asm/vdso.h>
36 #include <asm/dsp.h>
37
38 #include "signal-common.h"
39
40 static int (*save_fp_context32)(struct sigcontext32 __user *sc);
41 static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
42
43 extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
44 extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
45
46 extern asmlinkage int _save_msa_context32(struct sigcontext32 __user *sc);
47 extern asmlinkage int _restore_msa_context32(struct sigcontext32 __user *sc);
48
49 /*
50  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
51  */
52 #define __NR_O32_restart_syscall        4253
53
54 /* 32-bit compatibility types */
55
56 typedef unsigned int __sighandler32_t;
57 typedef void (*vfptr_t)(void);
58
59 struct ucontext32 {
60         u32                 uc_flags;
61         s32                 uc_link;
62         compat_stack_t      uc_stack;
63         struct sigcontext32 uc_mcontext;
64         compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
65 };
66
67 struct sigframe32 {
68         u32 sf_ass[4];          /* argument save space for o32 */
69         u32 sf_pad[2];          /* Was: signal trampoline */
70         struct sigcontext32 sf_sc;
71         compat_sigset_t sf_mask;
72 };
73
74 struct rt_sigframe32 {
75         u32 rs_ass[4];                  /* argument save space for o32 */
76         u32 rs_pad[2];                  /* Was: signal trampoline */
77         compat_siginfo_t rs_info;
78         struct ucontext32 rs_uc;
79 };
80
81 /*
82  * Thread saved context copy to/from a signal context presumed to be on the
83  * user stack, and therefore accessed with appropriate macros from uaccess.h.
84  */
85 static int copy_fp_to_sigcontext32(struct sigcontext32 __user *sc)
86 {
87         int i;
88         int err = 0;
89         int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
90
91         for (i = 0; i < NUM_FPU_REGS; i += inc) {
92                 err |=
93                     __put_user(get_fpr64(&current->thread.fpu.fpr[i], 0),
94                                &sc->sc_fpregs[i]);
95         }
96         err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
97
98         return err;
99 }
100
101 static int copy_fp_from_sigcontext32(struct sigcontext32 __user *sc)
102 {
103         int i;
104         int err = 0;
105         int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
106         u64 fpr_val;
107
108         for (i = 0; i < NUM_FPU_REGS; i += inc) {
109                 err |= __get_user(fpr_val, &sc->sc_fpregs[i]);
110                 set_fpr64(&current->thread.fpu.fpr[i], 0, fpr_val);
111         }
112         err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
113
114         return err;
115 }
116
117 /*
118  * These functions will save only the upper 64 bits of the vector registers,
119  * since the lower 64 bits have already been saved as the scalar FP context.
120  */
121 static int copy_msa_to_sigcontext32(struct sigcontext32 __user *sc)
122 {
123         int i;
124         int err = 0;
125
126         for (i = 0; i < NUM_FPU_REGS; i++) {
127                 err |=
128                     __put_user(get_fpr64(&current->thread.fpu.fpr[i], 1),
129                                &sc->sc_msaregs[i]);
130         }
131         err |= __put_user(current->thread.fpu.msacsr, &sc->sc_msa_csr);
132
133         return err;
134 }
135
136 static int copy_msa_from_sigcontext32(struct sigcontext32 __user *sc)
137 {
138         int i;
139         int err = 0;
140         u64 val;
141
142         for (i = 0; i < NUM_FPU_REGS; i++) {
143                 err |= __get_user(val, &sc->sc_msaregs[i]);
144                 set_fpr64(&current->thread.fpu.fpr[i], 1, val);
145         }
146         err |= __get_user(current->thread.fpu.msacsr, &sc->sc_msa_csr);
147
148         return err;
149 }
150
151 /*
152  * sigcontext handlers
153  */
154 static int protected_save_fp_context32(struct sigcontext32 __user *sc,
155                                        unsigned used_math)
156 {
157         int err;
158         bool save_msa = cpu_has_msa && (used_math & USEDMATH_MSA);
159         while (1) {
160                 lock_fpu_owner();
161                 if (is_fpu_owner()) {
162                         err = save_fp_context32(sc);
163                         if (save_msa && !err)
164                                 err = _save_msa_context32(sc);
165                         unlock_fpu_owner();
166                 } else {
167                         unlock_fpu_owner();
168                         err = copy_fp_to_sigcontext32(sc);
169                         if (save_msa && !err)
170                                 err = copy_msa_to_sigcontext32(sc);
171                 }
172                 if (likely(!err))
173                         break;
174                 /* touch the sigcontext and try again */
175                 err = __put_user(0, &sc->sc_fpregs[0]) |
176                         __put_user(0, &sc->sc_fpregs[31]) |
177                         __put_user(0, &sc->sc_fpc_csr);
178                 if (err)
179                         break;  /* really bad sigcontext */
180         }
181         return err;
182 }
183
184 static int protected_restore_fp_context32(struct sigcontext32 __user *sc,
185                                           unsigned used_math)
186 {
187         int err, tmp __maybe_unused;
188         bool restore_msa = cpu_has_msa && (used_math & USEDMATH_MSA);
189         while (1) {
190                 lock_fpu_owner();
191                 if (is_fpu_owner()) {
192                         err = restore_fp_context32(sc);
193                         if (restore_msa && !err) {
194                                 enable_msa();
195                                 err = _restore_msa_context32(sc);
196                         } else {
197                                 /* signal handler may have used MSA */
198                                 disable_msa();
199                         }
200                         unlock_fpu_owner();
201                 } else {
202                         unlock_fpu_owner();
203                         err = copy_fp_from_sigcontext32(sc);
204                         if (restore_msa && !err)
205                                 err = copy_msa_from_sigcontext32(sc);
206                 }
207                 if (likely(!err))
208                         break;
209                 /* touch the sigcontext and try again */
210                 err = __get_user(tmp, &sc->sc_fpregs[0]) |
211                         __get_user(tmp, &sc->sc_fpregs[31]) |
212                         __get_user(tmp, &sc->sc_fpc_csr);
213                 if (err)
214                         break;  /* really bad sigcontext */
215         }
216         return err;
217 }
218
219 static int setup_sigcontext32(struct pt_regs *regs,
220                               struct sigcontext32 __user *sc)
221 {
222         int err = 0;
223         int i;
224         u32 used_math;
225
226         err |= __put_user(regs->cp0_epc, &sc->sc_pc);
227
228         err |= __put_user(0, &sc->sc_regs[0]);
229         for (i = 1; i < 32; i++)
230                 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
231
232         err |= __put_user(regs->hi, &sc->sc_mdhi);
233         err |= __put_user(regs->lo, &sc->sc_mdlo);
234         if (cpu_has_dsp) {
235                 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
236                 err |= __put_user(mfhi1(), &sc->sc_hi1);
237                 err |= __put_user(mflo1(), &sc->sc_lo1);
238                 err |= __put_user(mfhi2(), &sc->sc_hi2);
239                 err |= __put_user(mflo2(), &sc->sc_lo2);
240                 err |= __put_user(mfhi3(), &sc->sc_hi3);
241                 err |= __put_user(mflo3(), &sc->sc_lo3);
242         }
243
244         used_math = used_math() ? USEDMATH_FP : 0;
245         used_math |= thread_msa_context_live() ? USEDMATH_MSA : 0;
246         err |= __put_user(used_math, &sc->sc_used_math);
247
248         if (used_math) {
249                 /*
250                  * Save FPU state to signal context.  Signal handler
251                  * will "inherit" current FPU state.
252                  */
253                 err |= protected_save_fp_context32(sc, used_math);
254         }
255         return err;
256 }
257
258 static int
259 check_and_restore_fp_context32(struct sigcontext32 __user *sc,
260                                unsigned used_math)
261 {
262         int err, sig;
263
264         err = sig = fpcsr_pending(&sc->sc_fpc_csr);
265         if (err > 0)
266                 err = 0;
267         err |= protected_restore_fp_context32(sc, used_math);
268         return err ?: sig;
269 }
270
271 static int restore_sigcontext32(struct pt_regs *regs,
272                                 struct sigcontext32 __user *sc)
273 {
274         u32 used_math;
275         int err = 0;
276         s32 treg;
277         int i;
278
279         /* Always make any pending restarted system calls return -EINTR */
280         current_thread_info()->restart_block.fn = do_no_restart_syscall;
281
282         err |= __get_user(regs->cp0_epc, &sc->sc_pc);
283         err |= __get_user(regs->hi, &sc->sc_mdhi);
284         err |= __get_user(regs->lo, &sc->sc_mdlo);
285         if (cpu_has_dsp) {
286                 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
287                 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
288                 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
289                 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
290                 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
291                 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
292                 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
293         }
294
295         for (i = 1; i < 32; i++)
296                 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
297
298         err |= __get_user(used_math, &sc->sc_used_math);
299         conditional_used_math(used_math);
300
301         if (used_math) {
302                 /* restore fpu context if we have used it before */
303                 if (!err)
304                         err = check_and_restore_fp_context32(sc, used_math);
305         } else {
306                 /* signal handler may have used FPU or MSA. Disable them. */
307                 disable_msa();
308                 lose_fpu(0);
309         }
310
311         return err;
312 }
313
314 /*
315  *
316  */
317 extern void __put_sigset_unknown_nsig(void);
318 extern void __get_sigset_unknown_nsig(void);
319
320 static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
321 {
322         int err = 0;
323
324         if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
325                 return -EFAULT;
326
327         switch (_NSIG_WORDS) {
328         default:
329                 __put_sigset_unknown_nsig();
330         case 2:
331                 err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
332                 err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
333         case 1:
334                 err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
335                 err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
336         }
337
338         return err;
339 }
340
341 static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
342 {
343         int err = 0;
344         unsigned long sig[4];
345
346         if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
347                 return -EFAULT;
348
349         switch (_NSIG_WORDS) {
350         default:
351                 __get_sigset_unknown_nsig();
352         case 2:
353                 err |= __get_user(sig[3], &ubuf->sig[3]);
354                 err |= __get_user(sig[2], &ubuf->sig[2]);
355                 kbuf->sig[1] = sig[2] | (sig[3] << 32);
356         case 1:
357                 err |= __get_user(sig[1], &ubuf->sig[1]);
358                 err |= __get_user(sig[0], &ubuf->sig[0]);
359                 kbuf->sig[0] = sig[0] | (sig[1] << 32);
360         }
361
362         return err;
363 }
364
365 /*
366  * Atomically swap in the new signal mask, and wait for a signal.
367  */
368
369 asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
370 {
371         return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
372 }
373
374 SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
375         struct compat_sigaction __user *, oact)
376 {
377         struct k_sigaction new_ka, old_ka;
378         int ret;
379         int err = 0;
380
381         if (act) {
382                 old_sigset_t mask;
383                 s32 handler;
384
385                 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
386                         return -EFAULT;
387                 err |= __get_user(handler, &act->sa_handler);
388                 new_ka.sa.sa_handler = (void __user *)(s64)handler;
389                 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
390                 err |= __get_user(mask, &act->sa_mask.sig[0]);
391                 if (err)
392                         return -EFAULT;
393
394                 siginitset(&new_ka.sa.sa_mask, mask);
395         }
396
397         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
398
399         if (!ret && oact) {
400                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
401                         return -EFAULT;
402                 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
403                 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
404                                   &oact->sa_handler);
405                 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
406                 err |= __put_user(0, &oact->sa_mask.sig[1]);
407                 err |= __put_user(0, &oact->sa_mask.sig[2]);
408                 err |= __put_user(0, &oact->sa_mask.sig[3]);
409                 if (err)
410                         return -EFAULT;
411         }
412
413         return ret;
414 }
415
416 int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
417 {
418         int err;
419
420         if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
421                 return -EFAULT;
422
423         /* If you change siginfo_t structure, please be sure
424            this code is fixed accordingly.
425            It should never copy any pad contained in the structure
426            to avoid security leaks, but must copy the generic
427            3 ints plus the relevant union member.
428            This routine must convert siginfo from 64bit to 32bit as well
429            at the same time.  */
430         err = __put_user(from->si_signo, &to->si_signo);
431         err |= __put_user(from->si_errno, &to->si_errno);
432         err |= __put_user((short)from->si_code, &to->si_code);
433         if (from->si_code < 0)
434                 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
435         else {
436                 switch (from->si_code >> 16) {
437                 case __SI_TIMER >> 16:
438                         err |= __put_user(from->si_tid, &to->si_tid);
439                         err |= __put_user(from->si_overrun, &to->si_overrun);
440                         err |= __put_user(from->si_int, &to->si_int);
441                         break;
442                 case __SI_CHLD >> 16:
443                         err |= __put_user(from->si_utime, &to->si_utime);
444                         err |= __put_user(from->si_stime, &to->si_stime);
445                         err |= __put_user(from->si_status, &to->si_status);
446                 default:
447                         err |= __put_user(from->si_pid, &to->si_pid);
448                         err |= __put_user(from->si_uid, &to->si_uid);
449                         break;
450                 case __SI_FAULT >> 16:
451                         err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
452                         break;
453                 case __SI_POLL >> 16:
454                         err |= __put_user(from->si_band, &to->si_band);
455                         err |= __put_user(from->si_fd, &to->si_fd);
456                         break;
457                 case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
458                 case __SI_MESGQ >> 16:
459                         err |= __put_user(from->si_pid, &to->si_pid);
460                         err |= __put_user(from->si_uid, &to->si_uid);
461                         err |= __put_user(from->si_int, &to->si_int);
462                         break;
463                 }
464         }
465         return err;
466 }
467
468 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
469 {
470         memset(to, 0, sizeof *to);
471
472         if (copy_from_user(to, from, 3*sizeof(int)) ||
473             copy_from_user(to->_sifields._pad,
474                            from->_sifields._pad, SI_PAD_SIZE32))
475                 return -EFAULT;
476
477         return 0;
478 }
479
480 asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
481 {
482         struct sigframe32 __user *frame;
483         sigset_t blocked;
484         int sig;
485
486         frame = (struct sigframe32 __user *) regs.regs[29];
487         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
488                 goto badframe;
489         if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
490                 goto badframe;
491
492         set_current_blocked(&blocked);
493
494         sig = restore_sigcontext32(&regs, &frame->sf_sc);
495         if (sig < 0)
496                 goto badframe;
497         else if (sig)
498                 force_sig(sig, current);
499
500         /*
501          * Don't let your children do this ...
502          */
503         __asm__ __volatile__(
504                 "move\t$29, %0\n\t"
505                 "j\tsyscall_exit"
506                 :/* no outputs */
507                 :"r" (&regs));
508         /* Unreached */
509
510 badframe:
511         force_sig(SIGSEGV, current);
512 }
513
514 asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
515 {
516         struct rt_sigframe32 __user *frame;
517         sigset_t set;
518         int sig;
519
520         frame = (struct rt_sigframe32 __user *) regs.regs[29];
521         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
522                 goto badframe;
523         if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
524                 goto badframe;
525
526         set_current_blocked(&set);
527
528         sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
529         if (sig < 0)
530                 goto badframe;
531         else if (sig)
532                 force_sig(sig, current);
533
534         if (compat_restore_altstack(&frame->rs_uc.uc_stack))
535                 goto badframe;
536
537         /*
538          * Don't let your children do this ...
539          */
540         __asm__ __volatile__(
541                 "move\t$29, %0\n\t"
542                 "j\tsyscall_exit"
543                 :/* no outputs */
544                 :"r" (&regs));
545         /* Unreached */
546
547 badframe:
548         force_sig(SIGSEGV, current);
549 }
550
551 static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
552                           struct pt_regs *regs, int signr, sigset_t *set)
553 {
554         struct sigframe32 __user *frame;
555         int err = 0;
556
557         frame = get_sigframe(ka, regs, sizeof(*frame));
558         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
559                 goto give_sigsegv;
560
561         err |= setup_sigcontext32(regs, &frame->sf_sc);
562         err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
563
564         if (err)
565                 goto give_sigsegv;
566
567         /*
568          * Arguments to signal handler:
569          *
570          *   a0 = signal number
571          *   a1 = 0 (should be cause)
572          *   a2 = pointer to struct sigcontext
573          *
574          * $25 and c0_epc point to the signal handler, $29 points to the
575          * struct sigframe.
576          */
577         regs->regs[ 4] = signr;
578         regs->regs[ 5] = 0;
579         regs->regs[ 6] = (unsigned long) &frame->sf_sc;
580         regs->regs[29] = (unsigned long) frame;
581         regs->regs[31] = (unsigned long) sig_return;
582         regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
583
584         DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
585                current->comm, current->pid,
586                frame, regs->cp0_epc, regs->regs[31]);
587
588         return 0;
589
590 give_sigsegv:
591         force_sigsegv(signr, current);
592         return -EFAULT;
593 }
594
595 static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
596                              struct pt_regs *regs, int signr, sigset_t *set,
597                              siginfo_t *info)
598 {
599         struct rt_sigframe32 __user *frame;
600         int err = 0;
601
602         frame = get_sigframe(ka, regs, sizeof(*frame));
603         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
604                 goto give_sigsegv;
605
606         /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
607         err |= copy_siginfo_to_user32(&frame->rs_info, info);
608
609         /* Create the ucontext.  */
610         err |= __put_user(0, &frame->rs_uc.uc_flags);
611         err |= __put_user(0, &frame->rs_uc.uc_link);
612         err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
613         err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
614         err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
615
616         if (err)
617                 goto give_sigsegv;
618
619         /*
620          * Arguments to signal handler:
621          *
622          *   a0 = signal number
623          *   a1 = 0 (should be cause)
624          *   a2 = pointer to ucontext
625          *
626          * $25 and c0_epc point to the signal handler, $29 points to
627          * the struct rt_sigframe32.
628          */
629         regs->regs[ 4] = signr;
630         regs->regs[ 5] = (unsigned long) &frame->rs_info;
631         regs->regs[ 6] = (unsigned long) &frame->rs_uc;
632         regs->regs[29] = (unsigned long) frame;
633         regs->regs[31] = (unsigned long) sig_return;
634         regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
635
636         DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
637                current->comm, current->pid,
638                frame, regs->cp0_epc, regs->regs[31]);
639
640         return 0;
641
642 give_sigsegv:
643         force_sigsegv(signr, current);
644         return -EFAULT;
645 }
646
647 /*
648  * o32 compatibility on 64-bit kernels, without DSP ASE
649  */
650 struct mips_abi mips_abi_32 = {
651         .setup_frame    = setup_frame_32,
652         .signal_return_offset =
653                 offsetof(struct mips_vdso, o32_signal_trampoline),
654         .setup_rt_frame = setup_rt_frame_32,
655         .rt_signal_return_offset =
656                 offsetof(struct mips_vdso, o32_rt_signal_trampoline),
657         .restart        = __NR_O32_restart_syscall
658 };
659
660 static int signal32_init(void)
661 {
662         if (cpu_has_fpu) {
663                 save_fp_context32 = _save_fp_context32;
664                 restore_fp_context32 = _restore_fp_context32;
665         } else {
666                 save_fp_context32 = copy_fp_to_sigcontext32;
667                 restore_fp_context32 = copy_fp_from_sigcontext32;
668         }
669
670         return 0;
671 }
672
673 arch_initcall(signal32_init);