root/arch/x86/um/signal.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. twd_i387_to_fxsr
  2. twd_fxsr_to_i387
  3. convert_fxsr_to_user
  4. convert_fxsr_from_user
  5. copy_sc_from_user
  6. copy_sc_to_user
  7. copy_ucontext_to_user
  8. setup_signal_stack_sc
  9. setup_signal_stack_si
  10. sys_sigreturn
  11. setup_signal_stack_si
  12. sys_rt_sigreturn

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

/* [<][>][^][v][top][bottom][index][help] */