Linux Audio

Check our new training course

Loading...
v4.17
 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/kernel.h>
14#include <linux/signal.h>
15#include <linux/syscalls.h>
 
 
 
 
 
 
16
17#include <asm/compat.h>
 
18#include <asm/compat-signal.h>
19#include <linux/uaccess.h>
20#include <asm/unistd.h>
 
 
 
 
 
 
21
22#include "signal-common.h"
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24/* 32-bit compatibility types */
25
26typedef unsigned int __sighandler32_t;
27typedef void (*vfptr_t)(void);
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29/*
30 * Atomically swap in the new signal mask, and wait for a signal.
31 */
32
33asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
34{
35	return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36}
37
38SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
39	struct compat_sigaction __user *, oact)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40{
41	struct k_sigaction new_ka, old_ka;
42	int ret;
43	int err = 0;
44
45	if (act) {
46		old_sigset_t mask;
47		s32 handler;
48
49		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
50			return -EFAULT;
51		err |= __get_user(handler, &act->sa_handler);
52		new_ka.sa.sa_handler = (void __user *)(s64)handler;
53		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
54		err |= __get_user(mask, &act->sa_mask.sig[0]);
55		if (err)
56			return -EFAULT;
57
58		siginitset(&new_ka.sa.sa_mask, mask);
59	}
60
61	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
62
63	if (!ret && oact) {
64		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
65			return -EFAULT;
66		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
67		err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
68				  &oact->sa_handler);
69		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
70		err |= __put_user(0, &oact->sa_mask.sig[1]);
71		err |= __put_user(0, &oact->sa_mask.sig[2]);
72		err |= __put_user(0, &oact->sa_mask.sig[3]);
73		if (err)
74			return -EFAULT;
75	}
76
77	return ret;
78}
v3.1
  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/system.h>
 33#include <asm/fpu.h>
 34#include <asm/war.h>
 35#include <asm/vdso.h>
 36
 37#include "signal-common.h"
 38
 39static int (*save_fp_context32)(struct sigcontext32 __user *sc);
 40static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
 41
 42extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
 43extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
 44
 45extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
 46extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
 47
 48/*
 49 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
 50 */
 51#define __NR_O32_restart_syscall        4253
 52
 53/* 32-bit compatibility types */
 54
 55typedef unsigned int __sighandler32_t;
 56typedef void (*vfptr_t)(void);
 57
 58struct sigaction32 {
 59	unsigned int		sa_flags;
 60	__sighandler32_t	sa_handler;
 61	compat_sigset_t		sa_mask;
 62};
 63
 64/* IRIX compatible stack_t  */
 65typedef struct sigaltstack32 {
 66	s32 ss_sp;
 67	compat_size_t ss_size;
 68	int ss_flags;
 69} stack32_t;
 70
 71struct ucontext32 {
 72	u32                 uc_flags;
 73	s32                 uc_link;
 74	stack32_t           uc_stack;
 75	struct sigcontext32 uc_mcontext;
 76	compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 77};
 78
 79struct sigframe32 {
 80	u32 sf_ass[4];		/* argument save space for o32 */
 81	u32 sf_pad[2];		/* Was: signal trampoline */
 82	struct sigcontext32 sf_sc;
 83	compat_sigset_t sf_mask;
 84};
 85
 86struct rt_sigframe32 {
 87	u32 rs_ass[4];			/* argument save space for o32 */
 88	u32 rs_pad[2];			/* Was: signal trampoline */
 89	compat_siginfo_t rs_info;
 90	struct ucontext32 rs_uc;
 91};
 92
 93/*
 94 * sigcontext handlers
 95 */
 96static int protected_save_fp_context32(struct sigcontext32 __user *sc)
 97{
 98	int err;
 99	while (1) {
100		lock_fpu_owner();
101		own_fpu_inatomic(1);
102		err = save_fp_context32(sc); /* this might fail */
103		unlock_fpu_owner();
104		if (likely(!err))
105			break;
106		/* touch the sigcontext and try again */
107		err = __put_user(0, &sc->sc_fpregs[0]) |
108			__put_user(0, &sc->sc_fpregs[31]) |
109			__put_user(0, &sc->sc_fpc_csr);
110		if (err)
111			break;	/* really bad sigcontext */
112	}
113	return err;
114}
115
116static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
117{
118	int err, tmp __maybe_unused;
119	while (1) {
120		lock_fpu_owner();
121		own_fpu_inatomic(0);
122		err = restore_fp_context32(sc); /* this might fail */
123		unlock_fpu_owner();
124		if (likely(!err))
125			break;
126		/* touch the sigcontext and try again */
127		err = __get_user(tmp, &sc->sc_fpregs[0]) |
128			__get_user(tmp, &sc->sc_fpregs[31]) |
129			__get_user(tmp, &sc->sc_fpc_csr);
130		if (err)
131			break;	/* really bad sigcontext */
132	}
133	return err;
134}
135
136static int setup_sigcontext32(struct pt_regs *regs,
137			      struct sigcontext32 __user *sc)
138{
139	int err = 0;
140	int i;
141	u32 used_math;
142
143	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
144
145	err |= __put_user(0, &sc->sc_regs[0]);
146	for (i = 1; i < 32; i++)
147		err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
148
149	err |= __put_user(regs->hi, &sc->sc_mdhi);
150	err |= __put_user(regs->lo, &sc->sc_mdlo);
151	if (cpu_has_dsp) {
152		err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
153		err |= __put_user(mfhi1(), &sc->sc_hi1);
154		err |= __put_user(mflo1(), &sc->sc_lo1);
155		err |= __put_user(mfhi2(), &sc->sc_hi2);
156		err |= __put_user(mflo2(), &sc->sc_lo2);
157		err |= __put_user(mfhi3(), &sc->sc_hi3);
158		err |= __put_user(mflo3(), &sc->sc_lo3);
159	}
160
161	used_math = !!used_math();
162	err |= __put_user(used_math, &sc->sc_used_math);
163
164	if (used_math) {
165		/*
166		 * Save FPU state to signal context.  Signal handler
167		 * will "inherit" current FPU state.
168		 */
169		err |= protected_save_fp_context32(sc);
170	}
171	return err;
172}
173
174static int
175check_and_restore_fp_context32(struct sigcontext32 __user *sc)
176{
177	int err, sig;
178
179	err = sig = fpcsr_pending(&sc->sc_fpc_csr);
180	if (err > 0)
181		err = 0;
182	err |= protected_restore_fp_context32(sc);
183	return err ?: sig;
184}
185
186static int restore_sigcontext32(struct pt_regs *regs,
187				struct sigcontext32 __user *sc)
188{
189	u32 used_math;
190	int err = 0;
191	s32 treg;
192	int i;
193
194	/* Always make any pending restarted system calls return -EINTR */
195	current_thread_info()->restart_block.fn = do_no_restart_syscall;
196
197	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
198	err |= __get_user(regs->hi, &sc->sc_mdhi);
199	err |= __get_user(regs->lo, &sc->sc_mdlo);
200	if (cpu_has_dsp) {
201		err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
202		err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
203		err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
204		err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
205		err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
206		err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
207		err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
208	}
209
210	for (i = 1; i < 32; i++)
211		err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
212
213	err |= __get_user(used_math, &sc->sc_used_math);
214	conditional_used_math(used_math);
215
216	if (used_math) {
217		/* restore fpu context if we have used it before */
218		if (!err)
219			err = check_and_restore_fp_context32(sc);
220	} else {
221		/* signal handler may have used FPU.  Give it up. */
222		lose_fpu(0);
223	}
224
225	return err;
226}
227
228/*
229 *
230 */
231extern void __put_sigset_unknown_nsig(void);
232extern void __get_sigset_unknown_nsig(void);
233
234static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
235{
236	int err = 0;
237
238	if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
239		return -EFAULT;
240
241	switch (_NSIG_WORDS) {
242	default:
243		__put_sigset_unknown_nsig();
244	case 2:
245		err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
246		err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
247	case 1:
248		err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
249		err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
250	}
251
252	return err;
253}
254
255static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
256{
257	int err = 0;
258	unsigned long sig[4];
259
260	if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
261		return -EFAULT;
262
263	switch (_NSIG_WORDS) {
264	default:
265		__get_sigset_unknown_nsig();
266	case 2:
267		err |= __get_user(sig[3], &ubuf->sig[3]);
268		err |= __get_user(sig[2], &ubuf->sig[2]);
269		kbuf->sig[1] = sig[2] | (sig[3] << 32);
270	case 1:
271		err |= __get_user(sig[1], &ubuf->sig[1]);
272		err |= __get_user(sig[0], &ubuf->sig[0]);
273		kbuf->sig[0] = sig[0] | (sig[1] << 32);
274	}
275
276	return err;
277}
278
279/*
280 * Atomically swap in the new signal mask, and wait for a signal.
281 */
282
283asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
284{
285	compat_sigset_t __user *uset;
286	sigset_t newset;
287
288	uset = (compat_sigset_t __user *) regs.regs[4];
289	if (get_sigset(&newset, uset))
290		return -EFAULT;
291	sigdelsetmask(&newset, ~_BLOCKABLE);
292
293	spin_lock_irq(&current->sighand->siglock);
294	current->saved_sigmask = current->blocked;
295	current->blocked = newset;
296	recalc_sigpending();
297	spin_unlock_irq(&current->sighand->siglock);
298
299	current->state = TASK_INTERRUPTIBLE;
300	schedule();
301	set_thread_flag(TIF_RESTORE_SIGMASK);
302	return -ERESTARTNOHAND;
303}
304
305asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
306{
307	compat_sigset_t __user *uset;
308	sigset_t newset;
309	size_t sigsetsize;
310
311	/* XXX Don't preclude handling different sized sigset_t's.  */
312	sigsetsize = regs.regs[5];
313	if (sigsetsize != sizeof(compat_sigset_t))
314		return -EINVAL;
315
316	uset = (compat_sigset_t __user *) regs.regs[4];
317	if (get_sigset(&newset, uset))
318		return -EFAULT;
319	sigdelsetmask(&newset, ~_BLOCKABLE);
320
321	spin_lock_irq(&current->sighand->siglock);
322	current->saved_sigmask = current->blocked;
323	current->blocked = newset;
324	recalc_sigpending();
325	spin_unlock_irq(&current->sighand->siglock);
326
327	current->state = TASK_INTERRUPTIBLE;
328	schedule();
329	set_thread_flag(TIF_RESTORE_SIGMASK);
330	return -ERESTARTNOHAND;
331}
332
333SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
334	struct sigaction32 __user *, oact)
335{
336	struct k_sigaction new_ka, old_ka;
337	int ret;
338	int err = 0;
339
340	if (act) {
341		old_sigset_t mask;
342		s32 handler;
343
344		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
345			return -EFAULT;
346		err |= __get_user(handler, &act->sa_handler);
347		new_ka.sa.sa_handler = (void __user *)(s64)handler;
348		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
349		err |= __get_user(mask, &act->sa_mask.sig[0]);
350		if (err)
351			return -EFAULT;
352
353		siginitset(&new_ka.sa.sa_mask, mask);
354	}
355
356	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
357
358	if (!ret && oact) {
359		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
360			return -EFAULT;
361		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
362		err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
363		                  &oact->sa_handler);
364		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
365		err |= __put_user(0, &oact->sa_mask.sig[1]);
366		err |= __put_user(0, &oact->sa_mask.sig[2]);
367		err |= __put_user(0, &oact->sa_mask.sig[3]);
368		if (err)
369			return -EFAULT;
370	}
371
372	return ret;
373}
374
375asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
376{
377	const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
378	stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
379	unsigned long usp = regs.regs[29];
380	stack_t kss, koss;
381	int ret, err = 0;
382	mm_segment_t old_fs = get_fs();
383	s32 sp;
384
385	if (uss) {
386		if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
387			return -EFAULT;
388		err |= __get_user(sp, &uss->ss_sp);
389		kss.ss_sp = (void __user *) (long) sp;
390		err |= __get_user(kss.ss_size, &uss->ss_size);
391		err |= __get_user(kss.ss_flags, &uss->ss_flags);
392		if (err)
393			return -EFAULT;
394	}
395
396	set_fs(KERNEL_DS);
397	ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
398			     uoss ? (stack_t __user *)&koss : NULL, usp);
399	set_fs(old_fs);
400
401	if (!ret && uoss) {
402		if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
403			return -EFAULT;
404		sp = (int) (unsigned long) koss.ss_sp;
405		err |= __put_user(sp, &uoss->ss_sp);
406		err |= __put_user(koss.ss_size, &uoss->ss_size);
407		err |= __put_user(koss.ss_flags, &uoss->ss_flags);
408		if (err)
409			return -EFAULT;
410	}
411	return ret;
412}
413
414int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
415{
416	int err;
417
418	if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
419		return -EFAULT;
420
421	/* If you change siginfo_t structure, please be sure
422	   this code is fixed accordingly.
423	   It should never copy any pad contained in the structure
424	   to avoid security leaks, but must copy the generic
425	   3 ints plus the relevant union member.
426	   This routine must convert siginfo from 64bit to 32bit as well
427	   at the same time.  */
428	err = __put_user(from->si_signo, &to->si_signo);
429	err |= __put_user(from->si_errno, &to->si_errno);
430	err |= __put_user((short)from->si_code, &to->si_code);
431	if (from->si_code < 0)
432		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
433	else {
434		switch (from->si_code >> 16) {
435		case __SI_TIMER >> 16:
436			err |= __put_user(from->si_tid, &to->si_tid);
437			err |= __put_user(from->si_overrun, &to->si_overrun);
438			err |= __put_user(from->si_int, &to->si_int);
439			break;
440		case __SI_CHLD >> 16:
441			err |= __put_user(from->si_utime, &to->si_utime);
442			err |= __put_user(from->si_stime, &to->si_stime);
443			err |= __put_user(from->si_status, &to->si_status);
444		default:
445			err |= __put_user(from->si_pid, &to->si_pid);
446			err |= __put_user(from->si_uid, &to->si_uid);
447			break;
448		case __SI_FAULT >> 16:
449			err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
450			break;
451		case __SI_POLL >> 16:
452			err |= __put_user(from->si_band, &to->si_band);
453			err |= __put_user(from->si_fd, &to->si_fd);
454			break;
455		case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
456		case __SI_MESGQ >> 16:
457			err |= __put_user(from->si_pid, &to->si_pid);
458			err |= __put_user(from->si_uid, &to->si_uid);
459			err |= __put_user(from->si_int, &to->si_int);
460			break;
461		}
462	}
463	return err;
464}
465
466int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
467{
468	memset(to, 0, sizeof *to);
469
470	if (copy_from_user(to, from, 3*sizeof(int)) ||
471	    copy_from_user(to->_sifields._pad,
472			   from->_sifields._pad, SI_PAD_SIZE32))
473		return -EFAULT;
474
475	return 0;
476}
477
478asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
479{
480	struct sigframe32 __user *frame;
481	sigset_t blocked;
482	int sig;
483
484	frame = (struct sigframe32 __user *) regs.regs[29];
485	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
486		goto badframe;
487	if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
488		goto badframe;
489
490	sigdelsetmask(&blocked, ~_BLOCKABLE);
491	spin_lock_irq(&current->sighand->siglock);
492	current->blocked = blocked;
493	recalc_sigpending();
494	spin_unlock_irq(&current->sighand->siglock);
495
496	sig = restore_sigcontext32(&regs, &frame->sf_sc);
497	if (sig < 0)
498		goto badframe;
499	else if (sig)
500		force_sig(sig, current);
501
502	/*
503	 * Don't let your children do this ...
504	 */
505	__asm__ __volatile__(
506		"move\t$29, %0\n\t"
507		"j\tsyscall_exit"
508		:/* no outputs */
509		:"r" (&regs));
510	/* Unreached */
511
512badframe:
513	force_sig(SIGSEGV, current);
514}
515
516asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
517{
518	struct rt_sigframe32 __user *frame;
519	mm_segment_t old_fs;
520	sigset_t set;
521	stack_t st;
522	s32 sp;
523	int sig;
524
525	frame = (struct rt_sigframe32 __user *) regs.regs[29];
526	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
527		goto badframe;
528	if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
529		goto badframe;
530
531	sigdelsetmask(&set, ~_BLOCKABLE);
532	spin_lock_irq(&current->sighand->siglock);
533	current->blocked = set;
534	recalc_sigpending();
535	spin_unlock_irq(&current->sighand->siglock);
536
537	sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
538	if (sig < 0)
539		goto badframe;
540	else if (sig)
541		force_sig(sig, current);
542
543	/* The ucontext contains a stack32_t, so we must convert!  */
544	if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
545		goto badframe;
546	st.ss_sp = (void __user *)(long) sp;
547	if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
548		goto badframe;
549	if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
550		goto badframe;
551
552	/* It is more difficult to avoid calling this function than to
553	   call it and ignore errors.  */
554	old_fs = get_fs();
555	set_fs(KERNEL_DS);
556	do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
557	set_fs(old_fs);
558
559	/*
560	 * Don't let your children do this ...
561	 */
562	__asm__ __volatile__(
563		"move\t$29, %0\n\t"
564		"j\tsyscall_exit"
565		:/* no outputs */
566		:"r" (&regs));
567	/* Unreached */
568
569badframe:
570	force_sig(SIGSEGV, current);
571}
572
573static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
574			  struct pt_regs *regs, int signr, sigset_t *set)
575{
576	struct sigframe32 __user *frame;
577	int err = 0;
578
579	frame = get_sigframe(ka, regs, sizeof(*frame));
580	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
581		goto give_sigsegv;
582
583	err |= setup_sigcontext32(regs, &frame->sf_sc);
584	err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
585
586	if (err)
587		goto give_sigsegv;
588
589	/*
590	 * Arguments to signal handler:
591	 *
592	 *   a0 = signal number
593	 *   a1 = 0 (should be cause)
594	 *   a2 = pointer to struct sigcontext
595	 *
596	 * $25 and c0_epc point to the signal handler, $29 points to the
597	 * struct sigframe.
598	 */
599	regs->regs[ 4] = signr;
600	regs->regs[ 5] = 0;
601	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
602	regs->regs[29] = (unsigned long) frame;
603	regs->regs[31] = (unsigned long) sig_return;
604	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
605
606	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
607	       current->comm, current->pid,
608	       frame, regs->cp0_epc, regs->regs[31]);
609
610	return 0;
611
612give_sigsegv:
613	force_sigsegv(signr, current);
614	return -EFAULT;
615}
616
617static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
618			     struct pt_regs *regs, int signr, sigset_t *set,
619			     siginfo_t *info)
620{
621	struct rt_sigframe32 __user *frame;
622	int err = 0;
623	s32 sp;
624
625	frame = get_sigframe(ka, regs, sizeof(*frame));
626	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
627		goto give_sigsegv;
628
629	/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
630	err |= copy_siginfo_to_user32(&frame->rs_info, info);
631
632	/* Create the ucontext.  */
633	err |= __put_user(0, &frame->rs_uc.uc_flags);
634	err |= __put_user(0, &frame->rs_uc.uc_link);
635	sp = (int) (long) current->sas_ss_sp;
636	err |= __put_user(sp,
637	                  &frame->rs_uc.uc_stack.ss_sp);
638	err |= __put_user(sas_ss_flags(regs->regs[29]),
639	                  &frame->rs_uc.uc_stack.ss_flags);
640	err |= __put_user(current->sas_ss_size,
641	                  &frame->rs_uc.uc_stack.ss_size);
642	err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
643	err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
644
645	if (err)
646		goto give_sigsegv;
647
648	/*
649	 * Arguments to signal handler:
650	 *
651	 *   a0 = signal number
652	 *   a1 = 0 (should be cause)
653	 *   a2 = pointer to ucontext
654	 *
655	 * $25 and c0_epc point to the signal handler, $29 points to
656	 * the struct rt_sigframe32.
657	 */
658	regs->regs[ 4] = signr;
659	regs->regs[ 5] = (unsigned long) &frame->rs_info;
660	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
661	regs->regs[29] = (unsigned long) frame;
662	regs->regs[31] = (unsigned long) sig_return;
663	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
664
665	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
666	       current->comm, current->pid,
667	       frame, regs->cp0_epc, regs->regs[31]);
668
669	return 0;
670
671give_sigsegv:
672	force_sigsegv(signr, current);
673	return -EFAULT;
674}
675
676/*
677 * o32 compatibility on 64-bit kernels, without DSP ASE
678 */
679struct mips_abi mips_abi_32 = {
680	.setup_frame	= setup_frame_32,
681	.signal_return_offset =
682		offsetof(struct mips_vdso, o32_signal_trampoline),
683	.setup_rt_frame	= setup_rt_frame_32,
684	.rt_signal_return_offset =
685		offsetof(struct mips_vdso, o32_rt_signal_trampoline),
686	.restart	= __NR_O32_restart_syscall
687};
688
689SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
690	const struct sigaction32 __user *, act,
691	struct sigaction32 __user *, oact, unsigned int, sigsetsize)
692{
693	struct k_sigaction new_sa, old_sa;
694	int ret = -EINVAL;
695
696	/* XXX: Don't preclude handling different sized sigset_t's.  */
697	if (sigsetsize != sizeof(sigset_t))
698		goto out;
699
700	if (act) {
701		s32 handler;
702		int err = 0;
703
704		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
705			return -EFAULT;
706		err |= __get_user(handler, &act->sa_handler);
707		new_sa.sa.sa_handler = (void __user *)(s64)handler;
708		err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
709		err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
710		if (err)
711			return -EFAULT;
712	}
713
714	ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
715
716	if (!ret && oact) {
717		int err = 0;
718
719		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
720			return -EFAULT;
721
722		err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
723		                   &oact->sa_handler);
724		err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
725		err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
726		if (err)
727			return -EFAULT;
728	}
729out:
730	return ret;
731}
732
733SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set,
734	compat_sigset_t __user *, oset, unsigned int, sigsetsize)
735{
736	sigset_t old_set, new_set;
737	int ret;
738	mm_segment_t old_fs = get_fs();
739
740	if (set && get_sigset(&new_set, set))
741		return -EFAULT;
742
743	set_fs(KERNEL_DS);
744	ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
745				 oset ? (sigset_t __user *)&old_set : NULL,
746				 sigsetsize);
747	set_fs(old_fs);
748
749	if (!ret && oset && put_sigset(&old_set, oset))
750		return -EFAULT;
751
752	return ret;
753}
754
755SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset,
756	unsigned int, sigsetsize)
757{
758	int ret;
759	sigset_t set;
760	mm_segment_t old_fs = get_fs();
761
762	set_fs(KERNEL_DS);
763	ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
764	set_fs(old_fs);
765
766	if (!ret && put_sigset(&set, uset))
767		return -EFAULT;
768
769	return ret;
770}
771
772SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig,
773	compat_siginfo_t __user *, uinfo)
774{
775	siginfo_t info;
776	int ret;
777	mm_segment_t old_fs = get_fs();
778
779	if (copy_from_user(&info, uinfo, 3*sizeof(int)) ||
780	    copy_from_user(info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
781		return -EFAULT;
782	set_fs(KERNEL_DS);
783	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
784	set_fs(old_fs);
785	return ret;
786}
787
788SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid,
789	     compat_siginfo_t __user *, uinfo, int, options,
790	     struct compat_rusage __user *, uru)
791{
792	siginfo_t info;
793	struct rusage ru;
794	long ret;
795	mm_segment_t old_fs = get_fs();
796
797	info.si_signo = 0;
798	set_fs(KERNEL_DS);
799	ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
800			 uru ? (struct rusage __user *) &ru : NULL);
801	set_fs(old_fs);
802
803	if (ret < 0 || info.si_signo == 0)
804		return ret;
805
806	if (uru && (ret = put_compat_rusage(&ru, uru)))
807		return ret;
808
809	BUG_ON(info.si_code & __SI_MASK);
810	info.si_code |= __SI_CHLD;
811	return copy_siginfo_to_user32(uinfo, &info);
812}
813
814static int signal32_init(void)
815{
816	if (cpu_has_fpu) {
817		save_fp_context32 = _save_fp_context32;
818		restore_fp_context32 = _restore_fp_context32;
819	} else {
820		save_fp_context32 = fpu_emulator_save_context32;
821		restore_fp_context32 = fpu_emulator_restore_context32;
822	}
823
824	return 0;
825}
826
827arch_initcall(signal32_init);