x86/fpu: Split out fpu/signal.h from fpu/internal.h for signal frame handling functions
[deliverable/linux.git] / arch / x86 / ia32 / ia32_signal.c
CommitLineData
1da177e4
LT
1/*
2 * linux/arch/x86_64/ia32/ia32_signal.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 *
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
1da177e4
LT
9 */
10
11#include <linux/sched.h>
12#include <linux/mm.h>
13#include <linux/smp.h>
1da177e4 14#include <linux/kernel.h>
1da177e4
LT
15#include <linux/errno.h>
16#include <linux/wait.h>
1da177e4
LT
17#include <linux/unistd.h>
18#include <linux/stddef.h>
19#include <linux/personality.h>
20#include <linux/compat.h>
9fbbd4dd 21#include <linux/binfmts.h>
1da177e4
LT
22#include <asm/ucontext.h>
23#include <asm/uaccess.h>
78f7f1e5 24#include <asm/fpu/internal.h>
fcbc99c4 25#include <asm/fpu/signal.h>
1da177e4
LT
26#include <asm/ptrace.h>
27#include <asm/ia32_unistd.h>
28#include <asm/user32.h>
29#include <asm/sigcontext32.h>
1da177e4 30#include <asm/proto.h>
af65d648 31#include <asm/vdso.h>
d98f9d84 32#include <asm/sigframe.h>
f28f0c23 33#include <asm/sighandling.h>
2f06de06 34#include <asm/sys_ia32.h>
49b8c695 35#include <asm/smap.h>
d98f9d84 36
ce395960 37int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
1da177e4 38{
3b4b7570 39 int err = 0;
0b91f45b 40 bool ia32 = test_thread_flag(TIF_IA32);
99b9cdf7
TG
41
42 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
1da177e4
LT
43 return -EFAULT;
44
3b4b7570
HS
45 put_user_try {
46 /* If you change siginfo_t structure, please make sure that
47 this code is fixed accordingly.
48 It should never copy any pad contained in the structure
49 to avoid security leaks, but must copy the generic
50 3 ints plus the relevant union member. */
51 put_user_ex(from->si_signo, &to->si_signo);
52 put_user_ex(from->si_errno, &to->si_errno);
53 put_user_ex((short)from->si_code, &to->si_code);
54
55 if (from->si_code < 0) {
56 put_user_ex(from->si_pid, &to->si_pid);
57 put_user_ex(from->si_uid, &to->si_uid);
58 put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
59 } else {
60 /*
61 * First 32bits of unions are always present:
62 * si_pid === si_band === si_tid === si_addr(LS half)
63 */
64 put_user_ex(from->_sifields._pad[0],
65 &to->_sifields._pad[0]);
66 switch (from->si_code >> 16) {
67 case __SI_FAULT >> 16:
68 break;
a0727e8c
WD
69 case __SI_SYS >> 16:
70 put_user_ex(from->si_syscall, &to->si_syscall);
71 put_user_ex(from->si_arch, &to->si_arch);
72 break;
3b4b7570 73 case __SI_CHLD >> 16:
e7084fd5
PA
74 if (ia32) {
75 put_user_ex(from->si_utime, &to->si_utime);
76 put_user_ex(from->si_stime, &to->si_stime);
77 } else {
78 put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime);
79 put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime);
80 }
3b4b7570
HS
81 put_user_ex(from->si_status, &to->si_status);
82 /* FALL THROUGH */
83 default:
84 case __SI_KILL >> 16:
85 put_user_ex(from->si_uid, &to->si_uid);
86 break;
87 case __SI_POLL >> 16:
88 put_user_ex(from->si_fd, &to->si_fd);
89 break;
90 case __SI_TIMER >> 16:
91 put_user_ex(from->si_overrun, &to->si_overrun);
92 put_user_ex(ptr_to_compat(from->si_ptr),
93 &to->si_ptr);
94 break;
95 /* This is not generated by the kernel as of now. */
96 case __SI_RT >> 16:
97 case __SI_MESGQ >> 16:
98 put_user_ex(from->si_uid, &to->si_uid);
99 put_user_ex(from->si_int, &to->si_int);
100 break;
101 }
1da177e4 102 }
3b4b7570
HS
103 } put_user_catch(err);
104
1da177e4
LT
105 return err;
106}
107
108int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
109{
3b4b7570 110 int err = 0;
1da177e4 111 u32 ptr32;
99b9cdf7
TG
112
113 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
1da177e4
LT
114 return -EFAULT;
115
3b4b7570
HS
116 get_user_try {
117 get_user_ex(to->si_signo, &from->si_signo);
118 get_user_ex(to->si_errno, &from->si_errno);
119 get_user_ex(to->si_code, &from->si_code);
1da177e4 120
3b4b7570
HS
121 get_user_ex(to->si_pid, &from->si_pid);
122 get_user_ex(to->si_uid, &from->si_uid);
123 get_user_ex(ptr32, &from->si_ptr);
124 to->si_ptr = compat_ptr(ptr32);
125 } get_user_catch(err);
1da177e4
LT
126
127 return err;
128}
129
1da177e4
LT
130/*
131 * Do a signal return; undo the signal stack.
132 */
a967bb3f
HS
133#define loadsegment_gs(v) load_gs_index(v)
134#define loadsegment_fs(v) loadsegment(fs, v)
135#define loadsegment_ds(v) loadsegment(ds, v)
136#define loadsegment_es(v) loadsegment(es, v)
137
138#define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
139#define set_user_seg(seg, v) loadsegment_##seg(v)
140
b78a5b52 141#define COPY(x) { \
3b4b7570 142 get_user_ex(regs->x, &sc->x); \
1da177e4 143}
1da177e4 144
8801ead4
HS
145#define GET_SEG(seg) ({ \
146 unsigned short tmp; \
147 get_user_ex(tmp, &sc->seg); \
148 tmp; \
149})
150
151#define COPY_SEG_CPL3(seg) do { \
152 regs->seg = GET_SEG(seg) | 3; \
153} while (0)
1da177e4 154
8c6e5ce0 155#define RELOAD_SEG(seg) { \
a967bb3f
HS
156 unsigned int pre = GET_SEG(seg); \
157 unsigned int cur = get_user_seg(seg); \
8c6e5ce0
HS
158 pre |= 3; \
159 if (pre != cur) \
a967bb3f 160 set_user_seg(seg, pre); \
8c6e5ce0 161}
99b9cdf7
TG
162
163static int ia32_restore_sigcontext(struct pt_regs *regs,
6a3713f0 164 struct sigcontext_ia32 __user *sc)
99b9cdf7 165{
a967bb3f 166 unsigned int tmpflags, err = 0;
ab513701 167 void __user *buf;
99b9cdf7
TG
168 u32 tmp;
169
170 /* Always make any pending restarted system calls return -EINTR */
f56141e3 171 current->restart_block.fn = do_no_restart_syscall;
99b9cdf7 172
3b4b7570
HS
173 get_user_try {
174 /*
175 * Reload fs and gs if they have changed in the signal
176 * handler. This does not handle long fs/gs base changes in
177 * the handler, but does not clobber them at least in the
178 * normal case.
179 */
a967bb3f 180 RELOAD_SEG(gs);
3b4b7570
HS
181 RELOAD_SEG(fs);
182 RELOAD_SEG(ds);
183 RELOAD_SEG(es);
184
185 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
6a3713f0 186 COPY(dx); COPY(cx); COPY(ip); COPY(ax);
3b4b7570
HS
187 /* Don't touch extended registers */
188
189 COPY_SEG_CPL3(cs);
190 COPY_SEG_CPL3(ss);
191
192 get_user_ex(tmpflags, &sc->flags);
193 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
194 /* disable syscall checks */
195 regs->orig_ax = -1;
196
197 get_user_ex(tmp, &sc->fpstate);
198 buf = compat_ptr(tmp);
3b4b7570
HS
199 } get_user_catch(err);
200
9dfe99b7 201 err |= fpu__restore_sig(buf, 1);
5e88353d 202
1daeaa31
BG
203 force_iret();
204
1da177e4 205 return err;
1da177e4
LT
206}
207
3fe26fa3 208asmlinkage long sys32_sigreturn(void)
1da177e4 209{
3fe26fa3 210 struct pt_regs *regs = current_pt_regs();
3b0d29ee 211 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
1da177e4 212 sigset_t set;
1da177e4
LT
213
214 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
215 goto badframe;
216 if (__get_user(set.sig[0], &frame->sc.oldmask)
217 || (_COMPAT_NSIG_WORDS > 1
99b9cdf7
TG
218 && __copy_from_user((((char *) &set.sig) + 4),
219 &frame->extramask,
1da177e4
LT
220 sizeof(frame->extramask))))
221 goto badframe;
222
905f29e2 223 set_current_blocked(&set);
99b9cdf7 224
6a3713f0 225 if (ia32_restore_sigcontext(regs, &frame->sc))
1da177e4 226 goto badframe;
6a3713f0 227 return regs->ax;
1da177e4
LT
228
229badframe:
230 signal_fault(regs, frame, "32bit sigreturn");
231 return 0;
99b9cdf7 232}
1da177e4 233
3fe26fa3 234asmlinkage long sys32_rt_sigreturn(void)
1da177e4 235{
3fe26fa3 236 struct pt_regs *regs = current_pt_regs();
3b0d29ee 237 struct rt_sigframe_ia32 __user *frame;
1da177e4 238 sigset_t set;
1da177e4 239
3b0d29ee 240 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
1da177e4
LT
241
242 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
243 goto badframe;
244 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
245 goto badframe;
246
905f29e2 247 set_current_blocked(&set);
99b9cdf7 248
6a3713f0 249 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext))
1da177e4
LT
250 goto badframe;
251
90268439 252 if (compat_restore_altstack(&frame->uc.uc_stack))
1da177e4
LT
253 goto badframe;
254
6a3713f0 255 return regs->ax;
1da177e4
LT
256
257badframe:
99b9cdf7 258 signal_fault(regs, frame, "32bit rt sigreturn");
1da177e4 259 return 0;
99b9cdf7 260}
1da177e4
LT
261
262/*
263 * Set up a signal frame.
264 */
265
99b9cdf7 266static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
ab513701 267 void __user *fpstate,
99b9cdf7 268 struct pt_regs *regs, unsigned int mask)
1da177e4 269{
a967bb3f 270 int err = 0;
1da177e4 271
3b4b7570 272 put_user_try {
a967bb3f
HS
273 put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
274 put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
275 put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
276 put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
3b4b7570
HS
277
278 put_user_ex(regs->di, &sc->di);
279 put_user_ex(regs->si, &sc->si);
280 put_user_ex(regs->bp, &sc->bp);
281 put_user_ex(regs->sp, &sc->sp);
282 put_user_ex(regs->bx, &sc->bx);
283 put_user_ex(regs->dx, &sc->dx);
284 put_user_ex(regs->cx, &sc->cx);
285 put_user_ex(regs->ax, &sc->ax);
51e7dc70 286 put_user_ex(current->thread.trap_nr, &sc->trapno);
3b4b7570
HS
287 put_user_ex(current->thread.error_code, &sc->err);
288 put_user_ex(regs->ip, &sc->ip);
289 put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
290 put_user_ex(regs->flags, &sc->flags);
291 put_user_ex(regs->sp, &sc->sp_at_signal);
292 put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
293
294 put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
295
296 /* non-iBCS2 extensions.. */
297 put_user_ex(mask, &sc->oldmask);
298 put_user_ex(current->thread.cr2, &sc->cr2);
299 } put_user_catch(err);
1da177e4
LT
300
301 return err;
302}
303
304/*
305 * Determine which stack to use..
306 */
235b8022 307static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
3c1c7f10 308 size_t frame_size,
0ff8fef4 309 void __user **fpstate)
1da177e4 310{
c5bedc68 311 struct fpu *fpu = &current->thread.fpu;
65ea5b03 312 unsigned long sp;
1da177e4
LT
313
314 /* Default to using normal stack */
65ea5b03 315 sp = regs->sp;
1da177e4
LT
316
317 /* This is the X/Open sanctioned signal stack switching. */
235b8022
AV
318 if (ksig->ka.sa.sa_flags & SA_ONSTACK)
319 sp = sigsp(sp, ksig);
1da177e4 320 /* This is the legacy signal stack switching. */
8bee3f0a 321 else if ((regs->ss & 0xffff) != __USER32_DS &&
235b8022
AV
322 !(ksig->ka.sa.sa_flags & SA_RESTORER) &&
323 ksig->ka.sa.sa_restorer)
324 sp = (unsigned long) ksig->ka.sa.sa_restorer;
1da177e4 325
c5bedc68 326 if (fpu->fpstate_active) {
72a671ce
SS
327 unsigned long fx_aligned, math_size;
328
82c0e45e 329 sp = fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size);
0ff8fef4 330 *fpstate = (struct _fpstate_ia32 __user *) sp;
c8e14041 331 if (copy_fpstate_to_sigframe(*fpstate, (void __user *)fx_aligned,
72a671ce 332 math_size) < 0)
99ea1b93 333 return (void __user *) -1L;
3c1c7f10
SS
334 }
335
65ea5b03 336 sp -= frame_size;
d347f372
MO
337 /* Align the stack pointer according to the i386 ABI,
338 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
65ea5b03
PA
339 sp = ((sp + 4) & -16ul) - 4;
340 return (void __user *) sp;
1da177e4
LT
341}
342
235b8022 343int ia32_setup_frame(int sig, struct ksignal *ksig,
99b9cdf7 344 compat_sigset_t *set, struct pt_regs *regs)
1da177e4 345{
3b0d29ee 346 struct sigframe_ia32 __user *frame;
99b9cdf7 347 void __user *restorer;
1da177e4 348 int err = 0;
ab513701 349 void __user *fpstate = NULL;
1da177e4 350
99b9cdf7
TG
351 /* copy_to_user optimizes that into a single 8 byte store */
352 static const struct {
353 u16 poplmovl;
354 u32 val;
355 u16 int80;
99b9cdf7
TG
356 } __attribute__((packed)) code = {
357 0xb858, /* popl %eax ; movl $...,%eax */
358 __NR_ia32_sigreturn,
359 0x80cd, /* int $0x80 */
99b9cdf7
TG
360 };
361
235b8022 362 frame = get_sigframe(ksig, regs, sizeof(*frame), &fpstate);
1da177e4
LT
363
364 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
3d0aedd9 365 return -EFAULT;
1da177e4 366
2ba48e16 367 if (__put_user(sig, &frame->sig))
3d0aedd9 368 return -EFAULT;
1da177e4 369
2ba48e16 370 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
3d0aedd9 371 return -EFAULT;
1da177e4
LT
372
373 if (_COMPAT_NSIG_WORDS > 1) {
2ba48e16
HS
374 if (__copy_to_user(frame->extramask, &set->sig[1],
375 sizeof(frame->extramask)))
3d0aedd9 376 return -EFAULT;
1da177e4 377 }
1da177e4 378
235b8022
AV
379 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
380 restorer = ksig->ka.sa.sa_restorer;
af65d648
RM
381 } else {
382 /* Return stub is in 32bit vsyscall page */
1a3e4ca4 383 if (current->mm->context.vdso)
6f121e54
AL
384 restorer = current->mm->context.vdso +
385 selected_vdso32->sym___kernel_sigreturn;
af65d648 386 else
ade1af77 387 restorer = &frame->retcode;
af65d648 388 }
99b9cdf7 389
3b4b7570
HS
390 put_user_try {
391 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
392
393 /*
394 * These are actually not used anymore, but left because some
395 * gdb versions depend on them as a marker.
396 */
0ff8fef4 397 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
3b4b7570
HS
398 } put_user_catch(err);
399
1da177e4 400 if (err)
3d0aedd9 401 return -EFAULT;
1da177e4
LT
402
403 /* Set up registers for signal handler */
65ea5b03 404 regs->sp = (unsigned long) frame;
235b8022 405 regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
1da177e4 406
536e3ee4 407 /* Make -mregparm=3 work */
65ea5b03
PA
408 regs->ax = sig;
409 regs->dx = 0;
410 regs->cx = 0;
536e3ee4 411
b6edbb1e
JF
412 loadsegment(ds, __USER32_DS);
413 loadsegment(es, __USER32_DS);
1da177e4 414
99b9cdf7
TG
415 regs->cs = __USER32_CS;
416 regs->ss = __USER32_DS;
1da177e4 417
1d001df1 418 return 0;
1da177e4
LT
419}
420
235b8022 421int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
99b9cdf7 422 compat_sigset_t *set, struct pt_regs *regs)
1da177e4 423{
3b0d29ee 424 struct rt_sigframe_ia32 __user *frame;
af65d648 425 void __user *restorer;
1da177e4 426 int err = 0;
ab513701 427 void __user *fpstate = NULL;
1da177e4 428
99b9cdf7
TG
429 /* __copy_to_user optimizes that into a single 8 byte store */
430 static const struct {
431 u8 movl;
432 u32 val;
433 u16 int80;
9cc3c49e 434 u8 pad;
99b9cdf7
TG
435 } __attribute__((packed)) code = {
436 0xb8,
437 __NR_ia32_rt_sigreturn,
438 0x80cd,
439 0,
440 };
441
235b8022 442 frame = get_sigframe(ksig, regs, sizeof(*frame), &fpstate);
1da177e4
LT
443
444 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
3d0aedd9 445 return -EFAULT;
1da177e4 446
3b4b7570
HS
447 put_user_try {
448 put_user_ex(sig, &frame->sig);
449 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
450 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
1da177e4 451
3b4b7570
HS
452 /* Create the ucontext. */
453 if (cpu_has_xsave)
454 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
455 else
456 put_user_ex(0, &frame->uc.uc_flags);
457 put_user_ex(0, &frame->uc.uc_link);
bd1c149a 458 compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp);
3b4b7570 459
235b8022
AV
460 if (ksig->ka.sa.sa_flags & SA_RESTORER)
461 restorer = ksig->ka.sa.sa_restorer;
3b4b7570 462 else
6f121e54
AL
463 restorer = current->mm->context.vdso +
464 selected_vdso32->sym___kernel_rt_sigreturn;
3b4b7570
HS
465 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
466
467 /*
468 * Not actually used anymore, but left because some gdb
469 * versions need it.
470 */
0ff8fef4 471 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
3b4b7570 472 } put_user_catch(err);
1da177e4 473
235b8022 474 err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
5e88353d
PA
475 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
476 regs, set->sig[0]);
477 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
478
1da177e4 479 if (err)
3d0aedd9 480 return -EFAULT;
1da177e4
LT
481
482 /* Set up registers for signal handler */
65ea5b03 483 regs->sp = (unsigned long) frame;
235b8022 484 regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
1da177e4 485
a7aacdf9 486 /* Make -mregparm=3 work */
65ea5b03
PA
487 regs->ax = sig;
488 regs->dx = (unsigned long) &frame->info;
489 regs->cx = (unsigned long) &frame->uc;
a7aacdf9 490
b6edbb1e
JF
491 loadsegment(ds, __USER32_DS);
492 loadsegment(es, __USER32_DS);
99b9cdf7
TG
493
494 regs->cs = __USER32_CS;
495 regs->ss = __USER32_DS;
1da177e4 496
1d001df1 497 return 0;
1da177e4 498}
This page took 1.146089 seconds and 5 git commands to generate.