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.
9 * Copyright (C) 2016, Imagination Technologies Ltd.
11 #include <linux/compiler.h>
12 #include <linux/errno.h>
13 #include <linux/signal.h>
14 #include <linux/sched/signal.h>
15 #include <linux/uaccess.h>
18 #include <asm/compat-signal.h>
21 #include <asm/unistd.h>
23 #include "signal-common.h"
26 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
28 #define __NR_O32_restart_syscall 4253
31 u32 sf_ass
[4]; /* argument save space for o32 */
32 u32 sf_pad
[2]; /* Was: signal trampoline */
33 struct sigcontext32 sf_sc
;
34 compat_sigset_t sf_mask
;
40 compat_stack_t uc_stack
;
41 struct sigcontext32 uc_mcontext
;
42 compat_sigset_t uc_sigmask
; /* mask last for extensibility */
45 struct rt_sigframe32
{
46 u32 rs_ass
[4]; /* argument save space for o32 */
47 u32 rs_pad
[2]; /* Was: signal trampoline */
48 compat_siginfo_t rs_info
;
49 struct ucontext32 rs_uc
;
52 static int setup_sigcontext32(struct pt_regs
*regs
,
53 struct sigcontext32 __user
*sc
)
58 err
|= __put_user(regs
->cp0_epc
, &sc
->sc_pc
);
60 err
|= __put_user(0, &sc
->sc_regs
[0]);
61 for (i
= 1; i
< 32; i
++)
62 err
|= __put_user(regs
->regs
[i
], &sc
->sc_regs
[i
]);
64 err
|= __put_user(regs
->hi
, &sc
->sc_mdhi
);
65 err
|= __put_user(regs
->lo
, &sc
->sc_mdlo
);
67 err
|= __put_user(rddsp(DSP_MASK
), &sc
->sc_dsp
);
68 err
|= __put_user(mfhi1(), &sc
->sc_hi1
);
69 err
|= __put_user(mflo1(), &sc
->sc_lo1
);
70 err
|= __put_user(mfhi2(), &sc
->sc_hi2
);
71 err
|= __put_user(mflo2(), &sc
->sc_lo2
);
72 err
|= __put_user(mfhi3(), &sc
->sc_hi3
);
73 err
|= __put_user(mflo3(), &sc
->sc_lo3
);
77 * Save FPU state to signal context. Signal handler
78 * will "inherit" current FPU state.
80 err
|= protected_save_fp_context(sc
);
85 static int restore_sigcontext32(struct pt_regs
*regs
,
86 struct sigcontext32 __user
*sc
)
92 /* Always make any pending restarted system calls return -EINTR */
93 current
->restart_block
.fn
= do_no_restart_syscall
;
95 err
|= __get_user(regs
->cp0_epc
, &sc
->sc_pc
);
96 err
|= __get_user(regs
->hi
, &sc
->sc_mdhi
);
97 err
|= __get_user(regs
->lo
, &sc
->sc_mdlo
);
99 err
|= __get_user(treg
, &sc
->sc_hi1
); mthi1(treg
);
100 err
|= __get_user(treg
, &sc
->sc_lo1
); mtlo1(treg
);
101 err
|= __get_user(treg
, &sc
->sc_hi2
); mthi2(treg
);
102 err
|= __get_user(treg
, &sc
->sc_lo2
); mtlo2(treg
);
103 err
|= __get_user(treg
, &sc
->sc_hi3
); mthi3(treg
);
104 err
|= __get_user(treg
, &sc
->sc_lo3
); mtlo3(treg
);
105 err
|= __get_user(treg
, &sc
->sc_dsp
); wrdsp(treg
, DSP_MASK
);
108 for (i
= 1; i
< 32; i
++)
109 err
|= __get_user(regs
->regs
[i
], &sc
->sc_regs
[i
]);
111 return err
?: protected_restore_fp_context(sc
);
114 static int setup_frame_32(void *sig_return
, struct ksignal
*ksig
,
115 struct pt_regs
*regs
, sigset_t
*set
)
117 struct sigframe32 __user
*frame
;
120 frame
= get_sigframe(ksig
, regs
, sizeof(*frame
));
121 if (!access_ok(frame
, sizeof (*frame
)))
124 err
|= setup_sigcontext32(regs
, &frame
->sf_sc
);
125 err
|= __copy_conv_sigset_to_user(&frame
->sf_mask
, set
);
131 * Arguments to signal handler:
134 * a1 = 0 (should be cause)
135 * a2 = pointer to struct sigcontext
137 * $25 and c0_epc point to the signal handler, $29 points to the
140 regs
->regs
[ 4] = ksig
->sig
;
142 regs
->regs
[ 6] = (unsigned long) &frame
->sf_sc
;
143 regs
->regs
[29] = (unsigned long) frame
;
144 regs
->regs
[31] = (unsigned long) sig_return
;
145 regs
->cp0_epc
= regs
->regs
[25] = (unsigned long) ksig
->ka
.sa
.sa_handler
;
147 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
148 current
->comm
, current
->pid
,
149 frame
, regs
->cp0_epc
, regs
->regs
[31]);
154 asmlinkage
void sys32_rt_sigreturn(void)
156 struct rt_sigframe32 __user
*frame
;
157 struct pt_regs
*regs
;
161 regs
= current_pt_regs();
162 frame
= (struct rt_sigframe32 __user
*)regs
->regs
[29];
163 if (!access_ok(frame
, sizeof(*frame
)))
165 if (__copy_conv_sigset_from_user(&set
, &frame
->rs_uc
.uc_sigmask
))
168 set_current_blocked(&set
);
170 sig
= restore_sigcontext32(regs
, &frame
->rs_uc
.uc_mcontext
);
176 if (compat_restore_altstack(&frame
->rs_uc
.uc_stack
))
180 * Don't let your children do this ...
182 __asm__
__volatile__(
193 static int setup_rt_frame_32(void *sig_return
, struct ksignal
*ksig
,
194 struct pt_regs
*regs
, sigset_t
*set
)
196 struct rt_sigframe32 __user
*frame
;
199 frame
= get_sigframe(ksig
, regs
, sizeof(*frame
));
200 if (!access_ok(frame
, sizeof (*frame
)))
203 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
204 err
|= copy_siginfo_to_user32(&frame
->rs_info
, &ksig
->info
);
206 /* Create the ucontext. */
207 err
|= __put_user(0, &frame
->rs_uc
.uc_flags
);
208 err
|= __put_user(0, &frame
->rs_uc
.uc_link
);
209 err
|= __compat_save_altstack(&frame
->rs_uc
.uc_stack
, regs
->regs
[29]);
210 err
|= setup_sigcontext32(regs
, &frame
->rs_uc
.uc_mcontext
);
211 err
|= __copy_conv_sigset_to_user(&frame
->rs_uc
.uc_sigmask
, set
);
217 * Arguments to signal handler:
220 * a1 = 0 (should be cause)
221 * a2 = pointer to ucontext
223 * $25 and c0_epc point to the signal handler, $29 points to
224 * the struct rt_sigframe32.
226 regs
->regs
[ 4] = ksig
->sig
;
227 regs
->regs
[ 5] = (unsigned long) &frame
->rs_info
;
228 regs
->regs
[ 6] = (unsigned long) &frame
->rs_uc
;
229 regs
->regs
[29] = (unsigned long) frame
;
230 regs
->regs
[31] = (unsigned long) sig_return
;
231 regs
->cp0_epc
= regs
->regs
[25] = (unsigned long) ksig
->ka
.sa
.sa_handler
;
233 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
234 current
->comm
, current
->pid
,
235 frame
, regs
->cp0_epc
, regs
->regs
[31]);
241 * o32 compatibility on 64-bit kernels, without DSP ASE
243 struct mips_abi mips_abi_32
= {
244 .setup_frame
= setup_frame_32
,
245 .setup_rt_frame
= setup_rt_frame_32
,
246 .restart
= __NR_O32_restart_syscall
,
248 .off_sc_fpregs
= offsetof(struct sigcontext32
, sc_fpregs
),
249 .off_sc_fpc_csr
= offsetof(struct sigcontext32
, sc_fpc_csr
),
250 .off_sc_used_math
= offsetof(struct sigcontext32
, sc_used_math
),
252 .vdso
= &vdso_image_o32
,
256 asmlinkage
void sys32_sigreturn(void)
258 struct sigframe32 __user
*frame
;
259 struct pt_regs
*regs
;
263 regs
= current_pt_regs();
264 frame
= (struct sigframe32 __user
*)regs
->regs
[29];
265 if (!access_ok(frame
, sizeof(*frame
)))
267 if (__copy_conv_sigset_from_user(&blocked
, &frame
->sf_mask
))
270 set_current_blocked(&blocked
);
272 sig
= restore_sigcontext32(regs
, &frame
->sf_sc
);
279 * Don't let your children do this ...
281 __asm__
__volatile__(