Merge branch 'for-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
[linux-2.6-block.git] / arch / mips / kernel / signal32.c
CommitLineData
1da177e4
LT
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
dda73d0b 7 * Copyright (C) 1994 - 2000, 2006 Ralf Baechle
1da177e4
LT
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 */
02416dcf 10#include <linux/cache.h>
431dc804 11#include <linux/compat.h>
1da177e4
LT
12#include <linux/sched.h>
13#include <linux/mm.h>
14#include <linux/smp.h>
1da177e4
LT
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>
1da177e4
LT
21#include <linux/suspend.h>
22#include <linux/compiler.h>
faea6234 23#include <linux/uaccess.h>
1da177e4 24
e50c0a8f 25#include <asm/abi.h>
1da177e4 26#include <asm/asm.h>
431dc804 27#include <asm/compat-signal.h>
1da177e4
LT
28#include <linux/bitops.h>
29#include <asm/cacheflush.h>
30#include <asm/sim.h>
1da177e4 31#include <asm/ucontext.h>
1da177e4 32#include <asm/fpu.h>
02416dcf 33#include <asm/war.h>
b81947c6 34#include <asm/dsp.h>
1da177e4 35
36a1f2c2
FBH
36#include "signal-common.h"
37
1da177e4
LT
38/*
39 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
40 */
70342287 41#define __NR_O32_restart_syscall 4253
1da177e4 42
1da177e4
LT
43/* 32-bit compatibility types */
44
1da177e4
LT
45typedef unsigned int __sighandler32_t;
46typedef void (*vfptr_t)(void);
47
1da177e4 48struct ucontext32 {
70342287
RB
49 u32 uc_flags;
50 s32 uc_link;
ea536ad4 51 compat_stack_t uc_stack;
1da177e4 52 struct sigcontext32 uc_mcontext;
70342287 53 compat_sigset_t uc_sigmask; /* mask last for extensibility */
1da177e4
LT
54};
55
dd02f06a
RB
56struct sigframe32 {
57 u32 sf_ass[4]; /* argument save space for o32 */
d814c28c 58 u32 sf_pad[2]; /* Was: signal trampoline */
dd02f06a 59 struct sigcontext32 sf_sc;
755f21bb 60 compat_sigset_t sf_mask;
dd02f06a
RB
61};
62
c0b9bae9
FBH
63struct rt_sigframe32 {
64 u32 rs_ass[4]; /* argument save space for o32 */
d814c28c 65 u32 rs_pad[2]; /* Was: signal trampoline */
c0b9bae9
FBH
66 compat_siginfo_t rs_info;
67 struct ucontext32 rs_uc;
68};
69
9432a9ba
FBH
70static 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);
9432a9ba
FBH
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
d02a40af
PB
94 /*
95 * Save FPU state to signal context. Signal handler
96 * will "inherit" current FPU state.
97 */
98 err |= protected_save_fp_context(sc);
9432a9ba 99
9432a9ba
FBH
100 return err;
101}
102
103static int restore_sigcontext32(struct pt_regs *regs,
104 struct sigcontext32 __user *sc)
105{
9432a9ba
FBH
106 int err = 0;
107 s32 treg;
108 int i;
109
110 /* Always make any pending restarted system calls return -EINTR */
f56141e3 111 current->restart_block.fn = do_no_restart_syscall;
9432a9ba
FBH
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
d02a40af 129 return err ?: protected_restore_fp_context(sc);
9432a9ba
FBH
130}
131
1da177e4
LT
132/*
133 * Atomically swap in the new signal mask, and wait for a signal.
134 */
135
1910f4ab 136asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
1da177e4 137{
1910f4ab 138 return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
1da177e4
LT
139}
140
aa584802
AV
141SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
142 struct compat_sigaction __user *, oact)
1da177e4
LT
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;
77c728c2 150 s32 handler;
1da177e4
LT
151
152 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
153 return -EFAULT;
77c728c2 154 err |= __get_user(handler, &act->sa_handler);
9bbf28a3 155 new_ka.sa.sa_handler = (void __user *)(s64)handler;
1da177e4
LT
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)))
6254944f 168 return -EFAULT;
1da177e4
LT
169 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
170 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
70342287 171 &oact->sa_handler);
1da177e4 172 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
6254944f
MM
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)
1da177e4
LT
177 return -EFAULT;
178 }
179
180 return ret;
181}
182
ce395960 183int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
1da177e4
LT
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) {
a982099c
RB
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;
1da177e4
LT
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:
5665a0ac 218 err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
1da177e4
LT
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
5d9a76cd
TB
235int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
236{
5d9a76cd
TB
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
f90080a0 245asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
1da177e4 246{
dd02f06a 247 struct sigframe32 __user *frame;
1da177e4 248 sigset_t blocked;
c6a2f467 249 int sig;
1da177e4 250
dd02f06a 251 frame = (struct sigframe32 __user *) regs.regs[29];
1da177e4
LT
252 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
253 goto badframe;
431dc804 254 if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
1da177e4
LT
255 goto badframe;
256
8598f3cd 257 set_current_blocked(&blocked);
1da177e4 258
c6a2f467
AN
259 sig = restore_sigcontext32(&regs, &frame->sf_sc);
260 if (sig < 0)
1da177e4 261 goto badframe;
c6a2f467
AN
262 else if (sig)
263 force_sig(sig, current);
1da177e4
LT
264
265 /*
266 * Don't let your children do this ...
267 */
1da177e4
LT
268 __asm__ __volatile__(
269 "move\t$29, %0\n\t"
270 "j\tsyscall_exit"
271 :/* no outputs */
272 :"r" (&regs));
273 /* Unreached */
274
275badframe:
276 force_sig(SIGSEGV, current);
277}
278
f90080a0 279asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
1da177e4 280{
9bbf28a3 281 struct rt_sigframe32 __user *frame;
1da177e4 282 sigset_t set;
c6a2f467 283 int sig;
1da177e4 284
9bbf28a3 285 frame = (struct rt_sigframe32 __user *) regs.regs[29];
1da177e4
LT
286 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
287 goto badframe;
431dc804 288 if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
1da177e4
LT
289 goto badframe;
290
8598f3cd 291 set_current_blocked(&set);
1da177e4 292
c6a2f467
AN
293 sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
294 if (sig < 0)
1da177e4 295 goto badframe;
c6a2f467
AN
296 else if (sig)
297 force_sig(sig, current);
1da177e4 298
ea536ad4 299 if (compat_restore_altstack(&frame->rs_uc.uc_stack))
1da177e4 300 goto badframe;
1da177e4
LT
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
312badframe:
313 force_sig(SIGSEGV, current);
314}
315
81d103bf
RW
316static int setup_frame_32(void *sig_return, struct ksignal *ksig,
317 struct pt_regs *regs, sigset_t *set)
1da177e4 318{
dd02f06a 319 struct sigframe32 __user *frame;
1da177e4
LT
320 int err = 0;
321
7c4f5635 322 frame = get_sigframe(ksig, regs, sizeof(*frame));
1da177e4 323 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
81d103bf 324 return -EFAULT;
1da177e4 325
1da177e4 326 err |= setup_sigcontext32(regs, &frame->sf_sc);
431dc804
RB
327 err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
328
1da177e4 329 if (err)
81d103bf 330 return -EFAULT;
1da177e4
LT
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 */
81d103bf 342 regs->regs[ 4] = ksig->sig;
1da177e4
LT
343 regs->regs[ 5] = 0;
344 regs->regs[ 6] = (unsigned long) &frame->sf_sc;
345 regs->regs[29] = (unsigned long) frame;
d814c28c 346 regs->regs[31] = (unsigned long) sig_return;
81d103bf 347 regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
1da177e4 348
722bb63d 349 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
1da177e4 350 current->comm, current->pid,
722bb63d
FBH
351 frame, regs->cp0_epc, regs->regs[31]);
352
7b3e2fc8 353 return 0;
1da177e4
LT
354}
355
81d103bf
RW
356static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig,
357 struct pt_regs *regs, sigset_t *set)
1da177e4 358{
9bbf28a3 359 struct rt_sigframe32 __user *frame;
1da177e4 360 int err = 0;
1da177e4 361
7c4f5635 362 frame = get_sigframe(ksig, regs, sizeof(*frame));
1da177e4 363 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
81d103bf 364 return -EFAULT;
1da177e4 365
1da177e4 366 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
81d103bf 367 err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
1da177e4 368
70342287 369 /* Create the ucontext. */
1da177e4
LT
370 err |= __put_user(0, &frame->rs_uc.uc_flags);
371 err |= __put_user(0, &frame->rs_uc.uc_link);
ea536ad4 372 err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
1da177e4 373 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
431dc804 374 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
1da177e4
LT
375
376 if (err)
81d103bf 377 return -EFAULT;
1da177e4
LT
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 */
81d103bf 389 regs->regs[ 4] = ksig->sig;
1da177e4
LT
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;
d814c28c 393 regs->regs[31] = (unsigned long) sig_return;
81d103bf 394 regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
1da177e4 395
722bb63d 396 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
1da177e4 397 current->comm, current->pid,
722bb63d
FBH
398 frame, regs->cp0_epc, regs->regs[31]);
399
7b3e2fc8 400 return 0;
1da177e4
LT
401}
402
151fd6ac
RB
403/*
404 * o32 compatibility on 64-bit kernels, without DSP ASE
405 */
406struct mips_abi mips_abi_32 = {
407 .setup_frame = setup_frame_32,
70342287 408 .setup_rt_frame = setup_rt_frame_32,
77856100
PB
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),
ebb5e78c
AS
414
415 .vdso = &vdso_image_o32,
151fd6ac 416};