Line data Source code
1 : /*
2 : * Copyright (C) 2003 PathScale, Inc.
3 : * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 : * Licensed under the GPL
5 : */
6 :
7 :
8 : #include <linux/personality.h>
9 : #include <linux/ptrace.h>
10 : #include <linux/kernel.h>
11 : #include <asm/unistd.h>
12 : #include <linux/uaccess.h>
13 : #include <asm/ucontext.h>
14 : #include <frame_kern.h>
15 : #include <registers.h>
16 : #include <skas.h>
17 :
18 : #ifdef CONFIG_X86_32
19 :
20 : /*
21 : * FPU tag word conversions.
22 : */
23 :
24 : static inline unsigned short twd_i387_to_fxsr(unsigned short twd)
25 : {
26 : unsigned int tmp; /* to avoid 16 bit prefixes in the code */
27 :
28 : /* Transform each pair of bits into 01 (valid) or 00 (empty) */
29 : tmp = ~twd;
30 : tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
31 : /* and move the valid bits to the lower byte. */
32 : tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
33 : tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
34 : tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
35 : return tmp;
36 : }
37 :
38 : static inline unsigned long twd_fxsr_to_i387(struct user_fxsr_struct *fxsave)
39 : {
40 : struct _fpxreg *st = NULL;
41 : unsigned long twd = (unsigned long) fxsave->twd;
42 : unsigned long tag;
43 : unsigned long ret = 0xffff0000;
44 : int i;
45 :
46 : #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16)
47 :
48 : for (i = 0; i < 8; i++) {
49 : if (twd & 0x1) {
50 : st = (struct _fpxreg *) FPREG_ADDR(fxsave, i);
51 :
52 : switch (st->exponent & 0x7fff) {
53 : case 0x7fff:
54 : tag = 2; /* Special */
55 : break;
56 : case 0x0000:
57 : if ( !st->significand[0] &&
58 : !st->significand[1] &&
59 : !st->significand[2] &&
60 : !st->significand[3] ) {
61 : tag = 1; /* Zero */
62 : } else {
63 : tag = 2; /* Special */
64 : }
65 : break;
66 : default:
67 : if (st->significand[3] & 0x8000) {
68 : tag = 0; /* Valid */
69 : } else {
70 : tag = 2; /* Special */
71 : }
72 : break;
73 : }
74 : } else {
75 : tag = 3; /* Empty */
76 : }
77 : ret |= (tag << (2 * i));
78 : twd = twd >> 1;
79 : }
80 : return ret;
81 : }
82 :
83 : static int convert_fxsr_to_user(struct _fpstate __user *buf,
84 : struct user_fxsr_struct *fxsave)
85 : {
86 : unsigned long env[7];
87 : struct _fpreg __user *to;
88 : struct _fpxreg *from;
89 : int i;
90 :
91 : env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul;
92 : env[1] = (unsigned long)fxsave->swd | 0xffff0000ul;
93 : env[2] = twd_fxsr_to_i387(fxsave);
94 : env[3] = fxsave->fip;
95 : env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
96 : env[5] = fxsave->foo;
97 : env[6] = fxsave->fos;
98 :
99 : if (__copy_to_user(buf, env, 7 * sizeof(unsigned long)))
100 : return 1;
101 :
102 : to = &buf->_st[0];
103 : from = (struct _fpxreg *) &fxsave->st_space[0];
104 : for (i = 0; i < 8; i++, to++, from++) {
105 : unsigned long __user *t = (unsigned long __user *)to;
106 : unsigned long *f = (unsigned long *)from;
107 :
108 : if (__put_user(*f, t) ||
109 : __put_user(*(f + 1), t + 1) ||
110 : __put_user(from->exponent, &to->exponent))
111 : return 1;
112 : }
113 : return 0;
114 : }
115 :
116 : static int convert_fxsr_from_user(struct user_fxsr_struct *fxsave,
117 : struct _fpstate __user *buf)
118 : {
119 : unsigned long env[7];
120 : struct _fpxreg *to;
121 : struct _fpreg __user *from;
122 : int i;
123 :
124 : if (copy_from_user( env, buf, 7 * sizeof(long)))
125 : return 1;
126 :
127 : fxsave->cwd = (unsigned short)(env[0] & 0xffff);
128 : fxsave->swd = (unsigned short)(env[1] & 0xffff);
129 : fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
130 : fxsave->fip = env[3];
131 : fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16);
132 : fxsave->fcs = (env[4] & 0xffff);
133 : fxsave->foo = env[5];
134 : fxsave->fos = env[6];
135 :
136 : to = (struct _fpxreg *) &fxsave->st_space[0];
137 : from = &buf->_st[0];
138 : for (i = 0; i < 8; i++, to++, from++) {
139 : unsigned long *t = (unsigned long *)to;
140 : unsigned long __user *f = (unsigned long __user *)from;
141 :
142 : if (__get_user(*t, f) ||
143 : __get_user(*(t + 1), f + 1) ||
144 : __get_user(to->exponent, &from->exponent))
145 : return 1;
146 : }
147 : return 0;
148 : }
149 :
150 : extern int have_fpx_regs;
151 :
152 : #endif
153 :
154 0 : static int copy_sc_from_user(struct pt_regs *regs,
155 : struct sigcontext __user *from)
156 : {
157 : struct sigcontext sc;
158 : int err, pid;
159 :
160 : /* Always make any pending restarted system calls return -EINTR */
161 0 : current->restart_block.fn = do_no_restart_syscall;
162 :
163 0 : err = copy_from_user(&sc, from, sizeof(sc));
164 0 : if (err)
165 : return err;
166 :
167 : #define GETREG(regno, regname) regs->regs.gp[HOST_##regno] = sc.regname
168 :
169 : #ifdef CONFIG_X86_32
170 : GETREG(GS, gs);
171 : GETREG(FS, fs);
172 : GETREG(ES, es);
173 : GETREG(DS, ds);
174 : #endif
175 0 : GETREG(DI, di);
176 0 : GETREG(SI, si);
177 0 : GETREG(BP, bp);
178 0 : GETREG(SP, sp);
179 0 : GETREG(BX, bx);
180 0 : GETREG(DX, dx);
181 0 : GETREG(CX, cx);
182 0 : GETREG(AX, ax);
183 0 : GETREG(IP, ip);
184 :
185 : #ifdef CONFIG_X86_64
186 0 : GETREG(R8, r8);
187 0 : GETREG(R9, r9);
188 0 : GETREG(R10, r10);
189 0 : GETREG(R11, r11);
190 0 : GETREG(R12, r12);
191 0 : GETREG(R13, r13);
192 0 : GETREG(R14, r14);
193 0 : GETREG(R15, r15);
194 : #endif
195 :
196 0 : GETREG(CS, cs);
197 0 : GETREG(EFLAGS, flags);
198 : #ifdef CONFIG_X86_32
199 : GETREG(SS, ss);
200 : #endif
201 :
202 : #undef GETREG
203 :
204 0 : pid = userspace_pid[current_thread_info()->cpu];
205 : #ifdef CONFIG_X86_32
206 : if (have_fpx_regs) {
207 : struct user_fxsr_struct fpx;
208 :
209 : err = copy_from_user(&fpx,
210 : &((struct _fpstate __user *)sc.fpstate)->_fxsr_env[0],
211 : sizeof(struct user_fxsr_struct));
212 : if (err)
213 : return 1;
214 :
215 : err = convert_fxsr_from_user(&fpx, (void *)sc.fpstate);
216 : if (err)
217 : return 1;
218 :
219 : err = restore_fpx_registers(pid, (unsigned long *) &fpx);
220 : if (err < 0) {
221 : printk(KERN_ERR "copy_sc_from_user - "
222 : "restore_fpx_registers failed, errno = %d\n",
223 : -err);
224 : return 1;
225 : }
226 : } else
227 : #endif
228 : {
229 0 : err = copy_from_user(regs->regs.fp, (void *)sc.fpstate,
230 : sizeof(struct _xstate));
231 0 : if (err)
232 : return 1;
233 : }
234 0 : return 0;
235 : }
236 :
237 0 : static int copy_sc_to_user(struct sigcontext __user *to,
238 : struct _xstate __user *to_fp, struct pt_regs *regs,
239 : unsigned long mask)
240 : {
241 : struct sigcontext sc;
242 0 : struct faultinfo * fi = ¤t->thread.arch.faultinfo;
243 : int err, pid;
244 0 : memset(&sc, 0, sizeof(struct sigcontext));
245 :
246 : #define PUTREG(regno, regname) sc.regname = regs->regs.gp[HOST_##regno]
247 :
248 : #ifdef CONFIG_X86_32
249 : PUTREG(GS, gs);
250 : PUTREG(FS, fs);
251 : PUTREG(ES, es);
252 : PUTREG(DS, ds);
253 : #endif
254 0 : PUTREG(DI, di);
255 0 : PUTREG(SI, si);
256 0 : PUTREG(BP, bp);
257 0 : PUTREG(SP, sp);
258 0 : PUTREG(BX, bx);
259 0 : PUTREG(DX, dx);
260 0 : PUTREG(CX, cx);
261 0 : PUTREG(AX, ax);
262 : #ifdef CONFIG_X86_64
263 0 : PUTREG(R8, r8);
264 0 : PUTREG(R9, r9);
265 0 : PUTREG(R10, r10);
266 0 : PUTREG(R11, r11);
267 0 : PUTREG(R12, r12);
268 0 : PUTREG(R13, r13);
269 0 : PUTREG(R14, r14);
270 0 : PUTREG(R15, r15);
271 : #endif
272 :
273 0 : sc.cr2 = fi->cr2;
274 0 : sc.err = fi->error_code;
275 0 : sc.trapno = fi->trap_no;
276 0 : PUTREG(IP, ip);
277 0 : PUTREG(CS, cs);
278 0 : PUTREG(EFLAGS, flags);
279 : #ifdef CONFIG_X86_32
280 : PUTREG(SP, sp_at_signal);
281 : PUTREG(SS, ss);
282 : #endif
283 : #undef PUTREG
284 0 : sc.oldmask = mask;
285 0 : sc.fpstate = (unsigned long)to_fp;
286 :
287 0 : err = copy_to_user(to, &sc, sizeof(struct sigcontext));
288 0 : if (err)
289 : return 1;
290 :
291 0 : pid = userspace_pid[current_thread_info()->cpu];
292 :
293 : #ifdef CONFIG_X86_32
294 : if (have_fpx_regs) {
295 : struct user_fxsr_struct fpx;
296 :
297 : err = save_fpx_registers(pid, (unsigned long *) &fpx);
298 : if (err < 0){
299 : printk(KERN_ERR "copy_sc_to_user - save_fpx_registers "
300 : "failed, errno = %d\n", err);
301 : return 1;
302 : }
303 :
304 : err = convert_fxsr_to_user(&to_fp->fpstate, &fpx);
305 : if (err)
306 : return 1;
307 :
308 : err |= __put_user(fpx.swd, &to_fp->fpstate.status);
309 : err |= __put_user(X86_FXSR_MAGIC, &to_fp->fpstate.magic);
310 : if (err)
311 : return 1;
312 :
313 : if (copy_to_user(&to_fp->fpstate._fxsr_env[0], &fpx,
314 : sizeof(struct user_fxsr_struct)))
315 : return 1;
316 : } else
317 : #endif
318 : {
319 0 : if (copy_to_user(to_fp, regs->regs.fp, sizeof(struct _xstate)))
320 : return 1;
321 : }
322 :
323 0 : return 0;
324 : }
325 :
326 : #ifdef CONFIG_X86_32
327 : static int copy_ucontext_to_user(struct ucontext __user *uc,
328 : struct _xstate __user *fp, sigset_t *set,
329 : unsigned long sp)
330 : {
331 : int err = 0;
332 :
333 : err |= __save_altstack(&uc->uc_stack, sp);
334 : err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs, 0);
335 : err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
336 : return err;
337 : }
338 :
339 : struct sigframe
340 : {
341 : char __user *pretcode;
342 : int sig;
343 : struct sigcontext sc;
344 : struct _xstate fpstate;
345 : unsigned long extramask[_NSIG_WORDS-1];
346 : char retcode[8];
347 : };
348 :
349 : struct rt_sigframe
350 : {
351 : char __user *pretcode;
352 : int sig;
353 : struct siginfo __user *pinfo;
354 : void __user *puc;
355 : struct siginfo info;
356 : struct ucontext uc;
357 : struct _xstate fpstate;
358 : char retcode[8];
359 : };
360 :
361 : int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig,
362 : struct pt_regs *regs, sigset_t *mask)
363 : {
364 : struct sigframe __user *frame;
365 : void __user *restorer;
366 : int err = 0, sig = ksig->sig;
367 :
368 : /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */
369 : stack_top = ((stack_top + 4) & -16UL) - 4;
370 : frame = (struct sigframe __user *) stack_top - 1;
371 : if (!access_ok(frame, sizeof(*frame)))
372 : return 1;
373 :
374 : restorer = frame->retcode;
375 : if (ksig->ka.sa.sa_flags & SA_RESTORER)
376 : restorer = ksig->ka.sa.sa_restorer;
377 :
378 : err |= __put_user(restorer, &frame->pretcode);
379 : err |= __put_user(sig, &frame->sig);
380 : err |= copy_sc_to_user(&frame->sc, &frame->fpstate, regs, mask->sig[0]);
381 : if (_NSIG_WORDS > 1)
382 : err |= __copy_to_user(&frame->extramask, &mask->sig[1],
383 : sizeof(frame->extramask));
384 :
385 : /*
386 : * This is popl %eax ; movl $,%eax ; int $0x80
387 : *
388 : * WE DO NOT USE IT ANY MORE! It's only left here for historical
389 : * reasons and because gdb uses it as a signature to notice
390 : * signal handler stack frames.
391 : */
392 : err |= __put_user(0xb858, (short __user *)(frame->retcode+0));
393 : err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2));
394 : err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
395 :
396 : if (err)
397 : return err;
398 :
399 : PT_REGS_SP(regs) = (unsigned long) frame;
400 : PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
401 : PT_REGS_AX(regs) = (unsigned long) sig;
402 : PT_REGS_DX(regs) = (unsigned long) 0;
403 : PT_REGS_CX(regs) = (unsigned long) 0;
404 : return 0;
405 : }
406 :
407 : int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
408 : struct pt_regs *regs, sigset_t *mask)
409 : {
410 : struct rt_sigframe __user *frame;
411 : void __user *restorer;
412 : int err = 0, sig = ksig->sig;
413 :
414 : stack_top &= -8UL;
415 : frame = (struct rt_sigframe __user *) stack_top - 1;
416 : if (!access_ok(frame, sizeof(*frame)))
417 : return 1;
418 :
419 : restorer = frame->retcode;
420 : if (ksig->ka.sa.sa_flags & SA_RESTORER)
421 : restorer = ksig->ka.sa.sa_restorer;
422 :
423 : err |= __put_user(restorer, &frame->pretcode);
424 : err |= __put_user(sig, &frame->sig);
425 : err |= __put_user(&frame->info, &frame->pinfo);
426 : err |= __put_user(&frame->uc, &frame->puc);
427 : err |= copy_siginfo_to_user(&frame->info, &ksig->info);
428 : err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask,
429 : PT_REGS_SP(regs));
430 :
431 : /*
432 : * This is movl $,%eax ; int $0x80
433 : *
434 : * WE DO NOT USE IT ANY MORE! It's only left here for historical
435 : * reasons and because gdb uses it as a signature to notice
436 : * signal handler stack frames.
437 : */
438 : err |= __put_user(0xb8, (char __user *)(frame->retcode+0));
439 : err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1));
440 : err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
441 :
442 : if (err)
443 : return err;
444 :
445 : PT_REGS_SP(regs) = (unsigned long) frame;
446 : PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
447 : PT_REGS_AX(regs) = (unsigned long) sig;
448 : PT_REGS_DX(regs) = (unsigned long) &frame->info;
449 : PT_REGS_CX(regs) = (unsigned long) &frame->uc;
450 : return 0;
451 : }
452 :
453 : long sys_sigreturn(void)
454 : {
455 : unsigned long sp = PT_REGS_SP(¤t->thread.regs);
456 : struct sigframe __user *frame = (struct sigframe __user *)(sp - 8);
457 : sigset_t set;
458 : struct sigcontext __user *sc = &frame->sc;
459 : int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
460 :
461 : if (copy_from_user(&set.sig[0], &sc->oldmask, sizeof(set.sig[0])) ||
462 : copy_from_user(&set.sig[1], frame->extramask, sig_size))
463 : goto segfault;
464 :
465 : set_current_blocked(&set);
466 :
467 : if (copy_sc_from_user(¤t->thread.regs, sc))
468 : goto segfault;
469 :
470 : /* Avoid ERESTART handling */
471 : PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1;
472 : return PT_REGS_SYSCALL_RET(¤t->thread.regs);
473 :
474 : segfault:
475 : force_sig(SIGSEGV);
476 : return 0;
477 : }
478 :
479 : #else
480 :
481 : struct rt_sigframe
482 : {
483 : char __user *pretcode;
484 : struct ucontext uc;
485 : struct siginfo info;
486 : struct _xstate fpstate;
487 : };
488 :
489 0 : int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
490 : struct pt_regs *regs, sigset_t *set)
491 : {
492 : struct rt_sigframe __user *frame;
493 0 : int err = 0, sig = ksig->sig;
494 : unsigned long fp_to;
495 :
496 0 : frame = (struct rt_sigframe __user *)
497 0 : round_down(stack_top - sizeof(struct rt_sigframe), 16);
498 : /* Subtract 128 for a red zone and 8 for proper alignment */
499 0 : frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8);
500 :
501 0 : if (!access_ok(frame, sizeof(*frame)))
502 : goto out;
503 :
504 0 : if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
505 0 : err |= copy_siginfo_to_user(&frame->info, &ksig->info);
506 0 : if (err)
507 : goto out;
508 : }
509 :
510 : /* Create the ucontext. */
511 0 : err |= __put_user(0, &frame->uc.uc_flags);
512 0 : err |= __put_user(0, &frame->uc.uc_link);
513 0 : err |= __save_altstack(&frame->uc.uc_stack, PT_REGS_SP(regs));
514 0 : err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs,
515 : set->sig[0]);
516 :
517 0 : fp_to = (unsigned long)&frame->fpstate;
518 :
519 0 : err |= __put_user(fp_to, &frame->uc.uc_mcontext.fpstate);
520 : if (sizeof(*set) == 16) {
521 : err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
522 : err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
523 : }
524 : else
525 0 : err |= __copy_to_user(&frame->uc.uc_sigmask, set,
526 : sizeof(*set));
527 :
528 : /*
529 : * Set up to return from userspace. If provided, use a stub
530 : * already in userspace.
531 : */
532 : /* x86-64 should always use SA_RESTORER. */
533 0 : if (ksig->ka.sa.sa_flags & SA_RESTORER)
534 0 : err |= __put_user((void *)ksig->ka.sa.sa_restorer,
535 : &frame->pretcode);
536 : else
537 : /* could use a vstub here */
538 : return err;
539 :
540 0 : if (err)
541 : return err;
542 :
543 0 : PT_REGS_SP(regs) = (unsigned long) frame;
544 0 : PT_REGS_DI(regs) = sig;
545 : /* In case the signal handler was declared without prototypes */
546 0 : PT_REGS_AX(regs) = 0;
547 :
548 : /*
549 : * This also works for non SA_SIGINFO handlers because they expect the
550 : * next argument after the signal number on the stack.
551 : */
552 0 : PT_REGS_SI(regs) = (unsigned long) &frame->info;
553 0 : PT_REGS_DX(regs) = (unsigned long) &frame->uc;
554 0 : PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
555 : out:
556 : return err;
557 : }
558 : #endif
559 :
560 0 : long sys_rt_sigreturn(void)
561 : {
562 0 : unsigned long sp = PT_REGS_SP(¤t->thread.regs);
563 0 : struct rt_sigframe __user *frame =
564 0 : (struct rt_sigframe __user *)(sp - sizeof(long));
565 0 : struct ucontext __user *uc = &frame->uc;
566 : sigset_t set;
567 :
568 0 : if (copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
569 : goto segfault;
570 :
571 0 : set_current_blocked(&set);
572 :
573 0 : if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext))
574 : goto segfault;
575 :
576 : /* Avoid ERESTART handling */
577 0 : PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1;
578 0 : return PT_REGS_SYSCALL_RET(¤t->thread.regs);
579 :
580 : segfault:
581 0 : force_sig(SIGSEGV);
582 0 : return 0;
583 : }
|