arm64: switch to generic compat rt_sigaction()
[linux-3.10.git] / arch / arm64 / kernel / signal32.c
1 /*
2  * Based on arch/arm/kernel/signal.c
3  *
4  * Copyright (C) 1995-2009 Russell King
5  * Copyright (C) 2012 ARM Ltd.
6  * Modified by Will Deacon <will.deacon@arm.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <linux/compat.h>
22 #include <linux/signal.h>
23 #include <linux/syscalls.h>
24 #include <linux/ratelimit.h>
25
26 #include <asm/fpsimd.h>
27 #include <asm/signal32.h>
28 #include <asm/uaccess.h>
29 #include <asm/unistd32.h>
30
31 struct compat_old_sigaction {
32         compat_uptr_t                   sa_handler;
33         compat_old_sigset_t             sa_mask;
34         compat_ulong_t                  sa_flags;
35         compat_uptr_t                   sa_restorer;
36 };
37
38 struct compat_sigcontext {
39         /* We always set these two fields to 0 */
40         compat_ulong_t                  trap_no;
41         compat_ulong_t                  error_code;
42
43         compat_ulong_t                  oldmask;
44         compat_ulong_t                  arm_r0;
45         compat_ulong_t                  arm_r1;
46         compat_ulong_t                  arm_r2;
47         compat_ulong_t                  arm_r3;
48         compat_ulong_t                  arm_r4;
49         compat_ulong_t                  arm_r5;
50         compat_ulong_t                  arm_r6;
51         compat_ulong_t                  arm_r7;
52         compat_ulong_t                  arm_r8;
53         compat_ulong_t                  arm_r9;
54         compat_ulong_t                  arm_r10;
55         compat_ulong_t                  arm_fp;
56         compat_ulong_t                  arm_ip;
57         compat_ulong_t                  arm_sp;
58         compat_ulong_t                  arm_lr;
59         compat_ulong_t                  arm_pc;
60         compat_ulong_t                  arm_cpsr;
61         compat_ulong_t                  fault_address;
62 };
63
64 struct compat_ucontext {
65         compat_ulong_t                  uc_flags;
66         struct compat_ucontext          *uc_link;
67         compat_stack_t                  uc_stack;
68         struct compat_sigcontext        uc_mcontext;
69         compat_sigset_t                 uc_sigmask;
70         int             __unused[32 - (sizeof (compat_sigset_t) / sizeof (int))];
71         compat_ulong_t  uc_regspace[128] __attribute__((__aligned__(8)));
72 };
73
74 struct compat_vfp_sigframe {
75         compat_ulong_t  magic;
76         compat_ulong_t  size;
77         struct compat_user_vfp {
78                 compat_u64      fpregs[32];
79                 compat_ulong_t  fpscr;
80         } ufp;
81         struct compat_user_vfp_exc {
82                 compat_ulong_t  fpexc;
83                 compat_ulong_t  fpinst;
84                 compat_ulong_t  fpinst2;
85         } ufp_exc;
86 } __attribute__((__aligned__(8)));
87
88 #define VFP_MAGIC               0x56465001
89 #define VFP_STORAGE_SIZE        sizeof(struct compat_vfp_sigframe)
90
91 struct compat_aux_sigframe {
92         struct compat_vfp_sigframe      vfp;
93
94         /* Something that isn't a valid magic number for any coprocessor.  */
95         unsigned long                   end_magic;
96 } __attribute__((__aligned__(8)));
97
98 struct compat_sigframe {
99         struct compat_ucontext  uc;
100         compat_ulong_t          retcode[2];
101 };
102
103 struct compat_rt_sigframe {
104         struct compat_siginfo info;
105         struct compat_sigframe sig;
106 };
107
108 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
109
110 /*
111  * For ARM syscalls, the syscall number has to be loaded into r7.
112  * We do not support an OABI userspace.
113  */
114 #define MOV_R7_NR_SIGRETURN     (0xe3a07000 | __NR_compat_sigreturn)
115 #define SVC_SYS_SIGRETURN       (0xef000000 | __NR_compat_sigreturn)
116 #define MOV_R7_NR_RT_SIGRETURN  (0xe3a07000 | __NR_compat_rt_sigreturn)
117 #define SVC_SYS_RT_SIGRETURN    (0xef000000 | __NR_compat_rt_sigreturn)
118
119 /*
120  * For Thumb syscalls, we also pass the syscall number via r7. We therefore
121  * need two 16-bit instructions.
122  */
123 #define SVC_THUMB_SIGRETURN     (((0xdf00 | __NR_compat_sigreturn) << 16) | \
124                                    0x2700 | __NR_compat_sigreturn)
125 #define SVC_THUMB_RT_SIGRETURN  (((0xdf00 | __NR_compat_rt_sigreturn) << 16) | \
126                                    0x2700 | __NR_compat_rt_sigreturn)
127
128 const compat_ulong_t aarch32_sigret_code[6] = {
129         /*
130          * AArch32 sigreturn code.
131          * We don't construct an OABI SWI - instead we just set the imm24 field
132          * to the EABI syscall number so that we create a sane disassembly.
133          */
134         MOV_R7_NR_SIGRETURN,    SVC_SYS_SIGRETURN,    SVC_THUMB_SIGRETURN,
135         MOV_R7_NR_RT_SIGRETURN, SVC_SYS_RT_SIGRETURN, SVC_THUMB_RT_SIGRETURN,
136 };
137
138 static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
139 {
140         compat_sigset_t cset;
141
142         cset.sig[0] = set->sig[0] & 0xffffffffull;
143         cset.sig[1] = set->sig[0] >> 32;
144
145         return copy_to_user(uset, &cset, sizeof(*uset));
146 }
147
148 static inline int get_sigset_t(sigset_t *set,
149                                const compat_sigset_t __user *uset)
150 {
151         compat_sigset_t s32;
152
153         if (copy_from_user(&s32, uset, sizeof(*uset)))
154                 return -EFAULT;
155
156         set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
157         return 0;
158 }
159
160 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
161 {
162         int err;
163
164         if (!access_ok(VERIFY_WRITE, to, sizeof(*to)))
165                 return -EFAULT;
166
167         /* If you change siginfo_t structure, please be sure
168          * this code is fixed accordingly.
169          * It should never copy any pad contained in the structure
170          * to avoid security leaks, but must copy the generic
171          * 3 ints plus the relevant union member.
172          * This routine must convert siginfo from 64bit to 32bit as well
173          * at the same time.
174          */
175         err = __put_user(from->si_signo, &to->si_signo);
176         err |= __put_user(from->si_errno, &to->si_errno);
177         err |= __put_user((short)from->si_code, &to->si_code);
178         if (from->si_code < 0)
179                 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad,
180                                       SI_PAD_SIZE);
181         else switch (from->si_code & __SI_MASK) {
182         case __SI_KILL:
183                 err |= __put_user(from->si_pid, &to->si_pid);
184                 err |= __put_user(from->si_uid, &to->si_uid);
185                 break;
186         case __SI_TIMER:
187                  err |= __put_user(from->si_tid, &to->si_tid);
188                  err |= __put_user(from->si_overrun, &to->si_overrun);
189                  err |= __put_user((compat_uptr_t)(unsigned long)from->si_ptr,
190                                    &to->si_ptr);
191                 break;
192         case __SI_POLL:
193                 err |= __put_user(from->si_band, &to->si_band);
194                 err |= __put_user(from->si_fd, &to->si_fd);
195                 break;
196         case __SI_FAULT:
197                 err |= __put_user((compat_uptr_t)(unsigned long)from->si_addr,
198                                   &to->si_addr);
199 #ifdef BUS_MCEERR_AO
200                 /*
201                  * Other callers might not initialize the si_lsb field,
202                  * so check explicitely for the right codes here.
203                  */
204                 if (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO)
205                         err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb);
206 #endif
207                 break;
208         case __SI_CHLD:
209                 err |= __put_user(from->si_pid, &to->si_pid);
210                 err |= __put_user(from->si_uid, &to->si_uid);
211                 err |= __put_user(from->si_status, &to->si_status);
212                 err |= __put_user(from->si_utime, &to->si_utime);
213                 err |= __put_user(from->si_stime, &to->si_stime);
214                 break;
215         case __SI_RT: /* This is not generated by the kernel as of now. */
216         case __SI_MESGQ: /* But this is */
217                 err |= __put_user(from->si_pid, &to->si_pid);
218                 err |= __put_user(from->si_uid, &to->si_uid);
219                 err |= __put_user((compat_uptr_t)(unsigned long)from->si_ptr, &to->si_ptr);
220                 break;
221         default: /* this is just in case for now ... */
222                 err |= __put_user(from->si_pid, &to->si_pid);
223                 err |= __put_user(from->si_uid, &to->si_uid);
224                 break;
225         }
226         return err;
227 }
228
229 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
230 {
231         memset(to, 0, sizeof *to);
232
233         if (copy_from_user(to, from, __ARCH_SI_PREAMBLE_SIZE) ||
234             copy_from_user(to->_sifields._pad,
235                            from->_sifields._pad, SI_PAD_SIZE))
236                 return -EFAULT;
237
238         return 0;
239 }
240
241 /*
242  * VFP save/restore code.
243  */
244 static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame)
245 {
246         struct fpsimd_state *fpsimd = &current->thread.fpsimd_state;
247         compat_ulong_t magic = VFP_MAGIC;
248         compat_ulong_t size = VFP_STORAGE_SIZE;
249         compat_ulong_t fpscr, fpexc;
250         int err = 0;
251
252         /*
253          * Save the hardware registers to the fpsimd_state structure.
254          * Note that this also saves V16-31, which aren't visible
255          * in AArch32.
256          */
257         fpsimd_save_state(fpsimd);
258
259         /* Place structure header on the stack */
260         __put_user_error(magic, &frame->magic, err);
261         __put_user_error(size, &frame->size, err);
262
263         /*
264          * Now copy the FP registers. Since the registers are packed,
265          * we can copy the prefix we want (V0-V15) as it is.
266          * FIXME: Won't work if big endian.
267          */
268         err |= __copy_to_user(&frame->ufp.fpregs, fpsimd->vregs,
269                               sizeof(frame->ufp.fpregs));
270
271         /* Create an AArch32 fpscr from the fpsr and the fpcr. */
272         fpscr = (fpsimd->fpsr & VFP_FPSCR_STAT_MASK) |
273                 (fpsimd->fpcr & VFP_FPSCR_CTRL_MASK);
274         __put_user_error(fpscr, &frame->ufp.fpscr, err);
275
276         /*
277          * The exception register aren't available so we fake up a
278          * basic FPEXC and zero everything else.
279          */
280         fpexc = (1 << 30);
281         __put_user_error(fpexc, &frame->ufp_exc.fpexc, err);
282         __put_user_error(0, &frame->ufp_exc.fpinst, err);
283         __put_user_error(0, &frame->ufp_exc.fpinst2, err);
284
285         return err ? -EFAULT : 0;
286 }
287
288 static int compat_restore_vfp_context(struct compat_vfp_sigframe __user *frame)
289 {
290         struct fpsimd_state fpsimd;
291         compat_ulong_t magic = VFP_MAGIC;
292         compat_ulong_t size = VFP_STORAGE_SIZE;
293         compat_ulong_t fpscr;
294         int err = 0;
295
296         __get_user_error(magic, &frame->magic, err);
297         __get_user_error(size, &frame->size, err);
298
299         if (err)
300                 return -EFAULT;
301         if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
302                 return -EINVAL;
303
304         /*
305          * Copy the FP registers into the start of the fpsimd_state.
306          * FIXME: Won't work if big endian.
307          */
308         err |= __copy_from_user(fpsimd.vregs, frame->ufp.fpregs,
309                                 sizeof(frame->ufp.fpregs));
310
311         /* Extract the fpsr and the fpcr from the fpscr */
312         __get_user_error(fpscr, &frame->ufp.fpscr, err);
313         fpsimd.fpsr = fpscr & VFP_FPSCR_STAT_MASK;
314         fpsimd.fpcr = fpscr & VFP_FPSCR_CTRL_MASK;
315
316         /*
317          * We don't need to touch the exception register, so
318          * reload the hardware state.
319          */
320         if (!err) {
321                 preempt_disable();
322                 fpsimd_load_state(&fpsimd);
323                 preempt_enable();
324         }
325
326         return err ? -EFAULT : 0;
327 }
328
329 asmlinkage int compat_sys_sigaction(int sig,
330                                     const struct compat_old_sigaction __user *act,
331                                     struct compat_old_sigaction __user *oact)
332 {
333         struct k_sigaction new_ka, old_ka;
334         int ret;
335         compat_old_sigset_t mask;
336         compat_uptr_t handler, restorer;
337
338         if (act) {
339                 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
340                     __get_user(handler, &act->sa_handler) ||
341                     __get_user(restorer, &act->sa_restorer) ||
342                     __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
343                     __get_user(mask, &act->sa_mask))
344                         return -EFAULT;
345
346                 new_ka.sa.sa_handler = compat_ptr(handler);
347                 new_ka.sa.sa_restorer = compat_ptr(restorer);
348                 siginitset(&new_ka.sa.sa_mask, mask);
349         }
350
351         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
352
353         if (!ret && oact) {
354                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
355                     __put_user(ptr_to_compat(old_ka.sa.sa_handler),
356                                &oact->sa_handler) ||
357                     __put_user(ptr_to_compat(old_ka.sa.sa_restorer),
358                                &oact->sa_restorer) ||
359                     __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
360                     __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
361                         return -EFAULT;
362         }
363
364         return ret;
365 }
366
367 static int compat_restore_sigframe(struct pt_regs *regs,
368                                    struct compat_sigframe __user *sf)
369 {
370         int err;
371         sigset_t set;
372         struct compat_aux_sigframe __user *aux;
373
374         err = get_sigset_t(&set, &sf->uc.uc_sigmask);
375         if (err == 0) {
376                 sigdelsetmask(&set, ~_BLOCKABLE);
377                 set_current_blocked(&set);
378         }
379
380         __get_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err);
381         __get_user_error(regs->regs[1], &sf->uc.uc_mcontext.arm_r1, err);
382         __get_user_error(regs->regs[2], &sf->uc.uc_mcontext.arm_r2, err);
383         __get_user_error(regs->regs[3], &sf->uc.uc_mcontext.arm_r3, err);
384         __get_user_error(regs->regs[4], &sf->uc.uc_mcontext.arm_r4, err);
385         __get_user_error(regs->regs[5], &sf->uc.uc_mcontext.arm_r5, err);
386         __get_user_error(regs->regs[6], &sf->uc.uc_mcontext.arm_r6, err);
387         __get_user_error(regs->regs[7], &sf->uc.uc_mcontext.arm_r7, err);
388         __get_user_error(regs->regs[8], &sf->uc.uc_mcontext.arm_r8, err);
389         __get_user_error(regs->regs[9], &sf->uc.uc_mcontext.arm_r9, err);
390         __get_user_error(regs->regs[10], &sf->uc.uc_mcontext.arm_r10, err);
391         __get_user_error(regs->regs[11], &sf->uc.uc_mcontext.arm_fp, err);
392         __get_user_error(regs->regs[12], &sf->uc.uc_mcontext.arm_ip, err);
393         __get_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err);
394         __get_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err);
395         __get_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err);
396         __get_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err);
397
398         /*
399          * Avoid compat_sys_sigreturn() restarting.
400          */
401         regs->syscallno = ~0UL;
402
403         err |= !valid_user_regs(&regs->user_regs);
404
405         aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace;
406         if (err == 0)
407                 err |= compat_restore_vfp_context(&aux->vfp);
408
409         return err;
410 }
411
412 asmlinkage int compat_sys_sigreturn(struct pt_regs *regs)
413 {
414         struct compat_sigframe __user *frame;
415
416         /* Always make any pending restarted system calls return -EINTR */
417         current_thread_info()->restart_block.fn = do_no_restart_syscall;
418
419         /*
420          * Since we stacked the signal on a 64-bit boundary,
421          * then 'sp' should be word aligned here.  If it's
422          * not, then the user is trying to mess with us.
423          */
424         if (regs->compat_sp & 7)
425                 goto badframe;
426
427         frame = (struct compat_sigframe __user *)regs->compat_sp;
428
429         if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
430                 goto badframe;
431
432         if (compat_restore_sigframe(regs, frame))
433                 goto badframe;
434
435         return regs->regs[0];
436
437 badframe:
438         if (show_unhandled_signals)
439                 pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n",
440                                     current->comm, task_pid_nr(current), __func__,
441                                     regs->pc, regs->sp);
442         force_sig(SIGSEGV, current);
443         return 0;
444 }
445
446 asmlinkage int compat_sys_rt_sigreturn(struct pt_regs *regs)
447 {
448         struct compat_rt_sigframe __user *frame;
449
450         /* Always make any pending restarted system calls return -EINTR */
451         current_thread_info()->restart_block.fn = do_no_restart_syscall;
452
453         /*
454          * Since we stacked the signal on a 64-bit boundary,
455          * then 'sp' should be word aligned here.  If it's
456          * not, then the user is trying to mess with us.
457          */
458         if (regs->compat_sp & 7)
459                 goto badframe;
460
461         frame = (struct compat_rt_sigframe __user *)regs->compat_sp;
462
463         if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
464                 goto badframe;
465
466         if (compat_restore_sigframe(regs, &frame->sig))
467                 goto badframe;
468
469         if (compat_restore_altstack(&frame->sig.uc.uc_stack))
470                 goto badframe;
471
472         return regs->regs[0];
473
474 badframe:
475         if (show_unhandled_signals)
476                 pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n",
477                                     current->comm, task_pid_nr(current), __func__,
478                                     regs->pc, regs->sp);
479         force_sig(SIGSEGV, current);
480         return 0;
481 }
482
483 static void __user *compat_get_sigframe(struct k_sigaction *ka,
484                                         struct pt_regs *regs,
485                                         int framesize)
486 {
487         compat_ulong_t sp = regs->compat_sp;
488         void __user *frame;
489
490         /*
491          * This is the X/Open sanctioned signal stack switching.
492          */
493         if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
494                 sp = current->sas_ss_sp + current->sas_ss_size;
495
496         /*
497          * ATPCS B01 mandates 8-byte alignment
498          */
499         frame = compat_ptr((compat_uptr_t)((sp - framesize) & ~7));
500
501         /*
502          * Check that we can actually write to the signal frame.
503          */
504         if (!access_ok(VERIFY_WRITE, frame, framesize))
505                 frame = NULL;
506
507         return frame;
508 }
509
510 static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
511                                 compat_ulong_t __user *rc, void __user *frame,
512                                 int usig)
513 {
514         compat_ulong_t handler = ptr_to_compat(ka->sa.sa_handler);
515         compat_ulong_t retcode;
516         compat_ulong_t spsr = regs->pstate & ~PSR_f;
517         int thumb;
518
519         /* Check if the handler is written for ARM or Thumb */
520         thumb = handler & 1;
521
522         if (thumb) {
523                 spsr |= COMPAT_PSR_T_BIT;
524                 spsr &= ~COMPAT_PSR_IT_MASK;
525         } else {
526                 spsr &= ~COMPAT_PSR_T_BIT;
527         }
528
529         if (ka->sa.sa_flags & SA_RESTORER) {
530                 retcode = ptr_to_compat(ka->sa.sa_restorer);
531         } else {
532                 /* Set up sigreturn pointer */
533                 unsigned int idx = thumb << 1;
534
535                 if (ka->sa.sa_flags & SA_SIGINFO)
536                         idx += 3;
537
538                 retcode = AARCH32_VECTORS_BASE +
539                           AARCH32_KERN_SIGRET_CODE_OFFSET +
540                           (idx << 2) + thumb;
541         }
542
543         regs->regs[0]   = usig;
544         regs->compat_sp = ptr_to_compat(frame);
545         regs->compat_lr = retcode;
546         regs->pc        = handler;
547         regs->pstate    = spsr;
548 }
549
550 static int compat_setup_sigframe(struct compat_sigframe __user *sf,
551                                  struct pt_regs *regs, sigset_t *set)
552 {
553         struct compat_aux_sigframe __user *aux;
554         int err = 0;
555
556         __put_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err);
557         __put_user_error(regs->regs[1], &sf->uc.uc_mcontext.arm_r1, err);
558         __put_user_error(regs->regs[2], &sf->uc.uc_mcontext.arm_r2, err);
559         __put_user_error(regs->regs[3], &sf->uc.uc_mcontext.arm_r3, err);
560         __put_user_error(regs->regs[4], &sf->uc.uc_mcontext.arm_r4, err);
561         __put_user_error(regs->regs[5], &sf->uc.uc_mcontext.arm_r5, err);
562         __put_user_error(regs->regs[6], &sf->uc.uc_mcontext.arm_r6, err);
563         __put_user_error(regs->regs[7], &sf->uc.uc_mcontext.arm_r7, err);
564         __put_user_error(regs->regs[8], &sf->uc.uc_mcontext.arm_r8, err);
565         __put_user_error(regs->regs[9], &sf->uc.uc_mcontext.arm_r9, err);
566         __put_user_error(regs->regs[10], &sf->uc.uc_mcontext.arm_r10, err);
567         __put_user_error(regs->regs[11], &sf->uc.uc_mcontext.arm_fp, err);
568         __put_user_error(regs->regs[12], &sf->uc.uc_mcontext.arm_ip, err);
569         __put_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err);
570         __put_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err);
571         __put_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err);
572         __put_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err);
573
574         __put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err);
575         __put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.error_code, err);
576         __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err);
577         __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err);
578
579         err |= put_sigset_t(&sf->uc.uc_sigmask, set);
580
581         aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace;
582
583         if (err == 0)
584                 err |= compat_preserve_vfp_context(&aux->vfp);
585         __put_user_error(0, &aux->end_magic, err);
586
587         return err;
588 }
589
590 /*
591  * 32-bit signal handling routines called from signal.c
592  */
593 int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
594                           sigset_t *set, struct pt_regs *regs)
595 {
596         struct compat_rt_sigframe __user *frame;
597         compat_stack_t stack;
598         int err = 0;
599
600         frame = compat_get_sigframe(ka, regs, sizeof(*frame));
601
602         if (!frame)
603                 return 1;
604
605         err |= copy_siginfo_to_user32(&frame->info, info);
606
607         __put_user_error(0, &frame->sig.uc.uc_flags, err);
608         __put_user_error(NULL, &frame->sig.uc.uc_link, err);
609
610         err |= __compat_save_altstack(&frame->sig.uc.uc_stack, regs->compat_sp);
611
612         err |= compat_setup_sigframe(&frame->sig, regs, set);
613
614         if (err == 0) {
615                 compat_setup_return(regs, ka, frame->sig.retcode, frame, usig);
616                 regs->regs[1] = (compat_ulong_t)(unsigned long)&frame->info;
617                 regs->regs[2] = (compat_ulong_t)(unsigned long)&frame->sig.uc;
618         }
619
620         return err;
621 }
622
623 int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set,
624                        struct pt_regs *regs)
625 {
626         struct compat_sigframe __user *frame;
627         int err = 0;
628
629         frame = compat_get_sigframe(ka, regs, sizeof(*frame));
630
631         if (!frame)
632                 return 1;
633
634         __put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err);
635
636         err |= compat_setup_sigframe(frame, regs, set);
637         if (err == 0)
638                 compat_setup_return(regs, ka, frame->retcode, frame, usig);
639
640         return err;
641 }
642
643 void compat_setup_restart_syscall(struct pt_regs *regs)
644 {
645        regs->regs[7] = __NR_compat_restart_syscall;
646 }