MIPS: BMIPS: Clear MIPS_CACHE_ALIASES earlier
[deliverable/linux.git] / arch / mips / kernel / signal32.c
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
45 typedef unsigned int __sighandler32_t;
46 typedef void (*vfptr_t)(void);
47
48 struct 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
56 struct 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
63 struct 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
70 static 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
103 static 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
136 asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
137 {
138 return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
139 }
140
141 SYSCALL_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
183 int 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 case __SI_SYS >> 16:
231 err |= __copy_to_user(&to->si_call_addr, &from->si_call_addr,
232 sizeof(compat_uptr_t));
233 err |= __put_user(from->si_syscall, &to->si_syscall);
234 err |= __put_user(from->si_arch, &to->si_arch);
235 break;
236 }
237 }
238 return err;
239 }
240
241 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
242 {
243 if (copy_from_user(to, from, 3*sizeof(int)) ||
244 copy_from_user(to->_sifields._pad,
245 from->_sifields._pad, SI_PAD_SIZE32))
246 return -EFAULT;
247
248 return 0;
249 }
250
251 asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
252 {
253 struct sigframe32 __user *frame;
254 sigset_t blocked;
255 int sig;
256
257 frame = (struct sigframe32 __user *) regs.regs[29];
258 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
259 goto badframe;
260 if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
261 goto badframe;
262
263 set_current_blocked(&blocked);
264
265 sig = restore_sigcontext32(&regs, &frame->sf_sc);
266 if (sig < 0)
267 goto badframe;
268 else if (sig)
269 force_sig(sig, current);
270
271 /*
272 * Don't let your children do this ...
273 */
274 __asm__ __volatile__(
275 "move\t$29, %0\n\t"
276 "j\tsyscall_exit"
277 :/* no outputs */
278 :"r" (&regs));
279 /* Unreached */
280
281 badframe:
282 force_sig(SIGSEGV, current);
283 }
284
285 asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
286 {
287 struct rt_sigframe32 __user *frame;
288 sigset_t set;
289 int sig;
290
291 frame = (struct rt_sigframe32 __user *) regs.regs[29];
292 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
293 goto badframe;
294 if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
295 goto badframe;
296
297 set_current_blocked(&set);
298
299 sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
300 if (sig < 0)
301 goto badframe;
302 else if (sig)
303 force_sig(sig, current);
304
305 if (compat_restore_altstack(&frame->rs_uc.uc_stack))
306 goto badframe;
307
308 /*
309 * Don't let your children do this ...
310 */
311 __asm__ __volatile__(
312 "move\t$29, %0\n\t"
313 "j\tsyscall_exit"
314 :/* no outputs */
315 :"r" (&regs));
316 /* Unreached */
317
318 badframe:
319 force_sig(SIGSEGV, current);
320 }
321
322 static int setup_frame_32(void *sig_return, struct ksignal *ksig,
323 struct pt_regs *regs, sigset_t *set)
324 {
325 struct sigframe32 __user *frame;
326 int err = 0;
327
328 frame = get_sigframe(ksig, regs, sizeof(*frame));
329 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
330 return -EFAULT;
331
332 err |= setup_sigcontext32(regs, &frame->sf_sc);
333 err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
334
335 if (err)
336 return -EFAULT;
337
338 /*
339 * Arguments to signal handler:
340 *
341 * a0 = signal number
342 * a1 = 0 (should be cause)
343 * a2 = pointer to struct sigcontext
344 *
345 * $25 and c0_epc point to the signal handler, $29 points to the
346 * struct sigframe.
347 */
348 regs->regs[ 4] = ksig->sig;
349 regs->regs[ 5] = 0;
350 regs->regs[ 6] = (unsigned long) &frame->sf_sc;
351 regs->regs[29] = (unsigned long) frame;
352 regs->regs[31] = (unsigned long) sig_return;
353 regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
354
355 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
356 current->comm, current->pid,
357 frame, regs->cp0_epc, regs->regs[31]);
358
359 return 0;
360 }
361
362 static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig,
363 struct pt_regs *regs, sigset_t *set)
364 {
365 struct rt_sigframe32 __user *frame;
366 int err = 0;
367
368 frame = get_sigframe(ksig, regs, sizeof(*frame));
369 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
370 return -EFAULT;
371
372 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
373 err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
374
375 /* Create the ucontext. */
376 err |= __put_user(0, &frame->rs_uc.uc_flags);
377 err |= __put_user(0, &frame->rs_uc.uc_link);
378 err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
379 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
380 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
381
382 if (err)
383 return -EFAULT;
384
385 /*
386 * Arguments to signal handler:
387 *
388 * a0 = signal number
389 * a1 = 0 (should be cause)
390 * a2 = pointer to ucontext
391 *
392 * $25 and c0_epc point to the signal handler, $29 points to
393 * the struct rt_sigframe32.
394 */
395 regs->regs[ 4] = ksig->sig;
396 regs->regs[ 5] = (unsigned long) &frame->rs_info;
397 regs->regs[ 6] = (unsigned long) &frame->rs_uc;
398 regs->regs[29] = (unsigned long) frame;
399 regs->regs[31] = (unsigned long) sig_return;
400 regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
401
402 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
403 current->comm, current->pid,
404 frame, regs->cp0_epc, regs->regs[31]);
405
406 return 0;
407 }
408
409 /*
410 * o32 compatibility on 64-bit kernels, without DSP ASE
411 */
412 struct mips_abi mips_abi_32 = {
413 .setup_frame = setup_frame_32,
414 .setup_rt_frame = setup_rt_frame_32,
415 .restart = __NR_O32_restart_syscall,
416
417 .off_sc_fpregs = offsetof(struct sigcontext32, sc_fpregs),
418 .off_sc_fpc_csr = offsetof(struct sigcontext32, sc_fpc_csr),
419 .off_sc_used_math = offsetof(struct sigcontext32, sc_used_math),
420
421 .vdso = &vdso_image_o32,
422 };
This page took 0.058721 seconds and 5 git commands to generate.