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>
12 #include <linux/sched/task_stack.h>
14 #include <linux/smp.h>
15 #include <linux/kernel.h>
16 #include <linux/errno.h>
17 #include <linux/wait.h>
18 #include <linux/unistd.h>
19 #include <linux/stddef.h>
20 #include <linux/personality.h>
21 #include <linux/compat.h>
22 #include <linux/binfmts.h>
23 #include <asm/ucontext.h>
24 #include <linux/uaccess.h>
25 #include <asm/fpu/internal.h>
26 #include <asm/fpu/signal.h>
27 #include <asm/ptrace.h>
28 #include <asm/ia32_unistd.h>
29 #include <asm/user32.h>
30 #include <uapi/asm/sigcontext.h>
31 #include <asm/proto.h>
33 #include <asm/sigframe.h>
34 #include <asm/sighandling.h>
35 #include <asm/sys_ia32.h>
39 * Do a signal return; undo the signal stack.
41 #define loadsegment_gs(v) load_gs_index(v)
42 #define loadsegment_fs(v) loadsegment(fs, v)
43 #define loadsegment_ds(v) loadsegment(ds, v)
44 #define loadsegment_es(v) loadsegment(es, v)
46 #define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
47 #define set_user_seg(seg, v) loadsegment_##seg(v)
50 get_user_ex(regs->x, &sc->x); \
53 #define GET_SEG(seg) ({ \
55 get_user_ex(tmp, &sc->seg); \
59 #define COPY_SEG_CPL3(seg) do { \
60 regs->seg = GET_SEG(seg) | 3; \
63 #define RELOAD_SEG(seg) { \
64 unsigned int pre = GET_SEG(seg); \
65 unsigned int cur = get_user_seg(seg); \
68 set_user_seg(seg, pre); \
71 static int ia32_restore_sigcontext(struct pt_regs
*regs
,
72 struct sigcontext_32 __user
*sc
)
74 unsigned int tmpflags
, err
= 0;
78 /* Always make any pending restarted system calls return -EINTR */
79 current
->restart_block
.fn
= do_no_restart_syscall
;
83 * Reload fs and gs if they have changed in the signal
84 * handler. This does not handle long fs/gs base changes in
85 * the handler, but does not clobber them at least in the
93 COPY(di
); COPY(si
); COPY(bp
); COPY(sp
); COPY(bx
);
94 COPY(dx
); COPY(cx
); COPY(ip
); COPY(ax
);
95 /* Don't touch extended registers */
100 get_user_ex(tmpflags
, &sc
->flags
);
101 regs
->flags
= (regs
->flags
& ~FIX_EFLAGS
) | (tmpflags
& FIX_EFLAGS
);
102 /* disable syscall checks */
105 get_user_ex(tmp
, &sc
->fpstate
);
106 buf
= compat_ptr(tmp
);
107 } get_user_catch(err
);
109 err
|= fpu__restore_sig(buf
, 1);
116 asmlinkage
long sys32_sigreturn(void)
118 struct pt_regs
*regs
= current_pt_regs();
119 struct sigframe_ia32 __user
*frame
= (struct sigframe_ia32 __user
*)(regs
->sp
-8);
122 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
124 if (__get_user(set
.sig
[0], &frame
->sc
.oldmask
)
125 || (_COMPAT_NSIG_WORDS
> 1
126 && __copy_from_user((((char *) &set
.sig
) + 4),
128 sizeof(frame
->extramask
))))
131 set_current_blocked(&set
);
133 if (ia32_restore_sigcontext(regs
, &frame
->sc
))
138 signal_fault(regs
, frame
, "32bit sigreturn");
142 asmlinkage
long sys32_rt_sigreturn(void)
144 struct pt_regs
*regs
= current_pt_regs();
145 struct rt_sigframe_ia32 __user
*frame
;
148 frame
= (struct rt_sigframe_ia32 __user
*)(regs
->sp
- 4);
150 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
152 if (__copy_from_user(&set
, &frame
->uc
.uc_sigmask
, sizeof(set
)))
155 set_current_blocked(&set
);
157 if (ia32_restore_sigcontext(regs
, &frame
->uc
.uc_mcontext
))
160 if (compat_restore_altstack(&frame
->uc
.uc_stack
))
166 signal_fault(regs
, frame
, "32bit rt sigreturn");
171 * Set up a signal frame.
174 static int ia32_setup_sigcontext(struct sigcontext_32 __user
*sc
,
175 void __user
*fpstate
,
176 struct pt_regs
*regs
, unsigned int mask
)
181 put_user_ex(get_user_seg(gs
), (unsigned int __user
*)&sc
->gs
);
182 put_user_ex(get_user_seg(fs
), (unsigned int __user
*)&sc
->fs
);
183 put_user_ex(get_user_seg(ds
), (unsigned int __user
*)&sc
->ds
);
184 put_user_ex(get_user_seg(es
), (unsigned int __user
*)&sc
->es
);
186 put_user_ex(regs
->di
, &sc
->di
);
187 put_user_ex(regs
->si
, &sc
->si
);
188 put_user_ex(regs
->bp
, &sc
->bp
);
189 put_user_ex(regs
->sp
, &sc
->sp
);
190 put_user_ex(regs
->bx
, &sc
->bx
);
191 put_user_ex(regs
->dx
, &sc
->dx
);
192 put_user_ex(regs
->cx
, &sc
->cx
);
193 put_user_ex(regs
->ax
, &sc
->ax
);
194 put_user_ex(current
->thread
.trap_nr
, &sc
->trapno
);
195 put_user_ex(current
->thread
.error_code
, &sc
->err
);
196 put_user_ex(regs
->ip
, &sc
->ip
);
197 put_user_ex(regs
->cs
, (unsigned int __user
*)&sc
->cs
);
198 put_user_ex(regs
->flags
, &sc
->flags
);
199 put_user_ex(regs
->sp
, &sc
->sp_at_signal
);
200 put_user_ex(regs
->ss
, (unsigned int __user
*)&sc
->ss
);
202 put_user_ex(ptr_to_compat(fpstate
), &sc
->fpstate
);
204 /* non-iBCS2 extensions.. */
205 put_user_ex(mask
, &sc
->oldmask
);
206 put_user_ex(current
->thread
.cr2
, &sc
->cr2
);
207 } put_user_catch(err
);
213 * Determine which stack to use..
215 static void __user
*get_sigframe(struct ksignal
*ksig
, struct pt_regs
*regs
,
217 void __user
**fpstate
)
219 struct fpu
*fpu
= ¤t
->thread
.fpu
;
222 /* Default to using normal stack */
225 /* This is the X/Open sanctioned signal stack switching. */
226 if (ksig
->ka
.sa
.sa_flags
& SA_ONSTACK
)
227 sp
= sigsp(sp
, ksig
);
228 /* This is the legacy signal stack switching. */
229 else if ((regs
->ss
& 0xffff) != __USER32_DS
&&
230 !(ksig
->ka
.sa
.sa_flags
& SA_RESTORER
) &&
231 ksig
->ka
.sa
.sa_restorer
)
232 sp
= (unsigned long) ksig
->ka
.sa
.sa_restorer
;
234 if (fpu
->fpstate_active
) {
235 unsigned long fx_aligned
, math_size
;
237 sp
= fpu__alloc_mathframe(sp
, 1, &fx_aligned
, &math_size
);
238 *fpstate
= (struct _fpstate_32 __user
*) sp
;
239 if (copy_fpstate_to_sigframe(*fpstate
, (void __user
*)fx_aligned
,
241 return (void __user
*) -1L;
245 /* Align the stack pointer according to the i386 ABI,
246 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
247 sp
= ((sp
+ 4) & -16ul) - 4;
248 return (void __user
*) sp
;
251 int ia32_setup_frame(int sig
, struct ksignal
*ksig
,
252 compat_sigset_t
*set
, struct pt_regs
*regs
)
254 struct sigframe_ia32 __user
*frame
;
255 void __user
*restorer
;
257 void __user
*fpstate
= NULL
;
259 /* copy_to_user optimizes that into a single 8 byte store */
260 static const struct {
264 } __attribute__((packed
)) code
= {
265 0xb858, /* popl %eax ; movl $...,%eax */
267 0x80cd, /* int $0x80 */
270 frame
= get_sigframe(ksig
, regs
, sizeof(*frame
), &fpstate
);
272 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
275 if (__put_user(sig
, &frame
->sig
))
278 if (ia32_setup_sigcontext(&frame
->sc
, fpstate
, regs
, set
->sig
[0]))
281 if (_COMPAT_NSIG_WORDS
> 1) {
282 if (__copy_to_user(frame
->extramask
, &set
->sig
[1],
283 sizeof(frame
->extramask
)))
287 if (ksig
->ka
.sa
.sa_flags
& SA_RESTORER
) {
288 restorer
= ksig
->ka
.sa
.sa_restorer
;
290 /* Return stub is in 32bit vsyscall page */
291 if (current
->mm
->context
.vdso
)
292 restorer
= current
->mm
->context
.vdso
+
293 vdso_image_32
.sym___kernel_sigreturn
;
295 restorer
= &frame
->retcode
;
299 put_user_ex(ptr_to_compat(restorer
), &frame
->pretcode
);
302 * These are actually not used anymore, but left because some
303 * gdb versions depend on them as a marker.
305 put_user_ex(*((u64
*)&code
), (u64 __user
*)frame
->retcode
);
306 } put_user_catch(err
);
311 /* Set up registers for signal handler */
312 regs
->sp
= (unsigned long) frame
;
313 regs
->ip
= (unsigned long) ksig
->ka
.sa
.sa_handler
;
315 /* Make -mregparm=3 work */
320 loadsegment(ds
, __USER32_DS
);
321 loadsegment(es
, __USER32_DS
);
323 regs
->cs
= __USER32_CS
;
324 regs
->ss
= __USER32_DS
;
329 int ia32_setup_rt_frame(int sig
, struct ksignal
*ksig
,
330 compat_sigset_t
*set
, struct pt_regs
*regs
)
332 struct rt_sigframe_ia32 __user
*frame
;
333 void __user
*restorer
;
335 void __user
*fpstate
= NULL
;
337 /* __copy_to_user optimizes that into a single 8 byte store */
338 static const struct {
343 } __attribute__((packed
)) code
= {
345 __NR_ia32_rt_sigreturn
,
350 frame
= get_sigframe(ksig
, regs
, sizeof(*frame
), &fpstate
);
352 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
356 put_user_ex(sig
, &frame
->sig
);
357 put_user_ex(ptr_to_compat(&frame
->info
), &frame
->pinfo
);
358 put_user_ex(ptr_to_compat(&frame
->uc
), &frame
->puc
);
360 /* Create the ucontext. */
361 if (boot_cpu_has(X86_FEATURE_XSAVE
))
362 put_user_ex(UC_FP_XSTATE
, &frame
->uc
.uc_flags
);
364 put_user_ex(0, &frame
->uc
.uc_flags
);
365 put_user_ex(0, &frame
->uc
.uc_link
);
366 compat_save_altstack_ex(&frame
->uc
.uc_stack
, regs
->sp
);
368 if (ksig
->ka
.sa
.sa_flags
& SA_RESTORER
)
369 restorer
= ksig
->ka
.sa
.sa_restorer
;
371 restorer
= current
->mm
->context
.vdso
+
372 vdso_image_32
.sym___kernel_rt_sigreturn
;
373 put_user_ex(ptr_to_compat(restorer
), &frame
->pretcode
);
376 * Not actually used anymore, but left because some gdb
379 put_user_ex(*((u64
*)&code
), (u64 __user
*)frame
->retcode
);
380 } put_user_catch(err
);
382 err
|= __copy_siginfo_to_user32(&frame
->info
, &ksig
->info
, false);
383 err
|= ia32_setup_sigcontext(&frame
->uc
.uc_mcontext
, fpstate
,
385 err
|= __copy_to_user(&frame
->uc
.uc_sigmask
, set
, sizeof(*set
));
390 /* Set up registers for signal handler */
391 regs
->sp
= (unsigned long) frame
;
392 regs
->ip
= (unsigned long) ksig
->ka
.sa
.sa_handler
;
394 /* Make -mregparm=3 work */
396 regs
->dx
= (unsigned long) &frame
->info
;
397 regs
->cx
= (unsigned long) &frame
->uc
;
399 loadsegment(ds
, __USER32_DS
);
400 loadsegment(es
, __USER32_DS
);
402 regs
->cs
= __USER32_CS
;
403 regs
->ss
= __USER32_DS
;