1 // SPDX-License-Identifier: GPL-2.0
3 * linux/arch/x86_64/ia32/ia32_signal.c
5 * Copyright (C) 1991, 1992 Linus Torvalds
7 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
8 * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes
9 * 2000-12-* x86-64 compatibility mode signal handling by Andi Kleen
12 #include <linux/sched.h>
13 #include <linux/sched/task_stack.h>
15 #include <linux/smp.h>
16 #include <linux/kernel.h>
17 #include <linux/errno.h>
18 #include <linux/wait.h>
19 #include <linux/unistd.h>
20 #include <linux/stddef.h>
21 #include <linux/personality.h>
22 #include <linux/compat.h>
23 #include <linux/binfmts.h>
24 #include <asm/ucontext.h>
25 #include <linux/uaccess.h>
26 #include <asm/fpu/internal.h>
27 #include <asm/fpu/signal.h>
28 #include <asm/ptrace.h>
29 #include <asm/ia32_unistd.h>
30 #include <asm/user32.h>
31 #include <uapi/asm/sigcontext.h>
32 #include <asm/proto.h>
34 #include <asm/sigframe.h>
35 #include <asm/sighandling.h>
36 #include <asm/sys_ia32.h>
40 * Do a signal return; undo the signal stack.
42 #define loadsegment_gs(v) load_gs_index(v)
43 #define loadsegment_fs(v) loadsegment(fs, v)
44 #define loadsegment_ds(v) loadsegment(ds, v)
45 #define loadsegment_es(v) loadsegment(es, v)
47 #define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
48 #define set_user_seg(seg, v) loadsegment_##seg(v)
51 get_user_ex(regs->x, &sc->x); \
54 #define GET_SEG(seg) ({ \
56 get_user_ex(tmp, &sc->seg); \
60 #define COPY_SEG_CPL3(seg) do { \
61 regs->seg = GET_SEG(seg) | 3; \
64 #define RELOAD_SEG(seg) { \
65 unsigned int pre = GET_SEG(seg); \
66 unsigned int cur = get_user_seg(seg); \
69 set_user_seg(seg, pre); \
72 static int ia32_restore_sigcontext(struct pt_regs
*regs
,
73 struct sigcontext_32 __user
*sc
)
75 unsigned int tmpflags
, err
= 0;
79 /* Always make any pending restarted system calls return -EINTR */
80 current
->restart_block
.fn
= do_no_restart_syscall
;
84 * Reload fs and gs if they have changed in the signal
85 * handler. This does not handle long fs/gs base changes in
86 * the handler, but does not clobber them at least in the
94 COPY(di
); COPY(si
); COPY(bp
); COPY(sp
); COPY(bx
);
95 COPY(dx
); COPY(cx
); COPY(ip
); COPY(ax
);
96 /* Don't touch extended registers */
101 get_user_ex(tmpflags
, &sc
->flags
);
102 regs
->flags
= (regs
->flags
& ~FIX_EFLAGS
) | (tmpflags
& FIX_EFLAGS
);
103 /* disable syscall checks */
106 get_user_ex(tmp
, &sc
->fpstate
);
107 buf
= compat_ptr(tmp
);
108 } get_user_catch(err
);
110 err
|= fpu__restore_sig(buf
, 1);
117 asmlinkage
long sys32_sigreturn(void)
119 struct pt_regs
*regs
= current_pt_regs();
120 struct sigframe_ia32 __user
*frame
= (struct sigframe_ia32 __user
*)(regs
->sp
-8);
123 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
125 if (__get_user(set
.sig
[0], &frame
->sc
.oldmask
)
126 || (_COMPAT_NSIG_WORDS
> 1
127 && __copy_from_user((((char *) &set
.sig
) + 4),
129 sizeof(frame
->extramask
))))
132 set_current_blocked(&set
);
134 if (ia32_restore_sigcontext(regs
, &frame
->sc
))
139 signal_fault(regs
, frame
, "32bit sigreturn");
143 asmlinkage
long sys32_rt_sigreturn(void)
145 struct pt_regs
*regs
= current_pt_regs();
146 struct rt_sigframe_ia32 __user
*frame
;
149 frame
= (struct rt_sigframe_ia32 __user
*)(regs
->sp
- 4);
151 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
153 if (__copy_from_user(&set
, &frame
->uc
.uc_sigmask
, sizeof(set
)))
156 set_current_blocked(&set
);
158 if (ia32_restore_sigcontext(regs
, &frame
->uc
.uc_mcontext
))
161 if (compat_restore_altstack(&frame
->uc
.uc_stack
))
167 signal_fault(regs
, frame
, "32bit rt sigreturn");
172 * Set up a signal frame.
175 static int ia32_setup_sigcontext(struct sigcontext_32 __user
*sc
,
176 void __user
*fpstate
,
177 struct pt_regs
*regs
, unsigned int mask
)
182 put_user_ex(get_user_seg(gs
), (unsigned int __user
*)&sc
->gs
);
183 put_user_ex(get_user_seg(fs
), (unsigned int __user
*)&sc
->fs
);
184 put_user_ex(get_user_seg(ds
), (unsigned int __user
*)&sc
->ds
);
185 put_user_ex(get_user_seg(es
), (unsigned int __user
*)&sc
->es
);
187 put_user_ex(regs
->di
, &sc
->di
);
188 put_user_ex(regs
->si
, &sc
->si
);
189 put_user_ex(regs
->bp
, &sc
->bp
);
190 put_user_ex(regs
->sp
, &sc
->sp
);
191 put_user_ex(regs
->bx
, &sc
->bx
);
192 put_user_ex(regs
->dx
, &sc
->dx
);
193 put_user_ex(regs
->cx
, &sc
->cx
);
194 put_user_ex(regs
->ax
, &sc
->ax
);
195 put_user_ex(current
->thread
.trap_nr
, &sc
->trapno
);
196 put_user_ex(current
->thread
.error_code
, &sc
->err
);
197 put_user_ex(regs
->ip
, &sc
->ip
);
198 put_user_ex(regs
->cs
, (unsigned int __user
*)&sc
->cs
);
199 put_user_ex(regs
->flags
, &sc
->flags
);
200 put_user_ex(regs
->sp
, &sc
->sp_at_signal
);
201 put_user_ex(regs
->ss
, (unsigned int __user
*)&sc
->ss
);
203 put_user_ex(ptr_to_compat(fpstate
), &sc
->fpstate
);
205 /* non-iBCS2 extensions.. */
206 put_user_ex(mask
, &sc
->oldmask
);
207 put_user_ex(current
->thread
.cr2
, &sc
->cr2
);
208 } put_user_catch(err
);
214 * Determine which stack to use..
216 static void __user
*get_sigframe(struct ksignal
*ksig
, struct pt_regs
*regs
,
218 void __user
**fpstate
)
220 struct fpu
*fpu
= ¤t
->thread
.fpu
;
223 /* Default to using normal stack */
226 /* This is the X/Open sanctioned signal stack switching. */
227 if (ksig
->ka
.sa
.sa_flags
& SA_ONSTACK
)
228 sp
= sigsp(sp
, ksig
);
229 /* This is the legacy signal stack switching. */
230 else if (regs
->ss
!= __USER32_DS
&&
231 !(ksig
->ka
.sa
.sa_flags
& SA_RESTORER
) &&
232 ksig
->ka
.sa
.sa_restorer
)
233 sp
= (unsigned long) ksig
->ka
.sa
.sa_restorer
;
235 if (fpu
->initialized
) {
236 unsigned long fx_aligned
, math_size
;
238 sp
= fpu__alloc_mathframe(sp
, 1, &fx_aligned
, &math_size
);
239 *fpstate
= (struct _fpstate_32 __user
*) sp
;
240 if (copy_fpstate_to_sigframe(*fpstate
, (void __user
*)fx_aligned
,
242 return (void __user
*) -1L;
246 /* Align the stack pointer according to the i386 ABI,
247 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
248 sp
= ((sp
+ 4) & -16ul) - 4;
249 return (void __user
*) sp
;
252 int ia32_setup_frame(int sig
, struct ksignal
*ksig
,
253 compat_sigset_t
*set
, struct pt_regs
*regs
)
255 struct sigframe_ia32 __user
*frame
;
256 void __user
*restorer
;
258 void __user
*fpstate
= NULL
;
260 /* copy_to_user optimizes that into a single 8 byte store */
261 static const struct {
265 } __attribute__((packed
)) code
= {
266 0xb858, /* popl %eax ; movl $...,%eax */
268 0x80cd, /* int $0x80 */
271 frame
= get_sigframe(ksig
, regs
, sizeof(*frame
), &fpstate
);
273 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
276 if (__put_user(sig
, &frame
->sig
))
279 if (ia32_setup_sigcontext(&frame
->sc
, fpstate
, regs
, set
->sig
[0]))
282 if (_COMPAT_NSIG_WORDS
> 1) {
283 if (__copy_to_user(frame
->extramask
, &set
->sig
[1],
284 sizeof(frame
->extramask
)))
288 if (ksig
->ka
.sa
.sa_flags
& SA_RESTORER
) {
289 restorer
= ksig
->ka
.sa
.sa_restorer
;
291 /* Return stub is in 32bit vsyscall page */
292 if (current
->mm
->context
.vdso
)
293 restorer
= current
->mm
->context
.vdso
+
294 vdso_image_32
.sym___kernel_sigreturn
;
296 restorer
= &frame
->retcode
;
300 put_user_ex(ptr_to_compat(restorer
), &frame
->pretcode
);
303 * These are actually not used anymore, but left because some
304 * gdb versions depend on them as a marker.
306 put_user_ex(*((u64
*)&code
), (u64 __user
*)frame
->retcode
);
307 } put_user_catch(err
);
312 /* Set up registers for signal handler */
313 regs
->sp
= (unsigned long) frame
;
314 regs
->ip
= (unsigned long) ksig
->ka
.sa
.sa_handler
;
316 /* Make -mregparm=3 work */
321 loadsegment(ds
, __USER32_DS
);
322 loadsegment(es
, __USER32_DS
);
324 regs
->cs
= __USER32_CS
;
325 regs
->ss
= __USER32_DS
;
330 int ia32_setup_rt_frame(int sig
, struct ksignal
*ksig
,
331 compat_sigset_t
*set
, struct pt_regs
*regs
)
333 struct rt_sigframe_ia32 __user
*frame
;
334 void __user
*restorer
;
336 void __user
*fpstate
= NULL
;
338 /* __copy_to_user optimizes that into a single 8 byte store */
339 static const struct {
344 } __attribute__((packed
)) code
= {
346 __NR_ia32_rt_sigreturn
,
351 frame
= get_sigframe(ksig
, regs
, sizeof(*frame
), &fpstate
);
353 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
357 put_user_ex(sig
, &frame
->sig
);
358 put_user_ex(ptr_to_compat(&frame
->info
), &frame
->pinfo
);
359 put_user_ex(ptr_to_compat(&frame
->uc
), &frame
->puc
);
361 /* Create the ucontext. */
362 if (boot_cpu_has(X86_FEATURE_XSAVE
))
363 put_user_ex(UC_FP_XSTATE
, &frame
->uc
.uc_flags
);
365 put_user_ex(0, &frame
->uc
.uc_flags
);
366 put_user_ex(0, &frame
->uc
.uc_link
);
367 compat_save_altstack_ex(&frame
->uc
.uc_stack
, regs
->sp
);
369 if (ksig
->ka
.sa
.sa_flags
& SA_RESTORER
)
370 restorer
= ksig
->ka
.sa
.sa_restorer
;
372 restorer
= current
->mm
->context
.vdso
+
373 vdso_image_32
.sym___kernel_rt_sigreturn
;
374 put_user_ex(ptr_to_compat(restorer
), &frame
->pretcode
);
377 * Not actually used anymore, but left because some gdb
380 put_user_ex(*((u64
*)&code
), (u64 __user
*)frame
->retcode
);
381 } put_user_catch(err
);
383 err
|= __copy_siginfo_to_user32(&frame
->info
, &ksig
->info
, false);
384 err
|= ia32_setup_sigcontext(&frame
->uc
.uc_mcontext
, fpstate
,
386 err
|= __copy_to_user(&frame
->uc
.uc_sigmask
, set
, sizeof(*set
));
391 /* Set up registers for signal handler */
392 regs
->sp
= (unsigned long) frame
;
393 regs
->ip
= (unsigned long) ksig
->ka
.sa
.sa_handler
;
395 /* Make -mregparm=3 work */
397 regs
->dx
= (unsigned long) &frame
->info
;
398 regs
->cx
= (unsigned long) &frame
->uc
;
400 loadsegment(ds
, __USER32_DS
);
401 loadsegment(es
, __USER32_DS
);
403 regs
->cs
= __USER32_CS
;
404 regs
->ss
= __USER32_DS
;