0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/personality.h>
0009 #include <linux/ptrace.h>
0010 #include <linux/kernel.h>
0011 #include <asm/unistd.h>
0012 #include <linux/uaccess.h>
0013 #include <asm/ucontext.h>
0014 #include <frame_kern.h>
0015 #include <registers.h>
0016 #include <skas.h>
0017
0018 #ifdef CONFIG_X86_32
0019
0020
0021
0022
0023
0024 static inline unsigned short twd_i387_to_fxsr(unsigned short twd)
0025 {
0026 unsigned int tmp;
0027
0028
0029 tmp = ~twd;
0030 tmp = (tmp | (tmp>>1)) & 0x5555;
0031
0032 tmp = (tmp | (tmp >> 1)) & 0x3333;
0033 tmp = (tmp | (tmp >> 2)) & 0x0f0f;
0034 tmp = (tmp | (tmp >> 4)) & 0x00ff;
0035 return tmp;
0036 }
0037
0038 static inline unsigned long twd_fxsr_to_i387(struct user_fxsr_struct *fxsave)
0039 {
0040 struct _fpxreg *st = NULL;
0041 unsigned long twd = (unsigned long) fxsave->twd;
0042 unsigned long tag;
0043 unsigned long ret = 0xffff0000;
0044 int i;
0045
0046 #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16)
0047
0048 for (i = 0; i < 8; i++) {
0049 if (twd & 0x1) {
0050 st = (struct _fpxreg *) FPREG_ADDR(fxsave, i);
0051
0052 switch (st->exponent & 0x7fff) {
0053 case 0x7fff:
0054 tag = 2;
0055 break;
0056 case 0x0000:
0057 if ( !st->significand[0] &&
0058 !st->significand[1] &&
0059 !st->significand[2] &&
0060 !st->significand[3] ) {
0061 tag = 1;
0062 } else {
0063 tag = 2;
0064 }
0065 break;
0066 default:
0067 if (st->significand[3] & 0x8000) {
0068 tag = 0;
0069 } else {
0070 tag = 2;
0071 }
0072 break;
0073 }
0074 } else {
0075 tag = 3;
0076 }
0077 ret |= (tag << (2 * i));
0078 twd = twd >> 1;
0079 }
0080 return ret;
0081 }
0082
0083 static int convert_fxsr_to_user(struct _fpstate __user *buf,
0084 struct user_fxsr_struct *fxsave)
0085 {
0086 unsigned long env[7];
0087 struct _fpreg __user *to;
0088 struct _fpxreg *from;
0089 int i;
0090
0091 env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul;
0092 env[1] = (unsigned long)fxsave->swd | 0xffff0000ul;
0093 env[2] = twd_fxsr_to_i387(fxsave);
0094 env[3] = fxsave->fip;
0095 env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
0096 env[5] = fxsave->foo;
0097 env[6] = fxsave->fos;
0098
0099 if (__copy_to_user(buf, env, 7 * sizeof(unsigned long)))
0100 return 1;
0101
0102 to = &buf->_st[0];
0103 from = (struct _fpxreg *) &fxsave->st_space[0];
0104 for (i = 0; i < 8; i++, to++, from++) {
0105 unsigned long __user *t = (unsigned long __user *)to;
0106 unsigned long *f = (unsigned long *)from;
0107
0108 if (__put_user(*f, t) ||
0109 __put_user(*(f + 1), t + 1) ||
0110 __put_user(from->exponent, &to->exponent))
0111 return 1;
0112 }
0113 return 0;
0114 }
0115
0116 static int convert_fxsr_from_user(struct user_fxsr_struct *fxsave,
0117 struct _fpstate __user *buf)
0118 {
0119 unsigned long env[7];
0120 struct _fpxreg *to;
0121 struct _fpreg __user *from;
0122 int i;
0123
0124 if (copy_from_user( env, buf, 7 * sizeof(long)))
0125 return 1;
0126
0127 fxsave->cwd = (unsigned short)(env[0] & 0xffff);
0128 fxsave->swd = (unsigned short)(env[1] & 0xffff);
0129 fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
0130 fxsave->fip = env[3];
0131 fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16);
0132 fxsave->fcs = (env[4] & 0xffff);
0133 fxsave->foo = env[5];
0134 fxsave->fos = env[6];
0135
0136 to = (struct _fpxreg *) &fxsave->st_space[0];
0137 from = &buf->_st[0];
0138 for (i = 0; i < 8; i++, to++, from++) {
0139 unsigned long *t = (unsigned long *)to;
0140 unsigned long __user *f = (unsigned long __user *)from;
0141
0142 if (__get_user(*t, f) ||
0143 __get_user(*(t + 1), f + 1) ||
0144 __get_user(to->exponent, &from->exponent))
0145 return 1;
0146 }
0147 return 0;
0148 }
0149
0150 extern int have_fpx_regs;
0151
0152 #endif
0153
0154 static int copy_sc_from_user(struct pt_regs *regs,
0155 struct sigcontext __user *from)
0156 {
0157 struct sigcontext sc;
0158 int err, pid;
0159
0160
0161 current->restart_block.fn = do_no_restart_syscall;
0162
0163 err = copy_from_user(&sc, from, sizeof(sc));
0164 if (err)
0165 return err;
0166
0167 #define GETREG(regno, regname) regs->regs.gp[HOST_##regno] = sc.regname
0168
0169 #ifdef CONFIG_X86_32
0170 GETREG(GS, gs);
0171 GETREG(FS, fs);
0172 GETREG(ES, es);
0173 GETREG(DS, ds);
0174 #endif
0175 GETREG(DI, di);
0176 GETREG(SI, si);
0177 GETREG(BP, bp);
0178 GETREG(SP, sp);
0179 GETREG(BX, bx);
0180 GETREG(DX, dx);
0181 GETREG(CX, cx);
0182 GETREG(AX, ax);
0183 GETREG(IP, ip);
0184
0185 #ifdef CONFIG_X86_64
0186 GETREG(R8, r8);
0187 GETREG(R9, r9);
0188 GETREG(R10, r10);
0189 GETREG(R11, r11);
0190 GETREG(R12, r12);
0191 GETREG(R13, r13);
0192 GETREG(R14, r14);
0193 GETREG(R15, r15);
0194 #endif
0195
0196 GETREG(CS, cs);
0197 GETREG(EFLAGS, flags);
0198 #ifdef CONFIG_X86_32
0199 GETREG(SS, ss);
0200 #endif
0201
0202 #undef GETREG
0203
0204 pid = userspace_pid[current_thread_info()->cpu];
0205 #ifdef CONFIG_X86_32
0206 if (have_fpx_regs) {
0207 struct user_fxsr_struct fpx;
0208
0209 err = copy_from_user(&fpx,
0210 &((struct _fpstate __user *)sc.fpstate)->_fxsr_env[0],
0211 sizeof(struct user_fxsr_struct));
0212 if (err)
0213 return 1;
0214
0215 err = convert_fxsr_from_user(&fpx, (void *)sc.fpstate);
0216 if (err)
0217 return 1;
0218
0219 err = restore_fpx_registers(pid, (unsigned long *) &fpx);
0220 if (err < 0) {
0221 printk(KERN_ERR "copy_sc_from_user - "
0222 "restore_fpx_registers failed, errno = %d\n",
0223 -err);
0224 return 1;
0225 }
0226 } else
0227 #endif
0228 {
0229 err = copy_from_user(regs->regs.fp, (void *)sc.fpstate,
0230 sizeof(struct _xstate));
0231 if (err)
0232 return 1;
0233 }
0234 return 0;
0235 }
0236
0237 static int copy_sc_to_user(struct sigcontext __user *to,
0238 struct _xstate __user *to_fp, struct pt_regs *regs,
0239 unsigned long mask)
0240 {
0241 struct sigcontext sc;
0242 struct faultinfo * fi = ¤t->thread.arch.faultinfo;
0243 int err, pid;
0244 memset(&sc, 0, sizeof(struct sigcontext));
0245
0246 #define PUTREG(regno, regname) sc.regname = regs->regs.gp[HOST_##regno]
0247
0248 #ifdef CONFIG_X86_32
0249 PUTREG(GS, gs);
0250 PUTREG(FS, fs);
0251 PUTREG(ES, es);
0252 PUTREG(DS, ds);
0253 #endif
0254 PUTREG(DI, di);
0255 PUTREG(SI, si);
0256 PUTREG(BP, bp);
0257 PUTREG(SP, sp);
0258 PUTREG(BX, bx);
0259 PUTREG(DX, dx);
0260 PUTREG(CX, cx);
0261 PUTREG(AX, ax);
0262 #ifdef CONFIG_X86_64
0263 PUTREG(R8, r8);
0264 PUTREG(R9, r9);
0265 PUTREG(R10, r10);
0266 PUTREG(R11, r11);
0267 PUTREG(R12, r12);
0268 PUTREG(R13, r13);
0269 PUTREG(R14, r14);
0270 PUTREG(R15, r15);
0271 #endif
0272
0273 sc.cr2 = fi->cr2;
0274 sc.err = fi->error_code;
0275 sc.trapno = fi->trap_no;
0276 PUTREG(IP, ip);
0277 PUTREG(CS, cs);
0278 PUTREG(EFLAGS, flags);
0279 #ifdef CONFIG_X86_32
0280 PUTREG(SP, sp_at_signal);
0281 PUTREG(SS, ss);
0282 #endif
0283 #undef PUTREG
0284 sc.oldmask = mask;
0285 sc.fpstate = (unsigned long)to_fp;
0286
0287 err = copy_to_user(to, &sc, sizeof(struct sigcontext));
0288 if (err)
0289 return 1;
0290
0291 pid = userspace_pid[current_thread_info()->cpu];
0292
0293 #ifdef CONFIG_X86_32
0294 if (have_fpx_regs) {
0295 struct user_fxsr_struct fpx;
0296
0297 err = save_fpx_registers(pid, (unsigned long *) &fpx);
0298 if (err < 0){
0299 printk(KERN_ERR "copy_sc_to_user - save_fpx_registers "
0300 "failed, errno = %d\n", err);
0301 return 1;
0302 }
0303
0304 err = convert_fxsr_to_user(&to_fp->fpstate, &fpx);
0305 if (err)
0306 return 1;
0307
0308 err |= __put_user(fpx.swd, &to_fp->fpstate.status);
0309 err |= __put_user(X86_FXSR_MAGIC, &to_fp->fpstate.magic);
0310 if (err)
0311 return 1;
0312
0313 if (copy_to_user(&to_fp->fpstate._fxsr_env[0], &fpx,
0314 sizeof(struct user_fxsr_struct)))
0315 return 1;
0316 } else
0317 #endif
0318 {
0319 if (copy_to_user(to_fp, regs->regs.fp, sizeof(struct _xstate)))
0320 return 1;
0321 }
0322
0323 return 0;
0324 }
0325
0326 #ifdef CONFIG_X86_32
0327 static int copy_ucontext_to_user(struct ucontext __user *uc,
0328 struct _xstate __user *fp, sigset_t *set,
0329 unsigned long sp)
0330 {
0331 int err = 0;
0332
0333 err |= __save_altstack(&uc->uc_stack, sp);
0334 err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs, 0);
0335 err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
0336 return err;
0337 }
0338
0339 struct sigframe
0340 {
0341 char __user *pretcode;
0342 int sig;
0343 struct sigcontext sc;
0344 struct _xstate fpstate;
0345 unsigned long extramask[_NSIG_WORDS-1];
0346 char retcode[8];
0347 };
0348
0349 struct rt_sigframe
0350 {
0351 char __user *pretcode;
0352 int sig;
0353 struct siginfo __user *pinfo;
0354 void __user *puc;
0355 struct siginfo info;
0356 struct ucontext uc;
0357 struct _xstate fpstate;
0358 char retcode[8];
0359 };
0360
0361 int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig,
0362 struct pt_regs *regs, sigset_t *mask)
0363 {
0364 struct sigframe __user *frame;
0365 void __user *restorer;
0366 int err = 0, sig = ksig->sig;
0367
0368
0369 stack_top = ((stack_top + 4) & -16UL) - 4;
0370 frame = (struct sigframe __user *) stack_top - 1;
0371 if (!access_ok(frame, sizeof(*frame)))
0372 return 1;
0373
0374 restorer = frame->retcode;
0375 if (ksig->ka.sa.sa_flags & SA_RESTORER)
0376 restorer = ksig->ka.sa.sa_restorer;
0377
0378 err |= __put_user(restorer, &frame->pretcode);
0379 err |= __put_user(sig, &frame->sig);
0380 err |= copy_sc_to_user(&frame->sc, &frame->fpstate, regs, mask->sig[0]);
0381 if (_NSIG_WORDS > 1)
0382 err |= __copy_to_user(&frame->extramask, &mask->sig[1],
0383 sizeof(frame->extramask));
0384
0385
0386
0387
0388
0389
0390
0391
0392 err |= __put_user(0xb858, (short __user *)(frame->retcode+0));
0393 err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2));
0394 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
0395
0396 if (err)
0397 return err;
0398
0399 PT_REGS_SP(regs) = (unsigned long) frame;
0400 PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
0401 PT_REGS_AX(regs) = (unsigned long) sig;
0402 PT_REGS_DX(regs) = (unsigned long) 0;
0403 PT_REGS_CX(regs) = (unsigned long) 0;
0404 return 0;
0405 }
0406
0407 int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
0408 struct pt_regs *regs, sigset_t *mask)
0409 {
0410 struct rt_sigframe __user *frame;
0411 void __user *restorer;
0412 int err = 0, sig = ksig->sig;
0413
0414 stack_top &= -8UL;
0415 frame = (struct rt_sigframe __user *) stack_top - 1;
0416 if (!access_ok(frame, sizeof(*frame)))
0417 return 1;
0418
0419 restorer = frame->retcode;
0420 if (ksig->ka.sa.sa_flags & SA_RESTORER)
0421 restorer = ksig->ka.sa.sa_restorer;
0422
0423 err |= __put_user(restorer, &frame->pretcode);
0424 err |= __put_user(sig, &frame->sig);
0425 err |= __put_user(&frame->info, &frame->pinfo);
0426 err |= __put_user(&frame->uc, &frame->puc);
0427 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
0428 err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask,
0429 PT_REGS_SP(regs));
0430
0431
0432
0433
0434
0435
0436
0437
0438 err |= __put_user(0xb8, (char __user *)(frame->retcode+0));
0439 err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1));
0440 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
0441
0442 if (err)
0443 return err;
0444
0445 PT_REGS_SP(regs) = (unsigned long) frame;
0446 PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
0447 PT_REGS_AX(regs) = (unsigned long) sig;
0448 PT_REGS_DX(regs) = (unsigned long) &frame->info;
0449 PT_REGS_CX(regs) = (unsigned long) &frame->uc;
0450 return 0;
0451 }
0452
0453 long sys_sigreturn(void)
0454 {
0455 unsigned long sp = PT_REGS_SP(¤t->thread.regs);
0456 struct sigframe __user *frame = (struct sigframe __user *)(sp - 8);
0457 sigset_t set;
0458 struct sigcontext __user *sc = &frame->sc;
0459 int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
0460
0461 if (copy_from_user(&set.sig[0], &sc->oldmask, sizeof(set.sig[0])) ||
0462 copy_from_user(&set.sig[1], frame->extramask, sig_size))
0463 goto segfault;
0464
0465 set_current_blocked(&set);
0466
0467 if (copy_sc_from_user(¤t->thread.regs, sc))
0468 goto segfault;
0469
0470
0471 PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1;
0472 return PT_REGS_SYSCALL_RET(¤t->thread.regs);
0473
0474 segfault:
0475 force_sig(SIGSEGV);
0476 return 0;
0477 }
0478
0479 #else
0480
0481 struct rt_sigframe
0482 {
0483 char __user *pretcode;
0484 struct ucontext uc;
0485 struct siginfo info;
0486 struct _xstate fpstate;
0487 };
0488
0489 int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
0490 struct pt_regs *regs, sigset_t *set)
0491 {
0492 struct rt_sigframe __user *frame;
0493 int err = 0, sig = ksig->sig;
0494 unsigned long fp_to;
0495
0496 frame = (struct rt_sigframe __user *)
0497 round_down(stack_top - sizeof(struct rt_sigframe), 16);
0498
0499 frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8);
0500
0501 if (!access_ok(frame, sizeof(*frame)))
0502 goto out;
0503
0504 if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
0505 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
0506 if (err)
0507 goto out;
0508 }
0509
0510
0511 err |= __put_user(0, &frame->uc.uc_flags);
0512 err |= __put_user(0, &frame->uc.uc_link);
0513 err |= __save_altstack(&frame->uc.uc_stack, PT_REGS_SP(regs));
0514 err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs,
0515 set->sig[0]);
0516
0517 fp_to = (unsigned long)&frame->fpstate;
0518
0519 err |= __put_user(fp_to, &frame->uc.uc_mcontext.fpstate);
0520 if (sizeof(*set) == 16) {
0521 err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
0522 err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
0523 }
0524 else
0525 err |= __copy_to_user(&frame->uc.uc_sigmask, set,
0526 sizeof(*set));
0527
0528
0529
0530
0531
0532
0533 if (ksig->ka.sa.sa_flags & SA_RESTORER)
0534 err |= __put_user((void *)ksig->ka.sa.sa_restorer,
0535 &frame->pretcode);
0536 else
0537
0538 return err;
0539
0540 if (err)
0541 return err;
0542
0543 PT_REGS_SP(regs) = (unsigned long) frame;
0544 PT_REGS_DI(regs) = sig;
0545
0546 PT_REGS_AX(regs) = 0;
0547
0548
0549
0550
0551
0552 PT_REGS_SI(regs) = (unsigned long) &frame->info;
0553 PT_REGS_DX(regs) = (unsigned long) &frame->uc;
0554 PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
0555 out:
0556 return err;
0557 }
0558 #endif
0559
0560 long sys_rt_sigreturn(void)
0561 {
0562 unsigned long sp = PT_REGS_SP(¤t->thread.regs);
0563 struct rt_sigframe __user *frame =
0564 (struct rt_sigframe __user *)(sp - sizeof(long));
0565 struct ucontext __user *uc = &frame->uc;
0566 sigset_t set;
0567
0568 if (copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
0569 goto segfault;
0570
0571 set_current_blocked(&set);
0572
0573 if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext))
0574 goto segfault;
0575
0576
0577 PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1;
0578 return PT_REGS_SYSCALL_RET(¤t->thread.regs);
0579
0580 segfault:
0581 force_sig(SIGSEGV);
0582 return 0;
0583 }