2 * linux/arch/x86_64/ia32/ia32_signal.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
6 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
7 * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes
8 * 2000-12-* x86-64 compatibility mode signal handling by Andi Kleen
11 #include <linux/sched.h>
13 #include <linux/smp.h>
14 #include <linux/kernel.h>
15 #include <linux/errno.h>
16 #include <linux/wait.h>
17 #include <linux/unistd.h>
18 #include <linux/stddef.h>
19 #include <linux/personality.h>
20 #include <linux/compat.h>
21 #include <linux/binfmts.h>
22 #include <asm/ucontext.h>
23 #include <asm/uaccess.h>
24 #include <asm/fpu/internal.h>
25 #include <asm/fpu/signal.h>
26 #include <asm/ptrace.h>
27 #include <asm/ia32_unistd.h>
28 #include <asm/user32.h>
29 #include <uapi/asm/sigcontext.h>
30 #include <asm/proto.h>
32 #include <asm/sigframe.h>
33 #include <asm/sighandling.h>
34 #include <asm/sys_ia32.h>
38 * Do a signal return; undo the signal stack.
40 #define loadsegment_gs(v) load_gs_index(v)
41 #define loadsegment_fs(v) loadsegment(fs, v)
42 #define loadsegment_ds(v) loadsegment(ds, v)
43 #define loadsegment_es(v) loadsegment(es, v)
45 #define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
46 #define set_user_seg(seg, v) loadsegment_##seg(v)
49 get_user_ex(regs->x, &sc->x); \
52 #define GET_SEG(seg) ({ \
54 get_user_ex(tmp, &sc->seg); \
58 #define COPY_SEG_CPL3(seg) do { \
59 regs->seg = GET_SEG(seg) | 3; \
62 #define RELOAD_SEG(seg) { \
63 unsigned int pre = GET_SEG(seg); \
64 unsigned int cur = get_user_seg(seg); \
67 set_user_seg(seg, pre); \
70 static int ia32_restore_sigcontext(struct pt_regs
*regs
,
71 struct sigcontext_32 __user
*sc
)
73 unsigned int tmpflags
, err
= 0;
77 /* Always make any pending restarted system calls return -EINTR */
78 current
->restart_block
.fn
= do_no_restart_syscall
;
82 * Reload fs and gs if they have changed in the signal
83 * handler. This does not handle long fs/gs base changes in
84 * the handler, but does not clobber them at least in the
92 COPY(di
); COPY(si
); COPY(bp
); COPY(sp
); COPY(bx
);
93 COPY(dx
); COPY(cx
); COPY(ip
); COPY(ax
);
94 /* Don't touch extended registers */
99 get_user_ex(tmpflags
, &sc
->flags
);
100 regs
->flags
= (regs
->flags
& ~FIX_EFLAGS
) | (tmpflags
& FIX_EFLAGS
);
101 /* disable syscall checks */
104 get_user_ex(tmp
, &sc
->fpstate
);
105 buf
= compat_ptr(tmp
);
106 } get_user_catch(err
);
108 err
|= fpu__restore_sig(buf
, 1);
115 asmlinkage
long sys32_sigreturn(void)
117 struct pt_regs
*regs
= current_pt_regs();
118 struct sigframe_ia32 __user
*frame
= (struct sigframe_ia32 __user
*)(regs
->sp
-8);
121 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
123 if (__get_user(set
.sig
[0], &frame
->sc
.oldmask
)
124 || (_COMPAT_NSIG_WORDS
> 1
125 && __copy_from_user((((char *) &set
.sig
) + 4),
127 sizeof(frame
->extramask
))))
130 set_current_blocked(&set
);
132 if (ia32_restore_sigcontext(regs
, &frame
->sc
))
137 signal_fault(regs
, frame
, "32bit sigreturn");
141 asmlinkage
long sys32_rt_sigreturn(void)
143 struct pt_regs
*regs
= current_pt_regs();
144 struct rt_sigframe_ia32 __user
*frame
;
147 frame
= (struct rt_sigframe_ia32 __user
*)(regs
->sp
- 4);
149 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
151 if (__copy_from_user(&set
, &frame
->uc
.uc_sigmask
, sizeof(set
)))
154 set_current_blocked(&set
);
156 if (ia32_restore_sigcontext(regs
, &frame
->uc
.uc_mcontext
))
159 if (compat_restore_altstack(&frame
->uc
.uc_stack
))
165 signal_fault(regs
, frame
, "32bit rt sigreturn");
170 * Set up a signal frame.
173 static int ia32_setup_sigcontext(struct sigcontext_32 __user
*sc
,
174 void __user
*fpstate
,
175 struct pt_regs
*regs
, unsigned int mask
)
180 put_user_ex(get_user_seg(gs
), (unsigned int __user
*)&sc
->gs
);
181 put_user_ex(get_user_seg(fs
), (unsigned int __user
*)&sc
->fs
);
182 put_user_ex(get_user_seg(ds
), (unsigned int __user
*)&sc
->ds
);
183 put_user_ex(get_user_seg(es
), (unsigned int __user
*)&sc
->es
);
185 put_user_ex(regs
->di
, &sc
->di
);
186 put_user_ex(regs
->si
, &sc
->si
);
187 put_user_ex(regs
->bp
, &sc
->bp
);
188 put_user_ex(regs
->sp
, &sc
->sp
);
189 put_user_ex(regs
->bx
, &sc
->bx
);
190 put_user_ex(regs
->dx
, &sc
->dx
);
191 put_user_ex(regs
->cx
, &sc
->cx
);
192 put_user_ex(regs
->ax
, &sc
->ax
);
193 put_user_ex(current
->thread
.trap_nr
, &sc
->trapno
);
194 put_user_ex(current
->thread
.error_code
, &sc
->err
);
195 put_user_ex(regs
->ip
, &sc
->ip
);
196 put_user_ex(regs
->cs
, (unsigned int __user
*)&sc
->cs
);
197 put_user_ex(regs
->flags
, &sc
->flags
);
198 put_user_ex(regs
->sp
, &sc
->sp_at_signal
);
199 put_user_ex(regs
->ss
, (unsigned int __user
*)&sc
->ss
);
201 put_user_ex(ptr_to_compat(fpstate
), &sc
->fpstate
);
203 /* non-iBCS2 extensions.. */
204 put_user_ex(mask
, &sc
->oldmask
);
205 put_user_ex(current
->thread
.cr2
, &sc
->cr2
);
206 } put_user_catch(err
);
212 * Determine which stack to use..
214 static void __user
*get_sigframe(struct ksignal
*ksig
, struct pt_regs
*regs
,
216 void __user
**fpstate
)
218 struct fpu
*fpu
= ¤t
->thread
.fpu
;
221 /* Default to using normal stack */
224 /* This is the X/Open sanctioned signal stack switching. */
225 if (ksig
->ka
.sa
.sa_flags
& SA_ONSTACK
)
226 sp
= sigsp(sp
, ksig
);
227 /* This is the legacy signal stack switching. */
228 else if ((regs
->ss
& 0xffff) != __USER32_DS
&&
229 !(ksig
->ka
.sa
.sa_flags
& SA_RESTORER
) &&
230 ksig
->ka
.sa
.sa_restorer
)
231 sp
= (unsigned long) ksig
->ka
.sa
.sa_restorer
;
233 if (fpu
->fpstate_active
) {
234 unsigned long fx_aligned
, math_size
;
236 sp
= fpu__alloc_mathframe(sp
, 1, &fx_aligned
, &math_size
);
237 *fpstate
= (struct _fpstate_32 __user
*) sp
;
238 if (copy_fpstate_to_sigframe(*fpstate
, (void __user
*)fx_aligned
,
240 return (void __user
*) -1L;
244 /* Align the stack pointer according to the i386 ABI,
245 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
246 sp
= ((sp
+ 4) & -16ul) - 4;
247 return (void __user
*) sp
;
250 int ia32_setup_frame(int sig
, struct ksignal
*ksig
,
251 compat_sigset_t
*set
, struct pt_regs
*regs
)
253 struct sigframe_ia32 __user
*frame
;
254 void __user
*restorer
;
256 void __user
*fpstate
= NULL
;
258 /* copy_to_user optimizes that into a single 8 byte store */
259 static const struct {
263 } __attribute__((packed
)) code
= {
264 0xb858, /* popl %eax ; movl $...,%eax */
266 0x80cd, /* int $0x80 */
269 frame
= get_sigframe(ksig
, regs
, sizeof(*frame
), &fpstate
);
271 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
274 if (__put_user(sig
, &frame
->sig
))
277 if (ia32_setup_sigcontext(&frame
->sc
, fpstate
, regs
, set
->sig
[0]))
280 if (_COMPAT_NSIG_WORDS
> 1) {
281 if (__copy_to_user(frame
->extramask
, &set
->sig
[1],
282 sizeof(frame
->extramask
)))
286 if (ksig
->ka
.sa
.sa_flags
& SA_RESTORER
) {
287 restorer
= ksig
->ka
.sa
.sa_restorer
;
289 /* Return stub is in 32bit vsyscall page */
290 if (current
->mm
->context
.vdso
)
291 restorer
= current
->mm
->context
.vdso
+
292 vdso_image_32
.sym___kernel_sigreturn
;
294 restorer
= &frame
->retcode
;
298 put_user_ex(ptr_to_compat(restorer
), &frame
->pretcode
);
301 * These are actually not used anymore, but left because some
302 * gdb versions depend on them as a marker.
304 put_user_ex(*((u64
*)&code
), (u64 __user
*)frame
->retcode
);
305 } put_user_catch(err
);
310 /* Set up registers for signal handler */
311 regs
->sp
= (unsigned long) frame
;
312 regs
->ip
= (unsigned long) ksig
->ka
.sa
.sa_handler
;
314 /* Make -mregparm=3 work */
319 loadsegment(ds
, __USER32_DS
);
320 loadsegment(es
, __USER32_DS
);
322 regs
->cs
= __USER32_CS
;
323 regs
->ss
= __USER32_DS
;
328 int ia32_setup_rt_frame(int sig
, struct ksignal
*ksig
,
329 compat_sigset_t
*set
, struct pt_regs
*regs
)
331 struct rt_sigframe_ia32 __user
*frame
;
332 void __user
*restorer
;
334 void __user
*fpstate
= NULL
;
336 /* __copy_to_user optimizes that into a single 8 byte store */
337 static const struct {
342 } __attribute__((packed
)) code
= {
344 __NR_ia32_rt_sigreturn
,
349 frame
= get_sigframe(ksig
, regs
, sizeof(*frame
), &fpstate
);
351 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
355 put_user_ex(sig
, &frame
->sig
);
356 put_user_ex(ptr_to_compat(&frame
->info
), &frame
->pinfo
);
357 put_user_ex(ptr_to_compat(&frame
->uc
), &frame
->puc
);
359 /* Create the ucontext. */
361 put_user_ex(UC_FP_XSTATE
, &frame
->uc
.uc_flags
);
363 put_user_ex(0, &frame
->uc
.uc_flags
);
364 put_user_ex(0, &frame
->uc
.uc_link
);
365 compat_save_altstack_ex(&frame
->uc
.uc_stack
, regs
->sp
);
367 if (ksig
->ka
.sa
.sa_flags
& SA_RESTORER
)
368 restorer
= ksig
->ka
.sa
.sa_restorer
;
370 restorer
= current
->mm
->context
.vdso
+
371 vdso_image_32
.sym___kernel_rt_sigreturn
;
372 put_user_ex(ptr_to_compat(restorer
), &frame
->pretcode
);
375 * Not actually used anymore, but left because some gdb
378 put_user_ex(*((u64
*)&code
), (u64 __user
*)frame
->retcode
);
379 } put_user_catch(err
);
381 err
|= copy_siginfo_to_user32(&frame
->info
, &ksig
->info
);
382 err
|= ia32_setup_sigcontext(&frame
->uc
.uc_mcontext
, fpstate
,
384 err
|= __copy_to_user(&frame
->uc
.uc_sigmask
, set
, sizeof(*set
));
389 /* Set up registers for signal handler */
390 regs
->sp
= (unsigned long) frame
;
391 regs
->ip
= (unsigned long) ksig
->ka
.sa
.sa_handler
;
393 /* Make -mregparm=3 work */
395 regs
->dx
= (unsigned long) &frame
->info
;
396 regs
->cx
= (unsigned long) &frame
->uc
;
398 loadsegment(ds
, __USER32_DS
);
399 loadsegment(es
, __USER32_DS
);
401 regs
->cs
= __USER32_CS
;
402 regs
->ss
= __USER32_DS
;