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
6 * Copyright (C) 1991, 1992 Linus Torvalds
7 * Copyright (C) 1994 - 2000, 2006 Ralf Baechle
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
10 #include <linux/cache.h>
11 #include <linux/compat.h>
12 #include <linux/sched.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>
27 #include <asm/compat-signal.h>
28 #include <linux/bitops.h>
29 #include <asm/cacheflush.h>
31 #include <asm/ucontext.h>
36 #include "signal-common.h"
39 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
41 #define __NR_O32_restart_syscall 4253
43 /* 32-bit compatibility types */
45 typedef unsigned int __sighandler32_t
;
46 typedef void (*vfptr_t
)(void);
51 compat_stack_t uc_stack
;
52 struct sigcontext32 uc_mcontext
;
53 compat_sigset_t uc_sigmask
; /* mask last for extensibility */
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
;
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
;
70 static int setup_sigcontext32(struct pt_regs
*regs
,
71 struct sigcontext32 __user
*sc
)
76 err
|= __put_user(regs
->cp0_epc
, &sc
->sc_pc
);
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
]);
82 err
|= __put_user(regs
->hi
, &sc
->sc_mdhi
);
83 err
|= __put_user(regs
->lo
, &sc
->sc_mdlo
);
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
);
95 * Save FPU state to signal context. Signal handler
96 * will "inherit" current FPU state.
98 err
|= protected_save_fp_context(sc
);
103 static int restore_sigcontext32(struct pt_regs
*regs
,
104 struct sigcontext32 __user
*sc
)
110 /* Always make any pending restarted system calls return -EINTR */
111 current
->restart_block
.fn
= do_no_restart_syscall
;
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
);
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
);
126 for (i
= 1; i
< 32; i
++)
127 err
|= __get_user(regs
->regs
[i
], &sc
->sc_regs
[i
]);
129 return err
?: protected_restore_fp_context(sc
);
133 * Atomically swap in the new signal mask, and wait for a signal.
136 asmlinkage
int sys32_sigsuspend(compat_sigset_t __user
*uset
)
138 return compat_sys_rt_sigsuspend(uset
, sizeof(compat_sigset_t
));
141 SYSCALL_DEFINE3(32_sigaction
, long, sig
, const struct compat_sigaction __user
*, act
,
142 struct compat_sigaction __user
*, oact
)
144 struct k_sigaction new_ka
, old_ka
;
152 if (!access_ok(VERIFY_READ
, act
, sizeof(*act
)))
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]);
161 siginitset(&new_ka
.sa
.sa_mask
, mask
);
164 ret
= do_sigaction(sig
, act
? &new_ka
: NULL
, oact
? &old_ka
: NULL
);
167 if (!access_ok(VERIFY_WRITE
, oact
, sizeof(*oact
)))
169 err
|= __put_user(old_ka
.sa
.sa_flags
, &oact
->sa_flags
);
170 err
|= __put_user((u32
)(u64
)old_ka
.sa
.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]);
183 int copy_siginfo_to_user32(compat_siginfo_t __user
*to
, const siginfo_t
*from
)
187 if (!access_ok (VERIFY_WRITE
, to
, sizeof(compat_siginfo_t
)))
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
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
);
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
);
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
);
214 err
|= __put_user(from
->si_pid
, &to
->si_pid
);
215 err
|= __put_user(from
->si_uid
, &to
->si_uid
);
217 case __SI_FAULT
>> 16:
218 err
|= __put_user((unsigned long)from
->si_addr
, &to
->si_addr
);
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
);
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
);
235 int copy_siginfo_from_user32(siginfo_t
*to
, compat_siginfo_t __user
*from
)
237 if (copy_from_user(to
, from
, 3*sizeof(int)) ||
238 copy_from_user(to
->_sifields
._pad
,
239 from
->_sifields
._pad
, SI_PAD_SIZE32
))
245 asmlinkage
void sys32_sigreturn(nabi_no_regargs
struct pt_regs regs
)
247 struct sigframe32 __user
*frame
;
251 frame
= (struct sigframe32 __user
*) regs
.regs
[29];
252 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
254 if (__copy_conv_sigset_from_user(&blocked
, &frame
->sf_mask
))
257 set_current_blocked(&blocked
);
259 sig
= restore_sigcontext32(®s
, &frame
->sf_sc
);
263 force_sig(sig
, current
);
266 * Don't let your children do this ...
268 __asm__
__volatile__(
276 force_sig(SIGSEGV
, current
);
279 asmlinkage
void sys32_rt_sigreturn(nabi_no_regargs
struct pt_regs regs
)
281 struct rt_sigframe32 __user
*frame
;
285 frame
= (struct rt_sigframe32 __user
*) regs
.regs
[29];
286 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
288 if (__copy_conv_sigset_from_user(&set
, &frame
->rs_uc
.uc_sigmask
))
291 set_current_blocked(&set
);
293 sig
= restore_sigcontext32(®s
, &frame
->rs_uc
.uc_mcontext
);
297 force_sig(sig
, current
);
299 if (compat_restore_altstack(&frame
->rs_uc
.uc_stack
))
303 * Don't let your children do this ...
305 __asm__
__volatile__(
313 force_sig(SIGSEGV
, current
);
316 static int setup_frame_32(void *sig_return
, struct ksignal
*ksig
,
317 struct pt_regs
*regs
, sigset_t
*set
)
319 struct sigframe32 __user
*frame
;
322 frame
= get_sigframe(ksig
, regs
, sizeof(*frame
));
323 if (!access_ok(VERIFY_WRITE
, frame
, sizeof (*frame
)))
326 err
|= setup_sigcontext32(regs
, &frame
->sf_sc
);
327 err
|= __copy_conv_sigset_to_user(&frame
->sf_mask
, set
);
333 * Arguments to signal handler:
336 * a1 = 0 (should be cause)
337 * a2 = pointer to struct sigcontext
339 * $25 and c0_epc point to the signal handler, $29 points to the
342 regs
->regs
[ 4] = ksig
->sig
;
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
;
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]);
356 static int setup_rt_frame_32(void *sig_return
, struct ksignal
*ksig
,
357 struct pt_regs
*regs
, sigset_t
*set
)
359 struct rt_sigframe32 __user
*frame
;
362 frame
= get_sigframe(ksig
, regs
, sizeof(*frame
));
363 if (!access_ok(VERIFY_WRITE
, frame
, sizeof (*frame
)))
366 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
367 err
|= copy_siginfo_to_user32(&frame
->rs_info
, &ksig
->info
);
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
);
380 * Arguments to signal handler:
383 * a1 = 0 (should be cause)
384 * a2 = pointer to ucontext
386 * $25 and c0_epc point to the signal handler, $29 points to
387 * the struct rt_sigframe32.
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
;
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]);
404 * o32 compatibility on 64-bit kernels, without DSP ASE
406 struct 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
,
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
),
415 .vdso
= &vdso_image_o32
,