• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/mips/kernel/
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	sigsetsize = regs.regs[5];
312	if (sigsetsize != sizeof(compat_sigset_t))
313		return -EINVAL;
314
315	uset = (compat_sigset_t __user *) regs.regs[4];
316	if (get_sigset(&newset, uset))
317		return -EFAULT;
318	sigdelsetmask(&newset, ~_BLOCKABLE);
319
320	spin_lock_irq(&current->sighand->siglock);
321	current->saved_sigmask = current->blocked;
322	current->blocked = newset;
323	recalc_sigpending();
324	spin_unlock_irq(&current->sighand->siglock);
325
326	current->state = TASK_INTERRUPTIBLE;
327	schedule();
328	set_thread_flag(TIF_RESTORE_SIGMASK);
329	return -ERESTARTNOHAND;
330}
331
332SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
333	struct sigaction32 __user *, oact)
334{
335	struct k_sigaction new_ka, old_ka;
336	int ret;
337	int err = 0;
338
339	if (act) {
340		old_sigset_t mask;
341		s32 handler;
342
343		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
344			return -EFAULT;
345		err |= __get_user(handler, &act->sa_handler);
346		new_ka.sa.sa_handler = (void __user *)(s64)handler;
347		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
348		err |= __get_user(mask, &act->sa_mask.sig[0]);
349		if (err)
350			return -EFAULT;
351
352		siginitset(&new_ka.sa.sa_mask, mask);
353	}
354
355	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
356
357	if (!ret && oact) {
358		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
359			return -EFAULT;
360		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
361		err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
362		                  &oact->sa_handler);
363		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
364		err |= __put_user(0, &oact->sa_mask.sig[1]);
365		err |= __put_user(0, &oact->sa_mask.sig[2]);
366		err |= __put_user(0, &oact->sa_mask.sig[3]);
367		if (err)
368			return -EFAULT;
369	}
370
371	return ret;
372}
373
374asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
375{
376	const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
377	stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
378	unsigned long usp = regs.regs[29];
379	stack_t kss, koss;
380	int ret, err = 0;
381	mm_segment_t old_fs = get_fs();
382	s32 sp;
383
384	if (uss) {
385		if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
386			return -EFAULT;
387		err |= __get_user(sp, &uss->ss_sp);
388		kss.ss_sp = (void __user *) (long) sp;
389		err |= __get_user(kss.ss_size, &uss->ss_size);
390		err |= __get_user(kss.ss_flags, &uss->ss_flags);
391		if (err)
392			return -EFAULT;
393	}
394
395	set_fs(KERNEL_DS);
396	ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
397			     uoss ? (stack_t __user *)&koss : NULL, usp);
398	set_fs(old_fs);
399
400	if (!ret && uoss) {
401		if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
402			return -EFAULT;
403		sp = (int) (unsigned long) koss.ss_sp;
404		err |= __put_user(sp, &uoss->ss_sp);
405		err |= __put_user(koss.ss_size, &uoss->ss_size);
406		err |= __put_user(koss.ss_flags, &uoss->ss_flags);
407		if (err)
408			return -EFAULT;
409	}
410	return ret;
411}
412
413int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
414{
415	int err;
416
417	if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
418		return -EFAULT;
419
420	/* If you change siginfo_t structure, please be sure
421	   this code is fixed accordingly.
422	   It should never copy any pad contained in the structure
423	   to avoid security leaks, but must copy the generic
424	   3 ints plus the relevant union member.
425	   This routine must convert siginfo from 64bit to 32bit as well
426	   at the same time.  */
427	err = __put_user(from->si_signo, &to->si_signo);
428	err |= __put_user(from->si_errno, &to->si_errno);
429	err |= __put_user((short)from->si_code, &to->si_code);
430	if (from->si_code < 0)
431		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
432	else {
433		switch (from->si_code >> 16) {
434		case __SI_TIMER >> 16:
435			err |= __put_user(from->si_tid, &to->si_tid);
436			err |= __put_user(from->si_overrun, &to->si_overrun);
437			err |= __put_user(from->si_int, &to->si_int);
438			break;
439		case __SI_CHLD >> 16:
440			err |= __put_user(from->si_utime, &to->si_utime);
441			err |= __put_user(from->si_stime, &to->si_stime);
442			err |= __put_user(from->si_status, &to->si_status);
443		default:
444			err |= __put_user(from->si_pid, &to->si_pid);
445			err |= __put_user(from->si_uid, &to->si_uid);
446			break;
447		case __SI_FAULT >> 16:
448			err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
449			break;
450		case __SI_POLL >> 16:
451			err |= __put_user(from->si_band, &to->si_band);
452			err |= __put_user(from->si_fd, &to->si_fd);
453			break;
454		case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
455		case __SI_MESGQ >> 16:
456			err |= __put_user(from->si_pid, &to->si_pid);
457			err |= __put_user(from->si_uid, &to->si_uid);
458			err |= __put_user(from->si_int, &to->si_int);
459			break;
460		}
461	}
462	return err;
463}
464
465int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
466{
467	memset(to, 0, sizeof *to);
468
469	if (copy_from_user(to, from, 3*sizeof(int)) ||
470	    copy_from_user(to->_sifields._pad,
471			   from->_sifields._pad, SI_PAD_SIZE32))
472		return -EFAULT;
473
474	return 0;
475}
476
477asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
478{
479	struct sigframe32 __user *frame;
480	sigset_t blocked;
481	int sig;
482
483	frame = (struct sigframe32 __user *) regs.regs[29];
484	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
485		goto badframe;
486	if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
487		goto badframe;
488
489	sigdelsetmask(&blocked, ~_BLOCKABLE);
490	spin_lock_irq(&current->sighand->siglock);
491	current->blocked = blocked;
492	recalc_sigpending();
493	spin_unlock_irq(&current->sighand->siglock);
494
495	sig = restore_sigcontext32(&regs, &frame->sf_sc);
496	if (sig < 0)
497		goto badframe;
498	else if (sig)
499		force_sig(sig, current);
500
501	/*
502	 * Don't let your children do this ...
503	 */
504	__asm__ __volatile__(
505		"move\t$29, %0\n\t"
506		"j\tsyscall_exit"
507		:/* no outputs */
508		:"r" (&regs));
509	/* Unreached */
510
511badframe:
512	force_sig(SIGSEGV, current);
513}
514
515asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
516{
517	struct rt_sigframe32 __user *frame;
518	mm_segment_t old_fs;
519	sigset_t set;
520	stack_t st;
521	s32 sp;
522	int sig;
523
524	frame = (struct rt_sigframe32 __user *) regs.regs[29];
525	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
526		goto badframe;
527	if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
528		goto badframe;
529
530	sigdelsetmask(&set, ~_BLOCKABLE);
531	spin_lock_irq(&current->sighand->siglock);
532	current->blocked = set;
533	recalc_sigpending();
534	spin_unlock_irq(&current->sighand->siglock);
535
536	sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
537	if (sig < 0)
538		goto badframe;
539	else if (sig)
540		force_sig(sig, current);
541
542	/* The ucontext contains a stack32_t, so we must convert!  */
543	if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
544		goto badframe;
545	st.ss_sp = (void __user *)(long) sp;
546	if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
547		goto badframe;
548	if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
549		goto badframe;
550
551	/* It is more difficult to avoid calling this function than to
552	   call it and ignore errors.  */
553	old_fs = get_fs();
554	set_fs(KERNEL_DS);
555	do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
556	set_fs(old_fs);
557
558	/*
559	 * Don't let your children do this ...
560	 */
561	__asm__ __volatile__(
562		"move\t$29, %0\n\t"
563		"j\tsyscall_exit"
564		:/* no outputs */
565		:"r" (&regs));
566	/* Unreached */
567
568badframe:
569	force_sig(SIGSEGV, current);
570}
571
572static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
573			  struct pt_regs *regs, int signr, sigset_t *set)
574{
575	struct sigframe32 __user *frame;
576	int err = 0;
577
578	frame = get_sigframe(ka, regs, sizeof(*frame));
579	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
580		goto give_sigsegv;
581
582	err |= setup_sigcontext32(regs, &frame->sf_sc);
583	err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
584
585	if (err)
586		goto give_sigsegv;
587
588	/*
589	 * Arguments to signal handler:
590	 *
591	 *   a0 = signal number
592	 *   a1 = 0 (should be cause)
593	 *   a2 = pointer to struct sigcontext
594	 *
595	 * $25 and c0_epc point to the signal handler, $29 points to the
596	 * struct sigframe.
597	 */
598	regs->regs[ 4] = signr;
599	regs->regs[ 5] = 0;
600	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
601	regs->regs[29] = (unsigned long) frame;
602	regs->regs[31] = (unsigned long) sig_return;
603	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
604
605	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
606	       current->comm, current->pid,
607	       frame, regs->cp0_epc, regs->regs[31]);
608
609	return 0;
610
611give_sigsegv:
612	force_sigsegv(signr, current);
613	return -EFAULT;
614}
615
616static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
617			     struct pt_regs *regs, int signr, sigset_t *set,
618			     siginfo_t *info)
619{
620	struct rt_sigframe32 __user *frame;
621	int err = 0;
622	s32 sp;
623
624	frame = get_sigframe(ka, regs, sizeof(*frame));
625	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
626		goto give_sigsegv;
627
628	/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
629	err |= copy_siginfo_to_user32(&frame->rs_info, info);
630
631	/* Create the ucontext.  */
632	err |= __put_user(0, &frame->rs_uc.uc_flags);
633	err |= __put_user(0, &frame->rs_uc.uc_link);
634	sp = (int) (long) current->sas_ss_sp;
635	err |= __put_user(sp,
636	                  &frame->rs_uc.uc_stack.ss_sp);
637	err |= __put_user(sas_ss_flags(regs->regs[29]),
638	                  &frame->rs_uc.uc_stack.ss_flags);
639	err |= __put_user(current->sas_ss_size,
640	                  &frame->rs_uc.uc_stack.ss_size);
641	err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
642	err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
643
644	if (err)
645		goto give_sigsegv;
646
647	/*
648	 * Arguments to signal handler:
649	 *
650	 *   a0 = signal number
651	 *   a1 = 0 (should be cause)
652	 *   a2 = pointer to ucontext
653	 *
654	 * $25 and c0_epc point to the signal handler, $29 points to
655	 * the struct rt_sigframe32.
656	 */
657	regs->regs[ 4] = signr;
658	regs->regs[ 5] = (unsigned long) &frame->rs_info;
659	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
660	regs->regs[29] = (unsigned long) frame;
661	regs->regs[31] = (unsigned long) sig_return;
662	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
663
664	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
665	       current->comm, current->pid,
666	       frame, regs->cp0_epc, regs->regs[31]);
667
668	return 0;
669
670give_sigsegv:
671	force_sigsegv(signr, current);
672	return -EFAULT;
673}
674
675/*
676 * o32 compatibility on 64-bit kernels, without DSP ASE
677 */
678struct mips_abi mips_abi_32 = {
679	.setup_frame	= setup_frame_32,
680	.signal_return_offset =
681		offsetof(struct mips_vdso, o32_signal_trampoline),
682	.setup_rt_frame	= setup_rt_frame_32,
683	.rt_signal_return_offset =
684		offsetof(struct mips_vdso, o32_rt_signal_trampoline),
685	.restart	= __NR_O32_restart_syscall
686};
687
688SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
689	const struct sigaction32 __user *, act,
690	struct sigaction32 __user *, oact, unsigned int, sigsetsize)
691{
692	struct k_sigaction new_sa, old_sa;
693	int ret = -EINVAL;
694
695	if (sigsetsize != sizeof(sigset_t))
696		goto out;
697
698	if (act) {
699		s32 handler;
700		int err = 0;
701
702		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
703			return -EFAULT;
704		err |= __get_user(handler, &act->sa_handler);
705		new_sa.sa.sa_handler = (void __user *)(s64)handler;
706		err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
707		err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
708		if (err)
709			return -EFAULT;
710	}
711
712	ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
713
714	if (!ret && oact) {
715		int err = 0;
716
717		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
718			return -EFAULT;
719
720		err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
721		                   &oact->sa_handler);
722		err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
723		err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
724		if (err)
725			return -EFAULT;
726	}
727out:
728	return ret;
729}
730
731SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set,
732	compat_sigset_t __user *, oset, unsigned int, sigsetsize)
733{
734	sigset_t old_set, new_set;
735	int ret;
736	mm_segment_t old_fs = get_fs();
737
738	if (set && get_sigset(&new_set, set))
739		return -EFAULT;
740
741	set_fs(KERNEL_DS);
742	ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
743				 oset ? (sigset_t __user *)&old_set : NULL,
744				 sigsetsize);
745	set_fs(old_fs);
746
747	if (!ret && oset && put_sigset(&old_set, oset))
748		return -EFAULT;
749
750	return ret;
751}
752
753SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset,
754	unsigned int, sigsetsize)
755{
756	int ret;
757	sigset_t set;
758	mm_segment_t old_fs = get_fs();
759
760	set_fs(KERNEL_DS);
761	ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
762	set_fs(old_fs);
763
764	if (!ret && put_sigset(&set, uset))
765		return -EFAULT;
766
767	return ret;
768}
769
770SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig,
771	compat_siginfo_t __user *, uinfo)
772{
773	siginfo_t info;
774	int ret;
775	mm_segment_t old_fs = get_fs();
776
777	if (copy_from_user(&info, uinfo, 3*sizeof(int)) ||
778	    copy_from_user(info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
779		return -EFAULT;
780	set_fs(KERNEL_DS);
781	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
782	set_fs(old_fs);
783	return ret;
784}
785
786SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid,
787	     compat_siginfo_t __user *, uinfo, int, options,
788	     struct compat_rusage __user *, uru)
789{
790	siginfo_t info;
791	struct rusage ru;
792	long ret;
793	mm_segment_t old_fs = get_fs();
794
795	info.si_signo = 0;
796	set_fs(KERNEL_DS);
797	ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
798			 uru ? (struct rusage __user *) &ru : NULL);
799	set_fs(old_fs);
800
801	if (ret < 0 || info.si_signo == 0)
802		return ret;
803
804	if (uru && (ret = put_compat_rusage(&ru, uru)))
805		return ret;
806
807	BUG_ON(info.si_code & __SI_MASK);
808	info.si_code |= __SI_CHLD;
809	return copy_siginfo_to_user32(uinfo, &info);
810}
811
812static int signal32_init(void)
813{
814	if (cpu_has_fpu) {
815		save_fp_context32 = _save_fp_context32;
816		restore_fp_context32 = _restore_fp_context32;
817	} else {
818		save_fp_context32 = fpu_emulator_save_context32;
819		restore_fp_context32 = fpu_emulator_restore_context32;
820	}
821
822	return 0;
823}
824
825arch_initcall(signal32_init);
826