all arches, signal: move restart_block to struct task_struct
[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>
24#include <asm/i387.h>
1361b83a 25#include <asm/fpu-internal.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,
164 struct sigcontext_ia32 __user *sc,
047ce935 165 unsigned int *pax)
99b9cdf7 166{
a967bb3f 167 unsigned int tmpflags, err = 0;
ab513701 168 void __user *buf;
99b9cdf7
TG
169 u32 tmp;
170
171 /* Always make any pending restarted system calls return -EINTR */
f56141e3 172 current->restart_block.fn = do_no_restart_syscall;
99b9cdf7 173
3b4b7570
HS
174 get_user_try {
175 /*
176 * Reload fs and gs if they have changed in the signal
177 * handler. This does not handle long fs/gs base changes in
178 * the handler, but does not clobber them at least in the
179 * normal case.
180 */
a967bb3f 181 RELOAD_SEG(gs);
3b4b7570
HS
182 RELOAD_SEG(fs);
183 RELOAD_SEG(ds);
184 RELOAD_SEG(es);
185
186 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
187 COPY(dx); COPY(cx); COPY(ip);
188 /* Don't touch extended registers */
189
190 COPY_SEG_CPL3(cs);
191 COPY_SEG_CPL3(ss);
192
193 get_user_ex(tmpflags, &sc->flags);
194 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
195 /* disable syscall checks */
196 regs->orig_ax = -1;
197
198 get_user_ex(tmp, &sc->fpstate);
199 buf = compat_ptr(tmp);
3b4b7570
HS
200
201 get_user_ex(*pax, &sc->ax);
202 } get_user_catch(err);
203
49b8c695 204 err |= restore_xstate_sig(buf, 1);
5e88353d 205
1da177e4 206 return err;
1da177e4
LT
207}
208
3fe26fa3 209asmlinkage long sys32_sigreturn(void)
1da177e4 210{
3fe26fa3 211 struct pt_regs *regs = current_pt_regs();
3b0d29ee 212 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
1da177e4 213 sigset_t set;
65ea5b03 214 unsigned int ax;
1da177e4
LT
215
216 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
217 goto badframe;
218 if (__get_user(set.sig[0], &frame->sc.oldmask)
219 || (_COMPAT_NSIG_WORDS > 1
99b9cdf7
TG
220 && __copy_from_user((((char *) &set.sig) + 4),
221 &frame->extramask,
1da177e4
LT
222 sizeof(frame->extramask))))
223 goto badframe;
224
905f29e2 225 set_current_blocked(&set);
99b9cdf7 226
65ea5b03 227 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
1da177e4 228 goto badframe;
65ea5b03 229 return ax;
1da177e4
LT
230
231badframe:
232 signal_fault(regs, frame, "32bit sigreturn");
233 return 0;
99b9cdf7 234}
1da177e4 235
3fe26fa3 236asmlinkage long sys32_rt_sigreturn(void)
1da177e4 237{
3fe26fa3 238 struct pt_regs *regs = current_pt_regs();
3b0d29ee 239 struct rt_sigframe_ia32 __user *frame;
1da177e4 240 sigset_t set;
65ea5b03 241 unsigned int ax;
1da177e4 242
3b0d29ee 243 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
1da177e4
LT
244
245 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
246 goto badframe;
247 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
248 goto badframe;
249
905f29e2 250 set_current_blocked(&set);
99b9cdf7 251
65ea5b03 252 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
1da177e4
LT
253 goto badframe;
254
90268439 255 if (compat_restore_altstack(&frame->uc.uc_stack))
1da177e4
LT
256 goto badframe;
257
65ea5b03 258 return ax;
1da177e4
LT
259
260badframe:
99b9cdf7 261 signal_fault(regs, frame, "32bit rt sigreturn");
1da177e4 262 return 0;
99b9cdf7 263}
1da177e4
LT
264
265/*
266 * Set up a signal frame.
267 */
268
99b9cdf7 269static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
ab513701 270 void __user *fpstate,
99b9cdf7 271 struct pt_regs *regs, unsigned int mask)
1da177e4 272{
a967bb3f 273 int err = 0;
1da177e4 274
3b4b7570 275 put_user_try {
a967bb3f
HS
276 put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
277 put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
278 put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
279 put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
3b4b7570
HS
280
281 put_user_ex(regs->di, &sc->di);
282 put_user_ex(regs->si, &sc->si);
283 put_user_ex(regs->bp, &sc->bp);
284 put_user_ex(regs->sp, &sc->sp);
285 put_user_ex(regs->bx, &sc->bx);
286 put_user_ex(regs->dx, &sc->dx);
287 put_user_ex(regs->cx, &sc->cx);
288 put_user_ex(regs->ax, &sc->ax);
51e7dc70 289 put_user_ex(current->thread.trap_nr, &sc->trapno);
3b4b7570
HS
290 put_user_ex(current->thread.error_code, &sc->err);
291 put_user_ex(regs->ip, &sc->ip);
292 put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
293 put_user_ex(regs->flags, &sc->flags);
294 put_user_ex(regs->sp, &sc->sp_at_signal);
295 put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
296
297 put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
298
299 /* non-iBCS2 extensions.. */
300 put_user_ex(mask, &sc->oldmask);
301 put_user_ex(current->thread.cr2, &sc->cr2);
302 } put_user_catch(err);
1da177e4
LT
303
304 return err;
305}
306
307/*
308 * Determine which stack to use..
309 */
235b8022 310static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
3c1c7f10 311 size_t frame_size,
0ff8fef4 312 void __user **fpstate)
1da177e4 313{
65ea5b03 314 unsigned long sp;
1da177e4
LT
315
316 /* Default to using normal stack */
65ea5b03 317 sp = regs->sp;
1da177e4
LT
318
319 /* This is the X/Open sanctioned signal stack switching. */
235b8022
AV
320 if (ksig->ka.sa.sa_flags & SA_ONSTACK)
321 sp = sigsp(sp, ksig);
1da177e4 322 /* This is the legacy signal stack switching. */
8bee3f0a 323 else if ((regs->ss & 0xffff) != __USER32_DS &&
235b8022
AV
324 !(ksig->ka.sa.sa_flags & SA_RESTORER) &&
325 ksig->ka.sa.sa_restorer)
326 sp = (unsigned long) ksig->ka.sa.sa_restorer;
1da177e4 327
3c1c7f10 328 if (used_math()) {
72a671ce
SS
329 unsigned long fx_aligned, math_size;
330
331 sp = alloc_mathframe(sp, 1, &fx_aligned, &math_size);
0ff8fef4 332 *fpstate = (struct _fpstate_ia32 __user *) sp;
72a671ce
SS
333 if (save_xstate_sig(*fpstate, (void __user *)fx_aligned,
334 math_size) < 0)
99ea1b93 335 return (void __user *) -1L;
3c1c7f10
SS
336 }
337
65ea5b03 338 sp -= frame_size;
d347f372
MO
339 /* Align the stack pointer according to the i386 ABI,
340 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
65ea5b03
PA
341 sp = ((sp + 4) & -16ul) - 4;
342 return (void __user *) sp;
1da177e4
LT
343}
344
235b8022 345int ia32_setup_frame(int sig, struct ksignal *ksig,
99b9cdf7 346 compat_sigset_t *set, struct pt_regs *regs)
1da177e4 347{
3b0d29ee 348 struct sigframe_ia32 __user *frame;
99b9cdf7 349 void __user *restorer;
1da177e4 350 int err = 0;
ab513701 351 void __user *fpstate = NULL;
1da177e4 352
99b9cdf7
TG
353 /* copy_to_user optimizes that into a single 8 byte store */
354 static const struct {
355 u16 poplmovl;
356 u32 val;
357 u16 int80;
99b9cdf7
TG
358 } __attribute__((packed)) code = {
359 0xb858, /* popl %eax ; movl $...,%eax */
360 __NR_ia32_sigreturn,
361 0x80cd, /* int $0x80 */
99b9cdf7
TG
362 };
363
235b8022 364 frame = get_sigframe(ksig, regs, sizeof(*frame), &fpstate);
1da177e4
LT
365
366 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
3d0aedd9 367 return -EFAULT;
1da177e4 368
2ba48e16 369 if (__put_user(sig, &frame->sig))
3d0aedd9 370 return -EFAULT;
1da177e4 371
2ba48e16 372 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
3d0aedd9 373 return -EFAULT;
1da177e4
LT
374
375 if (_COMPAT_NSIG_WORDS > 1) {
2ba48e16
HS
376 if (__copy_to_user(frame->extramask, &set->sig[1],
377 sizeof(frame->extramask)))
3d0aedd9 378 return -EFAULT;
1da177e4 379 }
1da177e4 380
235b8022
AV
381 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
382 restorer = ksig->ka.sa.sa_restorer;
af65d648
RM
383 } else {
384 /* Return stub is in 32bit vsyscall page */
1a3e4ca4 385 if (current->mm->context.vdso)
6f121e54
AL
386 restorer = current->mm->context.vdso +
387 selected_vdso32->sym___kernel_sigreturn;
af65d648 388 else
ade1af77 389 restorer = &frame->retcode;
af65d648 390 }
99b9cdf7 391
3b4b7570
HS
392 put_user_try {
393 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
394
395 /*
396 * These are actually not used anymore, but left because some
397 * gdb versions depend on them as a marker.
398 */
0ff8fef4 399 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
3b4b7570
HS
400 } put_user_catch(err);
401
1da177e4 402 if (err)
3d0aedd9 403 return -EFAULT;
1da177e4
LT
404
405 /* Set up registers for signal handler */
65ea5b03 406 regs->sp = (unsigned long) frame;
235b8022 407 regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
1da177e4 408
536e3ee4 409 /* Make -mregparm=3 work */
65ea5b03
PA
410 regs->ax = sig;
411 regs->dx = 0;
412 regs->cx = 0;
536e3ee4 413
b6edbb1e
JF
414 loadsegment(ds, __USER32_DS);
415 loadsegment(es, __USER32_DS);
1da177e4 416
99b9cdf7
TG
417 regs->cs = __USER32_CS;
418 regs->ss = __USER32_DS;
1da177e4 419
1d001df1 420 return 0;
1da177e4
LT
421}
422
235b8022 423int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
99b9cdf7 424 compat_sigset_t *set, struct pt_regs *regs)
1da177e4 425{
3b0d29ee 426 struct rt_sigframe_ia32 __user *frame;
af65d648 427 void __user *restorer;
1da177e4 428 int err = 0;
ab513701 429 void __user *fpstate = NULL;
1da177e4 430
99b9cdf7
TG
431 /* __copy_to_user optimizes that into a single 8 byte store */
432 static const struct {
433 u8 movl;
434 u32 val;
435 u16 int80;
9cc3c49e 436 u8 pad;
99b9cdf7
TG
437 } __attribute__((packed)) code = {
438 0xb8,
439 __NR_ia32_rt_sigreturn,
440 0x80cd,
441 0,
442 };
443
235b8022 444 frame = get_sigframe(ksig, regs, sizeof(*frame), &fpstate);
1da177e4
LT
445
446 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
3d0aedd9 447 return -EFAULT;
1da177e4 448
3b4b7570
HS
449 put_user_try {
450 put_user_ex(sig, &frame->sig);
451 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
452 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
1da177e4 453
3b4b7570
HS
454 /* Create the ucontext. */
455 if (cpu_has_xsave)
456 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
457 else
458 put_user_ex(0, &frame->uc.uc_flags);
459 put_user_ex(0, &frame->uc.uc_link);
bd1c149a 460 compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp);
3b4b7570 461
235b8022
AV
462 if (ksig->ka.sa.sa_flags & SA_RESTORER)
463 restorer = ksig->ka.sa.sa_restorer;
3b4b7570 464 else
6f121e54
AL
465 restorer = current->mm->context.vdso +
466 selected_vdso32->sym___kernel_rt_sigreturn;
3b4b7570
HS
467 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
468
469 /*
470 * Not actually used anymore, but left because some gdb
471 * versions need it.
472 */
0ff8fef4 473 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
3b4b7570 474 } put_user_catch(err);
1da177e4 475
235b8022 476 err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
5e88353d
PA
477 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
478 regs, set->sig[0]);
479 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
480
1da177e4 481 if (err)
3d0aedd9 482 return -EFAULT;
1da177e4
LT
483
484 /* Set up registers for signal handler */
65ea5b03 485 regs->sp = (unsigned long) frame;
235b8022 486 regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
1da177e4 487
a7aacdf9 488 /* Make -mregparm=3 work */
65ea5b03
PA
489 regs->ax = sig;
490 regs->dx = (unsigned long) &frame->info;
491 regs->cx = (unsigned long) &frame->uc;
a7aacdf9 492
b6edbb1e
JF
493 loadsegment(ds, __USER32_DS);
494 loadsegment(es, __USER32_DS);
99b9cdf7
TG
495
496 regs->cs = __USER32_CS;
497 regs->ss = __USER32_DS;
1da177e4 498
1d001df1 499 return 0;
1da177e4 500}
This page took 0.829097 seconds and 5 git commands to generate.