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/war.h>
34#include <asm/dsp.h>
35
36#include "signal-common.h"
37
38/*
39 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
40 */
41#define __NR_O32_restart_syscall	4253
42
43/* 32-bit compatibility types */
44
45typedef unsigned int __sighandler32_t;
46typedef void (*vfptr_t)(void);
47
48struct ucontext32 {
49	u32		    uc_flags;
50	s32		    uc_link;
51	compat_stack_t      uc_stack;
52	struct sigcontext32 uc_mcontext;
53	compat_sigset_t	    uc_sigmask;	  /* mask last for extensibility */
54};
55
56struct sigframe32 {
57	u32 sf_ass[4];		/* argument save space for o32 */
58	u32 sf_pad[2];		/* Was: signal trampoline */
59	struct sigcontext32 sf_sc;
60	compat_sigset_t sf_mask;
61};
62
63struct rt_sigframe32 {
64	u32 rs_ass[4];			/* argument save space for o32 */
65	u32 rs_pad[2];			/* Was: signal trampoline */
66	compat_siginfo_t rs_info;
67	struct ucontext32 rs_uc;
68};
69
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);
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
94	/*
95	 * Save FPU state to signal context.  Signal handler
96	 * will "inherit" current FPU state.
97	 */
98	err |= protected_save_fp_context(sc);
99
100	return err;
101}
102
103static int restore_sigcontext32(struct pt_regs *regs,
104				struct sigcontext32 __user *sc)
105{
106	int err = 0;
107	s32 treg;
108	int i;
109
110	/* Always make any pending restarted system calls return -EINTR */
111	current->restart_block.fn = do_no_restart_syscall;
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
129	return err ?: protected_restore_fp_context(sc);
130}
131
132/*
133 * Atomically swap in the new signal mask, and wait for a signal.
134 */
135
136asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
137{
138	return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
139}
140
141SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
142	struct compat_sigaction __user *, oact)
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;
150		s32 handler;
151
152		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
153			return -EFAULT;
154		err |= __get_user(handler, &act->sa_handler);
155		new_ka.sa.sa_handler = (void __user *)(s64)handler;
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)))
168			return -EFAULT;
169		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
170		err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
171				  &oact->sa_handler);
172		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
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)
177			return -EFAULT;
178	}
179
180	return ret;
181}
182
183int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
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) {
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;
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:
218			err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
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
235int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
236{
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
245asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
246{
247	struct sigframe32 __user *frame;
248	sigset_t blocked;
249	int sig;
250
251	frame = (struct sigframe32 __user *) regs.regs[29];
252	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
253		goto badframe;
254	if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
255		goto badframe;
256
257	set_current_blocked(&blocked);
258
259	sig = restore_sigcontext32(&regs, &frame->sf_sc);
260	if (sig < 0)
261		goto badframe;
262	else if (sig)
263		force_sig(sig, current);
264
265	/*
266	 * Don't let your children do this ...
267	 */
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
279asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
280{
281	struct rt_sigframe32 __user *frame;
282	sigset_t set;
283	int sig;
284
285	frame = (struct rt_sigframe32 __user *) regs.regs[29];
286	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
287		goto badframe;
288	if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
289		goto badframe;
290
291	set_current_blocked(&set);
292
293	sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
294	if (sig < 0)
295		goto badframe;
296	else if (sig)
297		force_sig(sig, current);
298
299	if (compat_restore_altstack(&frame->rs_uc.uc_stack))
300		goto badframe;
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
316static int setup_frame_32(void *sig_return, struct ksignal *ksig,
317			  struct pt_regs *regs, sigset_t *set)
318{
319	struct sigframe32 __user *frame;
320	int err = 0;
321
322	frame = get_sigframe(ksig, regs, sizeof(*frame));
323	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
324		return -EFAULT;
325
326	err |= setup_sigcontext32(regs, &frame->sf_sc);
327	err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
328
329	if (err)
330		return -EFAULT;
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	 */
342	regs->regs[ 4] = ksig->sig;
343	regs->regs[ 5] = 0;
344	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
345	regs->regs[29] = (unsigned long) frame;
346	regs->regs[31] = (unsigned long) sig_return;
347	regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
348
349	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
350	       current->comm, current->pid,
351	       frame, regs->cp0_epc, regs->regs[31]);
352
353	return 0;
354}
355
356static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig,
357			     struct pt_regs *regs, sigset_t *set)
358{
359	struct rt_sigframe32 __user *frame;
360	int err = 0;
361
362	frame = get_sigframe(ksig, regs, sizeof(*frame));
363	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
364		return -EFAULT;
365
366	/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
367	err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
368
369	/* Create the ucontext.	 */
370	err |= __put_user(0, &frame->rs_uc.uc_flags);
371	err |= __put_user(0, &frame->rs_uc.uc_link);
372	err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
373	err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
374	err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
375
376	if (err)
377		return -EFAULT;
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	 */
389	regs->regs[ 4] = ksig->sig;
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;
393	regs->regs[31] = (unsigned long) sig_return;
394	regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
395
396	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
397	       current->comm, current->pid,
398	       frame, regs->cp0_epc, regs->regs[31]);
399
400	return 0;
401}
402
403/*
404 * o32 compatibility on 64-bit kernels, without DSP ASE
405 */
406struct mips_abi mips_abi_32 = {
407	.setup_frame	= setup_frame_32,
408	.setup_rt_frame = setup_rt_frame_32,
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),
414
415	.vdso		= &vdso_image_o32,
416};
417