Linux Audio

Check our new training course

Loading...
v5.4
 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/compat.h>
12#include <linux/compiler.h>
13#include <linux/errno.h>
 
14#include <linux/kernel.h>
15#include <linux/signal.h>
16#include <linux/syscalls.h>
 
 
 
 
 
 
17
 
 
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(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(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.15
  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/fpu.h>
 33#include <asm/msa.h>
 34#include <asm/war.h>
 35#include <asm/vdso.h>
 36#include <asm/dsp.h>
 37
 38#include "signal-common.h"
 39
 40static int (*save_fp_context32)(struct sigcontext32 __user *sc);
 41static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
 42
 43extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
 44extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
 45
 46extern asmlinkage int _save_msa_context32(struct sigcontext32 __user *sc);
 47extern asmlinkage int _restore_msa_context32(struct sigcontext32 __user *sc);
 48
 49/*
 50 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
 51 */
 52#define __NR_O32_restart_syscall	4253
 53
 54/* 32-bit compatibility types */
 55
 56typedef unsigned int __sighandler32_t;
 57typedef void (*vfptr_t)(void);
 58
 59struct ucontext32 {
 60	u32		    uc_flags;
 61	s32		    uc_link;
 62	compat_stack_t      uc_stack;
 63	struct sigcontext32 uc_mcontext;
 64	compat_sigset_t	    uc_sigmask;	  /* mask last for extensibility */
 65};
 66
 67struct sigframe32 {
 68	u32 sf_ass[4];		/* argument save space for o32 */
 69	u32 sf_pad[2];		/* Was: signal trampoline */
 70	struct sigcontext32 sf_sc;
 71	compat_sigset_t sf_mask;
 72};
 73
 74struct rt_sigframe32 {
 75	u32 rs_ass[4];			/* argument save space for o32 */
 76	u32 rs_pad[2];			/* Was: signal trampoline */
 77	compat_siginfo_t rs_info;
 78	struct ucontext32 rs_uc;
 79};
 80
 81/*
 82 * Thread saved context copy to/from a signal context presumed to be on the
 83 * user stack, and therefore accessed with appropriate macros from uaccess.h.
 84 */
 85static int copy_fp_to_sigcontext32(struct sigcontext32 __user *sc)
 86{
 87	int i;
 88	int err = 0;
 89	int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
 90
 91	for (i = 0; i < NUM_FPU_REGS; i += inc) {
 92		err |=
 93		    __put_user(get_fpr64(&current->thread.fpu.fpr[i], 0),
 94			       &sc->sc_fpregs[i]);
 95	}
 96	err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
 97
 98	return err;
 99}
100
101static int copy_fp_from_sigcontext32(struct sigcontext32 __user *sc)
102{
103	int i;
104	int err = 0;
105	int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
106	u64 fpr_val;
107
108	for (i = 0; i < NUM_FPU_REGS; i += inc) {
109		err |= __get_user(fpr_val, &sc->sc_fpregs[i]);
110		set_fpr64(&current->thread.fpu.fpr[i], 0, fpr_val);
111	}
112	err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
113
114	return err;
115}
116
117/*
118 * These functions will save only the upper 64 bits of the vector registers,
119 * since the lower 64 bits have already been saved as the scalar FP context.
120 */
121static int copy_msa_to_sigcontext32(struct sigcontext32 __user *sc)
122{
123	int i;
124	int err = 0;
125
126	for (i = 0; i < NUM_FPU_REGS; i++) {
127		err |=
128		    __put_user(get_fpr64(&current->thread.fpu.fpr[i], 1),
129			       &sc->sc_msaregs[i]);
130	}
131	err |= __put_user(current->thread.fpu.msacsr, &sc->sc_msa_csr);
132
133	return err;
134}
135
136static int copy_msa_from_sigcontext32(struct sigcontext32 __user *sc)
137{
138	int i;
139	int err = 0;
140	u64 val;
141
142	for (i = 0; i < NUM_FPU_REGS; i++) {
143		err |= __get_user(val, &sc->sc_msaregs[i]);
144		set_fpr64(&current->thread.fpu.fpr[i], 1, val);
145	}
146	err |= __get_user(current->thread.fpu.msacsr, &sc->sc_msa_csr);
147
148	return err;
149}
150
151/*
152 * sigcontext handlers
153 */
154static int protected_save_fp_context32(struct sigcontext32 __user *sc,
155				       unsigned used_math)
156{
157	int err;
158	bool save_msa = cpu_has_msa && (used_math & USEDMATH_MSA);
159	while (1) {
160		lock_fpu_owner();
161		if (is_fpu_owner()) {
162			err = save_fp_context32(sc);
163			if (save_msa && !err)
164				err = _save_msa_context32(sc);
165			unlock_fpu_owner();
166		} else {
167			unlock_fpu_owner();
168			err = copy_fp_to_sigcontext32(sc);
169			if (save_msa && !err)
170				err = copy_msa_to_sigcontext32(sc);
171		}
172		if (likely(!err))
173			break;
174		/* touch the sigcontext and try again */
175		err = __put_user(0, &sc->sc_fpregs[0]) |
176			__put_user(0, &sc->sc_fpregs[31]) |
177			__put_user(0, &sc->sc_fpc_csr);
178		if (err)
179			break;	/* really bad sigcontext */
180	}
181	return err;
182}
183
184static int protected_restore_fp_context32(struct sigcontext32 __user *sc,
185					  unsigned used_math)
186{
187	int err, tmp __maybe_unused;
188	bool restore_msa = cpu_has_msa && (used_math & USEDMATH_MSA);
189	while (1) {
190		lock_fpu_owner();
191		if (is_fpu_owner()) {
192			err = restore_fp_context32(sc);
193			if (restore_msa && !err) {
194				enable_msa();
195				err = _restore_msa_context32(sc);
196			} else {
197				/* signal handler may have used MSA */
198				disable_msa();
199			}
200			unlock_fpu_owner();
201		} else {
202			unlock_fpu_owner();
203			err = copy_fp_from_sigcontext32(sc);
204			if (restore_msa && !err)
205				err = copy_msa_from_sigcontext32(sc);
206		}
207		if (likely(!err))
208			break;
209		/* touch the sigcontext and try again */
210		err = __get_user(tmp, &sc->sc_fpregs[0]) |
211			__get_user(tmp, &sc->sc_fpregs[31]) |
212			__get_user(tmp, &sc->sc_fpc_csr);
213		if (err)
214			break;	/* really bad sigcontext */
215	}
216	return err;
217}
218
219static int setup_sigcontext32(struct pt_regs *regs,
220			      struct sigcontext32 __user *sc)
221{
222	int err = 0;
223	int i;
224	u32 used_math;
225
226	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
227
228	err |= __put_user(0, &sc->sc_regs[0]);
229	for (i = 1; i < 32; i++)
230		err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
231
232	err |= __put_user(regs->hi, &sc->sc_mdhi);
233	err |= __put_user(regs->lo, &sc->sc_mdlo);
234	if (cpu_has_dsp) {
235		err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
236		err |= __put_user(mfhi1(), &sc->sc_hi1);
237		err |= __put_user(mflo1(), &sc->sc_lo1);
238		err |= __put_user(mfhi2(), &sc->sc_hi2);
239		err |= __put_user(mflo2(), &sc->sc_lo2);
240		err |= __put_user(mfhi3(), &sc->sc_hi3);
241		err |= __put_user(mflo3(), &sc->sc_lo3);
242	}
243
244	used_math = used_math() ? USEDMATH_FP : 0;
245	used_math |= thread_msa_context_live() ? USEDMATH_MSA : 0;
246	err |= __put_user(used_math, &sc->sc_used_math);
247
248	if (used_math) {
249		/*
250		 * Save FPU state to signal context.  Signal handler
251		 * will "inherit" current FPU state.
252		 */
253		err |= protected_save_fp_context32(sc, used_math);
254	}
255	return err;
256}
257
258static int
259check_and_restore_fp_context32(struct sigcontext32 __user *sc,
260			       unsigned used_math)
261{
262	int err, sig;
263
264	err = sig = fpcsr_pending(&sc->sc_fpc_csr);
265	if (err > 0)
266		err = 0;
267	err |= protected_restore_fp_context32(sc, used_math);
268	return err ?: sig;
269}
270
271static int restore_sigcontext32(struct pt_regs *regs,
272				struct sigcontext32 __user *sc)
273{
274	u32 used_math;
275	int err = 0;
276	s32 treg;
277	int i;
278
279	/* Always make any pending restarted system calls return -EINTR */
280	current_thread_info()->restart_block.fn = do_no_restart_syscall;
281
282	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
283	err |= __get_user(regs->hi, &sc->sc_mdhi);
284	err |= __get_user(regs->lo, &sc->sc_mdlo);
285	if (cpu_has_dsp) {
286		err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
287		err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
288		err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
289		err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
290		err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
291		err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
292		err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
293	}
294
295	for (i = 1; i < 32; i++)
296		err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
297
298	err |= __get_user(used_math, &sc->sc_used_math);
299	conditional_used_math(used_math);
300
301	if (used_math) {
302		/* restore fpu context if we have used it before */
303		if (!err)
304			err = check_and_restore_fp_context32(sc, used_math);
305	} else {
306		/* signal handler may have used FPU or MSA. Disable them. */
307		disable_msa();
308		lose_fpu(0);
309	}
310
311	return err;
312}
313
314/*
315 *
316 */
317extern void __put_sigset_unknown_nsig(void);
318extern void __get_sigset_unknown_nsig(void);
319
320static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
321{
322	int err = 0;
323
324	if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
325		return -EFAULT;
326
327	switch (_NSIG_WORDS) {
328	default:
329		__put_sigset_unknown_nsig();
330	case 2:
331		err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
332		err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
333	case 1:
334		err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
335		err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
336	}
337
338	return err;
339}
340
341static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
342{
343	int err = 0;
344	unsigned long sig[4];
345
346	if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
347		return -EFAULT;
348
349	switch (_NSIG_WORDS) {
350	default:
351		__get_sigset_unknown_nsig();
352	case 2:
353		err |= __get_user(sig[3], &ubuf->sig[3]);
354		err |= __get_user(sig[2], &ubuf->sig[2]);
355		kbuf->sig[1] = sig[2] | (sig[3] << 32);
356	case 1:
357		err |= __get_user(sig[1], &ubuf->sig[1]);
358		err |= __get_user(sig[0], &ubuf->sig[0]);
359		kbuf->sig[0] = sig[0] | (sig[1] << 32);
360	}
361
362	return err;
363}
364
365/*
366 * Atomically swap in the new signal mask, and wait for a signal.
367 */
368
369asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
370{
371	return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
372}
373
374SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
375	struct compat_sigaction __user *, oact)
376{
377	struct k_sigaction new_ka, old_ka;
378	int ret;
379	int err = 0;
380
381	if (act) {
382		old_sigset_t mask;
383		s32 handler;
384
385		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
386			return -EFAULT;
387		err |= __get_user(handler, &act->sa_handler);
388		new_ka.sa.sa_handler = (void __user *)(s64)handler;
389		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
390		err |= __get_user(mask, &act->sa_mask.sig[0]);
391		if (err)
392			return -EFAULT;
393
394		siginitset(&new_ka.sa.sa_mask, mask);
395	}
396
397	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
398
399	if (!ret && oact) {
400		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
401			return -EFAULT;
402		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
403		err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
404				  &oact->sa_handler);
405		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
406		err |= __put_user(0, &oact->sa_mask.sig[1]);
407		err |= __put_user(0, &oact->sa_mask.sig[2]);
408		err |= __put_user(0, &oact->sa_mask.sig[3]);
409		if (err)
410			return -EFAULT;
411	}
412
413	return ret;
414}
415
416int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
417{
418	int err;
419
420	if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
421		return -EFAULT;
422
423	/* If you change siginfo_t structure, please be sure
424	   this code is fixed accordingly.
425	   It should never copy any pad contained in the structure
426	   to avoid security leaks, but must copy the generic
427	   3 ints plus the relevant union member.
428	   This routine must convert siginfo from 64bit to 32bit as well
429	   at the same time.  */
430	err = __put_user(from->si_signo, &to->si_signo);
431	err |= __put_user(from->si_errno, &to->si_errno);
432	err |= __put_user((short)from->si_code, &to->si_code);
433	if (from->si_code < 0)
434		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
435	else {
436		switch (from->si_code >> 16) {
437		case __SI_TIMER >> 16:
438			err |= __put_user(from->si_tid, &to->si_tid);
439			err |= __put_user(from->si_overrun, &to->si_overrun);
440			err |= __put_user(from->si_int, &to->si_int);
441			break;
442		case __SI_CHLD >> 16:
443			err |= __put_user(from->si_utime, &to->si_utime);
444			err |= __put_user(from->si_stime, &to->si_stime);
445			err |= __put_user(from->si_status, &to->si_status);
446		default:
447			err |= __put_user(from->si_pid, &to->si_pid);
448			err |= __put_user(from->si_uid, &to->si_uid);
449			break;
450		case __SI_FAULT >> 16:
451			err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
452			break;
453		case __SI_POLL >> 16:
454			err |= __put_user(from->si_band, &to->si_band);
455			err |= __put_user(from->si_fd, &to->si_fd);
456			break;
457		case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
458		case __SI_MESGQ >> 16:
459			err |= __put_user(from->si_pid, &to->si_pid);
460			err |= __put_user(from->si_uid, &to->si_uid);
461			err |= __put_user(from->si_int, &to->si_int);
462			break;
463		}
464	}
465	return err;
466}
467
468int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
469{
470	memset(to, 0, sizeof *to);
471
472	if (copy_from_user(to, from, 3*sizeof(int)) ||
473	    copy_from_user(to->_sifields._pad,
474			   from->_sifields._pad, SI_PAD_SIZE32))
475		return -EFAULT;
476
477	return 0;
478}
479
480asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
481{
482	struct sigframe32 __user *frame;
483	sigset_t blocked;
484	int sig;
485
486	frame = (struct sigframe32 __user *) regs.regs[29];
487	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
488		goto badframe;
489	if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
490		goto badframe;
491
492	set_current_blocked(&blocked);
493
494	sig = restore_sigcontext32(&regs, &frame->sf_sc);
495	if (sig < 0)
496		goto badframe;
497	else if (sig)
498		force_sig(sig, current);
499
500	/*
501	 * Don't let your children do this ...
502	 */
503	__asm__ __volatile__(
504		"move\t$29, %0\n\t"
505		"j\tsyscall_exit"
506		:/* no outputs */
507		:"r" (&regs));
508	/* Unreached */
509
510badframe:
511	force_sig(SIGSEGV, current);
512}
513
514asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
515{
516	struct rt_sigframe32 __user *frame;
517	sigset_t set;
518	int sig;
519
520	frame = (struct rt_sigframe32 __user *) regs.regs[29];
521	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
522		goto badframe;
523	if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
524		goto badframe;
525
526	set_current_blocked(&set);
527
528	sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
529	if (sig < 0)
530		goto badframe;
531	else if (sig)
532		force_sig(sig, current);
533
534	if (compat_restore_altstack(&frame->rs_uc.uc_stack))
535		goto badframe;
536
537	/*
538	 * Don't let your children do this ...
539	 */
540	__asm__ __volatile__(
541		"move\t$29, %0\n\t"
542		"j\tsyscall_exit"
543		:/* no outputs */
544		:"r" (&regs));
545	/* Unreached */
546
547badframe:
548	force_sig(SIGSEGV, current);
549}
550
551static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
552			  struct pt_regs *regs, int signr, sigset_t *set)
553{
554	struct sigframe32 __user *frame;
555	int err = 0;
556
557	frame = get_sigframe(ka, regs, sizeof(*frame));
558	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
559		goto give_sigsegv;
560
561	err |= setup_sigcontext32(regs, &frame->sf_sc);
562	err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
563
564	if (err)
565		goto give_sigsegv;
566
567	/*
568	 * Arguments to signal handler:
569	 *
570	 *   a0 = signal number
571	 *   a1 = 0 (should be cause)
572	 *   a2 = pointer to struct sigcontext
573	 *
574	 * $25 and c0_epc point to the signal handler, $29 points to the
575	 * struct sigframe.
576	 */
577	regs->regs[ 4] = signr;
578	regs->regs[ 5] = 0;
579	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
580	regs->regs[29] = (unsigned long) frame;
581	regs->regs[31] = (unsigned long) sig_return;
582	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
583
584	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
585	       current->comm, current->pid,
586	       frame, regs->cp0_epc, regs->regs[31]);
587
588	return 0;
589
590give_sigsegv:
591	force_sigsegv(signr, current);
592	return -EFAULT;
593}
594
595static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
596			     struct pt_regs *regs, int signr, sigset_t *set,
597			     siginfo_t *info)
598{
599	struct rt_sigframe32 __user *frame;
600	int err = 0;
601
602	frame = get_sigframe(ka, regs, sizeof(*frame));
603	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
604		goto give_sigsegv;
605
606	/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
607	err |= copy_siginfo_to_user32(&frame->rs_info, info);
608
609	/* Create the ucontext.	 */
610	err |= __put_user(0, &frame->rs_uc.uc_flags);
611	err |= __put_user(0, &frame->rs_uc.uc_link);
612	err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
613	err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
614	err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
615
616	if (err)
617		goto give_sigsegv;
618
619	/*
620	 * Arguments to signal handler:
621	 *
622	 *   a0 = signal number
623	 *   a1 = 0 (should be cause)
624	 *   a2 = pointer to ucontext
625	 *
626	 * $25 and c0_epc point to the signal handler, $29 points to
627	 * the struct rt_sigframe32.
628	 */
629	regs->regs[ 4] = signr;
630	regs->regs[ 5] = (unsigned long) &frame->rs_info;
631	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
632	regs->regs[29] = (unsigned long) frame;
633	regs->regs[31] = (unsigned long) sig_return;
634	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
635
636	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
637	       current->comm, current->pid,
638	       frame, regs->cp0_epc, regs->regs[31]);
639
640	return 0;
641
642give_sigsegv:
643	force_sigsegv(signr, current);
644	return -EFAULT;
645}
646
647/*
648 * o32 compatibility on 64-bit kernels, without DSP ASE
649 */
650struct mips_abi mips_abi_32 = {
651	.setup_frame	= setup_frame_32,
652	.signal_return_offset =
653		offsetof(struct mips_vdso, o32_signal_trampoline),
654	.setup_rt_frame = setup_rt_frame_32,
655	.rt_signal_return_offset =
656		offsetof(struct mips_vdso, o32_rt_signal_trampoline),
657	.restart	= __NR_O32_restart_syscall
658};
659
660static int signal32_init(void)
661{
662	if (cpu_has_fpu) {
663		save_fp_context32 = _save_fp_context32;
664		restore_fp_context32 = _restore_fp_context32;
665	} else {
666		save_fp_context32 = copy_fp_to_sigcontext32;
667		restore_fp_context32 = copy_fp_from_sigcontext32;
668	}
669
670	return 0;
671}
672
673arch_initcall(signal32_init);