Merge tag 'gcc-plugins-v4.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / arch / mips / kernel / signal_o32.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  * Copyright (C) 2016, Imagination Technologies Ltd.
10  */
11 #include <linux/compiler.h>
12 #include <linux/errno.h>
13 #include <linux/signal.h>
14 #include <linux/uaccess.h>
15
16 #include <asm/abi.h>
17 #include <asm/compat-signal.h>
18 #include <asm/dsp.h>
19 #include <asm/sim.h>
20 #include <asm/unistd.h>
21
22 #include "signal-common.h"
23
24 /*
25  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
26  */
27 #define __NR_O32_restart_syscall        4253
28
29 struct sigframe32 {
30         u32 sf_ass[4];          /* argument save space for o32 */
31         u32 sf_pad[2];          /* Was: signal trampoline */
32         struct sigcontext32 sf_sc;
33         compat_sigset_t sf_mask;
34 };
35
36 struct ucontext32 {
37         u32                 uc_flags;
38         s32                 uc_link;
39         compat_stack_t      uc_stack;
40         struct sigcontext32 uc_mcontext;
41         compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
42 };
43
44 struct rt_sigframe32 {
45         u32 rs_ass[4];                  /* argument save space for o32 */
46         u32 rs_pad[2];                  /* Was: signal trampoline */
47         compat_siginfo_t rs_info;
48         struct ucontext32 rs_uc;
49 };
50
51 static int setup_sigcontext32(struct pt_regs *regs,
52                               struct sigcontext32 __user *sc)
53 {
54         int err = 0;
55         int i;
56
57         err |= __put_user(regs->cp0_epc, &sc->sc_pc);
58
59         err |= __put_user(0, &sc->sc_regs[0]);
60         for (i = 1; i < 32; i++)
61                 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
62
63         err |= __put_user(regs->hi, &sc->sc_mdhi);
64         err |= __put_user(regs->lo, &sc->sc_mdlo);
65         if (cpu_has_dsp) {
66                 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
67                 err |= __put_user(mfhi1(), &sc->sc_hi1);
68                 err |= __put_user(mflo1(), &sc->sc_lo1);
69                 err |= __put_user(mfhi2(), &sc->sc_hi2);
70                 err |= __put_user(mflo2(), &sc->sc_lo2);
71                 err |= __put_user(mfhi3(), &sc->sc_hi3);
72                 err |= __put_user(mflo3(), &sc->sc_lo3);
73         }
74
75         /*
76          * Save FPU state to signal context.  Signal handler
77          * will "inherit" current FPU state.
78          */
79         err |= protected_save_fp_context(sc);
80
81         return err;
82 }
83
84 static int restore_sigcontext32(struct pt_regs *regs,
85                                 struct sigcontext32 __user *sc)
86 {
87         int err = 0;
88         s32 treg;
89         int i;
90
91         /* Always make any pending restarted system calls return -EINTR */
92         current->restart_block.fn = do_no_restart_syscall;
93
94         err |= __get_user(regs->cp0_epc, &sc->sc_pc);
95         err |= __get_user(regs->hi, &sc->sc_mdhi);
96         err |= __get_user(regs->lo, &sc->sc_mdlo);
97         if (cpu_has_dsp) {
98                 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
99                 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
100                 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
101                 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
102                 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
103                 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
104                 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
105         }
106
107         for (i = 1; i < 32; i++)
108                 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
109
110         return err ?: protected_restore_fp_context(sc);
111 }
112
113 static int setup_frame_32(void *sig_return, struct ksignal *ksig,
114                           struct pt_regs *regs, sigset_t *set)
115 {
116         struct sigframe32 __user *frame;
117         int err = 0;
118
119         frame = get_sigframe(ksig, regs, sizeof(*frame));
120         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
121                 return -EFAULT;
122
123         err |= setup_sigcontext32(regs, &frame->sf_sc);
124         err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
125
126         if (err)
127                 return -EFAULT;
128
129         /*
130          * Arguments to signal handler:
131          *
132          *   a0 = signal number
133          *   a1 = 0 (should be cause)
134          *   a2 = pointer to struct sigcontext
135          *
136          * $25 and c0_epc point to the signal handler, $29 points to the
137          * struct sigframe.
138          */
139         regs->regs[ 4] = ksig->sig;
140         regs->regs[ 5] = 0;
141         regs->regs[ 6] = (unsigned long) &frame->sf_sc;
142         regs->regs[29] = (unsigned long) frame;
143         regs->regs[31] = (unsigned long) sig_return;
144         regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
145
146         DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
147                current->comm, current->pid,
148                frame, regs->cp0_epc, regs->regs[31]);
149
150         return 0;
151 }
152
153 asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
154 {
155         struct rt_sigframe32 __user *frame;
156         sigset_t set;
157         int sig;
158
159         frame = (struct rt_sigframe32 __user *) regs.regs[29];
160         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
161                 goto badframe;
162         if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
163                 goto badframe;
164
165         set_current_blocked(&set);
166
167         sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
168         if (sig < 0)
169                 goto badframe;
170         else if (sig)
171                 force_sig(sig, current);
172
173         if (compat_restore_altstack(&frame->rs_uc.uc_stack))
174                 goto badframe;
175
176         /*
177          * Don't let your children do this ...
178          */
179         __asm__ __volatile__(
180                 "move\t$29, %0\n\t"
181                 "j\tsyscall_exit"
182                 :/* no outputs */
183                 :"r" (&regs));
184         /* Unreached */
185
186 badframe:
187         force_sig(SIGSEGV, current);
188 }
189
190 static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig,
191                              struct pt_regs *regs, sigset_t *set)
192 {
193         struct rt_sigframe32 __user *frame;
194         int err = 0;
195
196         frame = get_sigframe(ksig, regs, sizeof(*frame));
197         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
198                 return -EFAULT;
199
200         /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
201         err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
202
203         /* Create the ucontext.  */
204         err |= __put_user(0, &frame->rs_uc.uc_flags);
205         err |= __put_user(0, &frame->rs_uc.uc_link);
206         err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
207         err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
208         err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
209
210         if (err)
211                 return -EFAULT;
212
213         /*
214          * Arguments to signal handler:
215          *
216          *   a0 = signal number
217          *   a1 = 0 (should be cause)
218          *   a2 = pointer to ucontext
219          *
220          * $25 and c0_epc point to the signal handler, $29 points to
221          * the struct rt_sigframe32.
222          */
223         regs->regs[ 4] = ksig->sig;
224         regs->regs[ 5] = (unsigned long) &frame->rs_info;
225         regs->regs[ 6] = (unsigned long) &frame->rs_uc;
226         regs->regs[29] = (unsigned long) frame;
227         regs->regs[31] = (unsigned long) sig_return;
228         regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
229
230         DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
231                current->comm, current->pid,
232                frame, regs->cp0_epc, regs->regs[31]);
233
234         return 0;
235 }
236
237 /*
238  * o32 compatibility on 64-bit kernels, without DSP ASE
239  */
240 struct mips_abi mips_abi_32 = {
241         .setup_frame    = setup_frame_32,
242         .setup_rt_frame = setup_rt_frame_32,
243         .restart        = __NR_O32_restart_syscall,
244
245         .off_sc_fpregs = offsetof(struct sigcontext32, sc_fpregs),
246         .off_sc_fpc_csr = offsetof(struct sigcontext32, sc_fpc_csr),
247         .off_sc_used_math = offsetof(struct sigcontext32, sc_used_math),
248
249         .vdso           = &vdso_image_o32,
250 };
251
252
253 asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
254 {
255         struct sigframe32 __user *frame;
256         sigset_t blocked;
257         int sig;
258
259         frame = (struct sigframe32 __user *) regs.regs[29];
260         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
261                 goto badframe;
262         if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
263                 goto badframe;
264
265         set_current_blocked(&blocked);
266
267         sig = restore_sigcontext32(&regs, &frame->sf_sc);
268         if (sig < 0)
269                 goto badframe;
270         else if (sig)
271                 force_sig(sig, current);
272
273         /*
274          * Don't let your children do this ...
275          */
276         __asm__ __volatile__(
277                 "move\t$29, %0\n\t"
278                 "j\tsyscall_exit"
279                 :/* no outputs */
280                 :"r" (&regs));
281         /* Unreached */
282
283 badframe:
284         force_sig(SIGSEGV, current);
285 }