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 <linux/syscalls.h>
25 #include <asm/ucontext.h>
26 #include <linux/uaccess.h>
27 #include <asm/fpu/internal.h>
28 #include <asm/fpu/signal.h>
29 #include <asm/ptrace.h>
30 #include <asm/ia32_unistd.h>
31 #include <asm/user32.h>
32 #include <uapi/asm/sigcontext.h>
33 #include <asm/proto.h>
35 #include <asm/sigframe.h>
36 #include <asm/sighandling.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 = (seg) | 3; \
66 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;
79 /* Always make any pending restarted system calls return -EINTR */
80 current
->restart_block
.fn
= do_no_restart_syscall
;
88 COPY(di
); COPY(si
); COPY(bp
); COPY(sp
); COPY(bx
);
89 COPY(dx
); COPY(cx
); COPY(ip
); COPY(ax
);
90 /* Don't touch extended registers */
95 get_user_ex(tmpflags
, &sc
->flags
);
96 regs
->flags
= (regs
->flags
& ~FIX_EFLAGS
) | (tmpflags
& FIX_EFLAGS
);
97 /* disable syscall checks */
100 get_user_ex(tmp
, &sc
->fpstate
);
101 buf
= compat_ptr(tmp
);
102 } get_user_catch(err
);
105 * Reload fs and gs if they have changed in the signal
106 * handler. This does not handle long fs/gs base changes in
107 * the handler, but does not clobber them at least in the
115 err
|= fpu__restore_sig(buf
, 1);
120 COMPAT_SYSCALL_DEFINE0(sigreturn
)
122 struct pt_regs
*regs
= current_pt_regs();
123 struct sigframe_ia32 __user
*frame
= (struct sigframe_ia32 __user
*)(regs
->sp
-8);
126 if (!access_ok(frame
, sizeof(*frame
)))
128 if (__get_user(set
.sig
[0], &frame
->sc
.oldmask
)
129 || (_COMPAT_NSIG_WORDS
> 1
130 && __copy_from_user((((char *) &set
.sig
) + 4),
132 sizeof(frame
->extramask
))))
135 set_current_blocked(&set
);
137 if (ia32_restore_sigcontext(regs
, &frame
->sc
))
142 signal_fault(regs
, frame
, "32bit sigreturn");
146 COMPAT_SYSCALL_DEFINE0(rt_sigreturn
)
148 struct pt_regs
*regs
= current_pt_regs();
149 struct rt_sigframe_ia32 __user
*frame
;
152 frame
= (struct rt_sigframe_ia32 __user
*)(regs
->sp
- 4);
154 if (!access_ok(frame
, sizeof(*frame
)))
156 if (__copy_from_user(&set
, &frame
->uc
.uc_sigmask
, sizeof(set
)))
159 set_current_blocked(&set
);
161 if (ia32_restore_sigcontext(regs
, &frame
->uc
.uc_mcontext
))
164 if (compat_restore_altstack(&frame
->uc
.uc_stack
))
170 signal_fault(regs
, frame
, "32bit rt sigreturn");
175 * Set up a signal frame.
178 static int ia32_setup_sigcontext(struct sigcontext_32 __user
*sc
,
179 void __user
*fpstate
,
180 struct pt_regs
*regs
, unsigned int mask
)
185 put_user_ex(get_user_seg(gs
), (unsigned int __user
*)&sc
->gs
);
186 put_user_ex(get_user_seg(fs
), (unsigned int __user
*)&sc
->fs
);
187 put_user_ex(get_user_seg(ds
), (unsigned int __user
*)&sc
->ds
);
188 put_user_ex(get_user_seg(es
), (unsigned int __user
*)&sc
->es
);
190 put_user_ex(regs
->di
, &sc
->di
);
191 put_user_ex(regs
->si
, &sc
->si
);
192 put_user_ex(regs
->bp
, &sc
->bp
);
193 put_user_ex(regs
->sp
, &sc
->sp
);
194 put_user_ex(regs
->bx
, &sc
->bx
);
195 put_user_ex(regs
->dx
, &sc
->dx
);
196 put_user_ex(regs
->cx
, &sc
->cx
);
197 put_user_ex(regs
->ax
, &sc
->ax
);
198 put_user_ex(current
->thread
.trap_nr
, &sc
->trapno
);
199 put_user_ex(current
->thread
.error_code
, &sc
->err
);
200 put_user_ex(regs
->ip
, &sc
->ip
);
201 put_user_ex(regs
->cs
, (unsigned int __user
*)&sc
->cs
);
202 put_user_ex(regs
->flags
, &sc
->flags
);
203 put_user_ex(regs
->sp
, &sc
->sp_at_signal
);
204 put_user_ex(regs
->ss
, (unsigned int __user
*)&sc
->ss
);
206 put_user_ex(ptr_to_compat(fpstate
), &sc
->fpstate
);
208 /* non-iBCS2 extensions.. */
209 put_user_ex(mask
, &sc
->oldmask
);
210 put_user_ex(current
->thread
.cr2
, &sc
->cr2
);
211 } put_user_catch(err
);
217 * Determine which stack to use..
219 static void __user
*get_sigframe(struct ksignal
*ksig
, struct pt_regs
*regs
,
221 void __user
**fpstate
)
223 unsigned long sp
, fx_aligned
, math_size
;
225 /* Default to using normal stack */
228 /* This is the X/Open sanctioned signal stack switching. */
229 if (ksig
->ka
.sa
.sa_flags
& SA_ONSTACK
)
230 sp
= sigsp(sp
, ksig
);
231 /* This is the legacy signal stack switching. */
232 else if (regs
->ss
!= __USER32_DS
&&
233 !(ksig
->ka
.sa
.sa_flags
& SA_RESTORER
) &&
234 ksig
->ka
.sa
.sa_restorer
)
235 sp
= (unsigned long) ksig
->ka
.sa
.sa_restorer
;
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;
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(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(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. */
360 if (static_cpu_has(X86_FEATURE_XSAVE
))
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
, false);
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
;