Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (C) 2003 PathScale, Inc.
0003  * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
0004  * Licensed under the GPL
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  * FPU tag word conversions.
0022  */
0023 
0024 static inline unsigned short twd_i387_to_fxsr(unsigned short twd)
0025 {
0026     unsigned int tmp; /* to avoid 16 bit prefixes in the code */
0027 
0028     /* Transform each pair of bits into 01 (valid) or 00 (empty) */
0029     tmp = ~twd;
0030     tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
0031     /* and move the valid bits to the lower byte. */
0032     tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
0033     tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
0034     tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
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;        /* Special */
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;    /* Zero */
0062                 } else {
0063                     tag = 2;    /* Special */
0064                 }
0065                 break;
0066             default:
0067                 if (st->significand[3] & 0x8000) {
0068                     tag = 0;    /* Valid */
0069                 } else {
0070                     tag = 2;    /* Special */
0071                 }
0072                 break;
0073             }
0074         } else {
0075             tag = 3;            /* Empty */
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     /* Always make any pending restarted system calls return -EINTR */
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 = &current->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, &current->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     /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */
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      * This is popl %eax ; movl $,%eax ; int $0x80
0387      *
0388      * WE DO NOT USE IT ANY MORE! It's only left here for historical
0389      * reasons and because gdb uses it as a signature to notice
0390      * signal handler stack frames.
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      * This is movl $,%eax ; int $0x80
0433      *
0434      * WE DO NOT USE IT ANY MORE! It's only left here for historical
0435      * reasons and because gdb uses it as a signature to notice
0436      * signal handler stack frames.
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(&current->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(&current->thread.regs, sc))
0468         goto segfault;
0469 
0470     /* Avoid ERESTART handling */
0471     PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
0472     return PT_REGS_SYSCALL_RET(&current->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     /* Subtract 128 for a red zone and 8 for proper alignment */
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     /* Create the ucontext.  */
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      * Set up to return from userspace.  If provided, use a stub
0530      * already in userspace.
0531      */
0532     /* x86-64 should always use SA_RESTORER. */
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         /* could use a vstub here */
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     /* In case the signal handler was declared without prototypes */
0546     PT_REGS_AX(regs) = 0;
0547 
0548     /*
0549      * This also works for non SA_SIGINFO handlers because they expect the
0550      * next argument after the signal number on the stack.
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(&current->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(&current->thread.regs, &uc->uc_mcontext))
0574         goto segfault;
0575 
0576     /* Avoid ERESTART handling */
0577     PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
0578     return PT_REGS_SYSCALL_RET(&current->thread.regs);
0579 
0580  segfault:
0581     force_sig(SIGSEGV);
0582     return 0;
0583 }