1/* 2 * irixsig.c: WHEEE, IRIX signals! YOW, am I compatible or what?!?! 3 * 4 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) 5 * Copyright (C) 1997 - 2000 Ralf Baechle (ralf@gnu.org) 6 * Copyright (C) 2000 Silicon Graphics, Inc. 7 */ 8#include <linux/kernel.h> 9#include <linux/sched.h> 10#include <linux/mm.h> 11#include <linux/errno.h> 12#include <linux/smp.h> 13#include <linux/time.h> 14#include <linux/ptrace.h> 15#include <linux/resource.h> 16 17#include <asm/ptrace.h> 18#include <asm/uaccess.h> 19#include <asm/unistd.h> 20 21#undef DEBUG_SIG 22 23#define _S(nr) (1<<((nr)-1)) 24 25#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) 26 27typedef struct { 28 unsigned long sig[4]; 29} irix_sigset_t; 30 31struct sigctx_irix5 { 32 u32 rmask, cp0_status; 33 u64 pc; 34 u64 regs[32]; 35 u64 fpregs[32]; 36 u32 usedfp, fpcsr, fpeir, sstk_flags; 37 u64 hi, lo; 38 u64 cp0_cause, cp0_badvaddr, _unused0; 39 irix_sigset_t sigset; 40 u64 weird_fpu_thing; 41 u64 _unused1[31]; 42}; 43 44#ifdef DEBUG_SIG 45/* Debugging */ 46static inline void dump_irix5_sigctx(struct sigctx_irix5 *c) 47{ 48 int i; 49 50 printk("misc: rmask[%08lx] status[%08lx] pc[%08lx]\n", 51 (unsigned long) c->rmask, 52 (unsigned long) c->cp0_status, 53 (unsigned long) c->pc); 54 printk("regs: "); 55 for(i = 0; i < 16; i++) 56 printk("[%d]<%08lx> ", i, (unsigned long) c->regs[i]); 57 printk("\nregs: "); 58 for(i = 16; i < 32; i++) 59 printk("[%d]<%08lx> ", i, (unsigned long) c->regs[i]); 60 printk("\nfpregs: "); 61 for(i = 0; i < 16; i++) 62 printk("[%d]<%08lx> ", i, (unsigned long) c->fpregs[i]); 63 printk("\nfpregs: "); 64 for(i = 16; i < 32; i++) 65 printk("[%d]<%08lx> ", i, (unsigned long) c->fpregs[i]); 66 printk("misc: usedfp[%d] fpcsr[%08lx] fpeir[%08lx] stk_flgs[%08lx]\n", 67 (int) c->usedfp, (unsigned long) c->fpcsr, 68 (unsigned long) c->fpeir, (unsigned long) c->sstk_flags); 69 printk("misc: hi[%08lx] lo[%08lx] cause[%08lx] badvaddr[%08lx]\n", 70 (unsigned long) c->hi, (unsigned long) c->lo, 71 (unsigned long) c->cp0_cause, (unsigned long) c->cp0_badvaddr); 72 printk("misc: sigset<0>[%08lx] sigset<1>[%08lx] sigset<2>[%08lx] " 73 "sigset<3>[%08lx]\n", (unsigned long) c->sigset.sig[0], 74 (unsigned long) c->sigset.sig[1], 75 (unsigned long) c->sigset.sig[2], 76 (unsigned long) c->sigset.sig[3]); 77} 78#endif 79 80static int setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs, 81 int signr, sigset_t *oldmask) 82{ 83 struct sigctx_irix5 __user *ctx; 84 unsigned long sp; 85 int error, i; 86 87 sp = regs->regs[29]; 88 sp -= sizeof(struct sigctx_irix5); 89 sp &= ~(0xf); 90 ctx = (struct sigctx_irix5 __user *) sp; 91 if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))) 92 goto segv_and_exit; 93 94 error = __put_user(0, &ctx->weird_fpu_thing); 95 error |= __put_user(~(0x00000001), &ctx->rmask); 96 error |= __put_user(0, &ctx->regs[0]); 97 for(i = 1; i < 32; i++) 98 error |= __put_user((u64) regs->regs[i], &ctx->regs[i]); 99 100 error |= __put_user((u64) regs->hi, &ctx->hi); 101 error |= __put_user((u64) regs->lo, &ctx->lo); 102 error |= __put_user((u64) regs->cp0_epc, &ctx->pc); 103 error |= __put_user(!!used_math(), &ctx->usedfp); 104 error |= __put_user((u64) regs->cp0_cause, &ctx->cp0_cause); 105 error |= __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr); 106 107 error |= __put_user(0, &ctx->sstk_flags); 108 109 error |= __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)) ? -EFAULT : 0; 110 111 if (error) 112 goto segv_and_exit; 113 114#ifdef DEBUG_SIG 115 dump_irix5_sigctx(ctx); 116#endif 117 118 regs->regs[4] = (unsigned long) signr; 119 regs->regs[5] = 0; 120 regs->regs[6] = regs->regs[29] = sp; 121 regs->regs[7] = (unsigned long) ka->sa.sa_handler; 122 regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer; 123 124 return 1; 125 126segv_and_exit: 127 force_sigsegv(signr, current); 128 return 0; 129} 130 131static int inline 132setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, 133 int signr, sigset_t *oldmask, siginfo_t *info) 134{ 135 printk("Aiee: setup_tr_frame wants to be written"); 136 do_exit(SIGSEGV); 137} 138 139static inline int handle_signal(unsigned long sig, siginfo_t *info, 140 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs) 141{ 142 int ret; 143 144 switch(regs->regs[0]) { 145 case ERESTARTNOHAND: 146 regs->regs[2] = EINTR; 147 break; 148 case ERESTARTSYS: 149 if(!(ka->sa.sa_flags & SA_RESTART)) { 150 regs->regs[2] = EINTR; 151 break; 152 } 153 /* fallthrough */ 154 case ERESTARTNOINTR: /* Userland will reload $v0. */ 155 regs->cp0_epc -= 8; 156 } 157 158 regs->regs[0] = 0; /* Don't deal with this again. */ 159 160 if (ka->sa.sa_flags & SA_SIGINFO) 161 ret = setup_irix_rt_frame(ka, regs, sig, oldset, info); 162 else 163 ret = setup_irix_frame(ka, regs, sig, oldset); 164 165 spin_lock_irq(¤t->sighand->siglock); 166 sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); 167 if (!(ka->sa.sa_flags & SA_NODEFER)) 168 sigaddset(¤t->blocked,sig); 169 recalc_sigpending(); 170 spin_unlock_irq(¤t->sighand->siglock); 171 172 return ret; 173} 174 175void do_irix_signal(struct pt_regs *regs) 176{ 177 struct k_sigaction ka; 178 siginfo_t info; 179 int signr; 180 sigset_t *oldset; 181 182 /* 183 * We want the common case to go fast, which is why we may in certain 184 * cases get here from kernel mode. Just return without doing anything 185 * if so. 186 */ 187 if (!user_mode(regs)) 188 return; 189 190 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 191 oldset = ¤t->saved_sigmask; 192 else 193 oldset = ¤t->blocked; 194 195 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 196 if (signr > 0) { 197 /* Whee! Actually deliver the signal. */ 198 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { 199 /* a signal was successfully delivered; the saved 200 * sigmask will have been stored in the signal frame, 201 * and will be restored by sigreturn, so we can simply 202 * clear the TIF_RESTORE_SIGMASK flag */ 203 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 204 clear_thread_flag(TIF_RESTORE_SIGMASK); 205 } 206 207 return; 208 } 209 210 /* 211 * Who's code doesn't conform to the restartable syscall convention 212 * dies here!!! The li instruction, a single machine instruction, 213 * must directly be followed by the syscall instruction. 214 */ 215 if (regs->regs[0]) { 216 if (regs->regs[2] == ERESTARTNOHAND || 217 regs->regs[2] == ERESTARTSYS || 218 regs->regs[2] == ERESTARTNOINTR) { 219 regs->cp0_epc -= 8; 220 } 221 if (regs->regs[2] == ERESTART_RESTARTBLOCK) { 222 regs->regs[2] = __NR_restart_syscall; 223 regs->regs[7] = regs->regs[26]; 224 regs->cp0_epc -= 4; 225 } 226 regs->regs[0] = 0; /* Don't deal with this again. */ 227 } 228 229 /* 230 * If there's no signal to deliver, we just put the saved sigmask 231 * back 232 */ 233 if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 234 clear_thread_flag(TIF_RESTORE_SIGMASK); 235 sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); 236 } 237} 238 239asmlinkage void 240irix_sigreturn(struct pt_regs *regs) 241{ 242 struct sigctx_irix5 __user *context, *magic; 243 unsigned long umask, mask; 244 u64 *fregs; 245 u32 usedfp; 246 int error, sig, i, base = 0; 247 sigset_t blocked; 248 249 /* Always make any pending restarted system calls return -EINTR */ 250 current_thread_info()->restart_block.fn = do_no_restart_syscall; 251 252 if (regs->regs[2] == 1000) 253 base = 1; 254 255 context = (struct sigctx_irix5 __user *) regs->regs[base + 4]; 256 magic = (struct sigctx_irix5 __user *) regs->regs[base + 5]; 257 sig = (int) regs->regs[base + 6]; 258#ifdef DEBUG_SIG 259 printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n", 260 current->comm, current->pid, context, magic, sig); 261#endif 262 if (!context) 263 context = magic; 264 if (!access_ok(VERIFY_READ, context, sizeof(struct sigctx_irix5))) 265 goto badframe; 266 267#ifdef DEBUG_SIG 268 dump_irix5_sigctx(context); 269#endif 270 271 error = __get_user(regs->cp0_epc, &context->pc); 272 error |= __get_user(umask, &context->rmask); 273 274 mask = 2; 275 for (i = 1; i < 32; i++, mask <<= 1) { 276 if (umask & mask) 277 error |= __get_user(regs->regs[i], &context->regs[i]); 278 } 279 error |= __get_user(regs->hi, &context->hi); 280 error |= __get_user(regs->lo, &context->lo); 281 282 error |= __get_user(usedfp, &context->usedfp); 283 if ((umask & 1) && usedfp) { 284 fregs = (u64 *) ¤t->thread.fpu; 285 286 for(i = 0; i < 32; i++) 287 error |= __get_user(fregs[i], &context->fpregs[i]); 288 error |= __get_user(current->thread.fpu.fcr31, &context->fpcsr); 289 } 290 291 292 error |= __copy_from_user(&blocked, &context->sigset, sizeof(blocked)) ? -EFAULT : 0; 293 294 if (error) 295 goto badframe; 296 297 sigdelsetmask(&blocked, ~_BLOCKABLE); 298 spin_lock_irq(¤t->sighand->siglock); 299 current->blocked = blocked; 300 recalc_sigpending(); 301 spin_unlock_irq(¤t->sighand->siglock); 302 303 /* 304 * Don't let your children do this ... 305 */ 306 __asm__ __volatile__( 307 "move\t$29,%0\n\t" 308 "j\tsyscall_exit" 309 :/* no outputs */ 310 :"r" (®s)); 311 /* Unreached */ 312 313badframe: 314 force_sig(SIGSEGV, current); 315} 316 317struct sigact_irix5 { 318 int flags; 319 void (*handler)(int); 320 u32 sigset[4]; 321 int _unused0[2]; 322}; 323 324#define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility: 325 set only the low 32 bit of the sigset. */ 326 327#ifdef DEBUG_SIG 328static inline void dump_sigact_irix5(struct sigact_irix5 *p) 329{ 330 printk("<f[%d] hndlr[%08lx] msk[%08lx]>", p->flags, 331 (unsigned long) p->handler, 332 (unsigned long) p->sigset[0]); 333} 334#endif 335 336asmlinkage int 337irix_sigaction(int sig, const struct sigaction __user *act, 338 struct sigaction __user *oact, void __user *trampoline) 339{ 340 struct k_sigaction new_ka, old_ka; 341 int ret; 342 343#ifdef DEBUG_SIG 344 printk(" (%d,%s,%s,%08lx) ", sig, (!new ? "0" : "NEW"), 345 (!old ? "0" : "OLD"), trampoline); 346 if(new) { 347 dump_sigact_irix5(new); printk(" "); 348 } 349#endif 350 if (act) { 351 sigset_t mask; 352 int err; 353 354 if (!access_ok(VERIFY_READ, act, sizeof(*act))) 355 return -EFAULT; 356 err = __get_user(new_ka.sa.sa_handler, &act->sa_handler); 357 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); 358 359 err |= __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)) ? -EFAULT : 0; 360 if (err) 361 return err; 362 363 /* 364 * Hmmm... methinks IRIX libc always passes a valid trampoline 365 * value for all invocations of sigaction. Will have to 366 * investigate. POSIX POSIX, die die die... 367 */ 368 new_ka.sa_restorer = trampoline; 369 } 370 371 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 372 373 if (!ret && oact) { 374 int err; 375 376 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact))) 377 return -EFAULT; 378 379 err = __put_user(old_ka.sa.sa_handler, &oact->sa_handler); 380 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 381 err |= __copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, 382 sizeof(sigset_t)) ? -EFAULT : 0; 383 if (err) 384 return -EFAULT; 385 } 386 387 return ret; 388} 389 390asmlinkage int irix_sigpending(irix_sigset_t __user *set) 391{ 392 return do_sigpending(set, sizeof(*set)); 393} 394 395asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new, 396 irix_sigset_t __user *old) 397{ 398 sigset_t oldbits, newbits; 399 400 if (new) { 401 if (!access_ok(VERIFY_READ, new, sizeof(*new))) 402 return -EFAULT; 403 if (__copy_from_user(&newbits, new, sizeof(unsigned long)*4)) 404 return -EFAULT; 405 sigdelsetmask(&newbits, ~_BLOCKABLE); 406 407 spin_lock_irq(¤t->sighand->siglock); 408 oldbits = current->blocked; 409 410 switch(how) { 411 case 1: 412 sigorsets(&newbits, &oldbits, &newbits); 413 break; 414 415 case 2: 416 sigandsets(&newbits, &oldbits, &newbits); 417 break; 418 419 case 3: 420 break; 421 422 case 256: 423 siginitset(&newbits, newbits.sig[0]); 424 break; 425 426 default: 427 return -EINVAL; 428 } 429 recalc_sigpending(); 430 spin_unlock_irq(¤t->sighand->siglock); 431 } 432 if (old) 433 return copy_to_user(old, ¤t->blocked, 434 sizeof(unsigned long)*4) ? -EFAULT : 0; 435 436 return 0; 437} 438 439asmlinkage int irix_sigsuspend(struct pt_regs *regs) 440{ 441 sigset_t newset; 442 sigset_t __user *uset; 443 444 uset = (sigset_t __user *) regs->regs[4]; 445 if (copy_from_user(&newset, uset, sizeof(sigset_t))) 446 return -EFAULT; 447 sigdelsetmask(&newset, ~_BLOCKABLE); 448 449 spin_lock_irq(¤t->sighand->siglock); 450 current->saved_sigmask = current->blocked; 451 current->blocked = newset; 452 recalc_sigpending(); 453 spin_unlock_irq(¤t->sighand->siglock); 454 455 current->state = TASK_INTERRUPTIBLE; 456 schedule(); 457 set_thread_flag(TIF_RESTORE_SIGMASK); 458 return -ERESTARTNOHAND; 459} 460 461/* hate hate hate... */ 462struct irix5_siginfo { 463 int sig, code, error; 464 union { 465 char unused[128 - (3 * 4)]; /* Safety net. */ 466 struct { 467 int pid; 468 union { 469 int uid; 470 struct { 471 int utime, status, stime; 472 } child; 473 } procdata; 474 } procinfo; 475 476 unsigned long fault_addr; 477 478 struct { 479 int fd; 480 long band; 481 } fileinfo; 482 483 unsigned long sigval; 484 } stuff; 485}; 486 487asmlinkage int irix_sigpoll_sys(unsigned long __user *set, 488 struct irix5_siginfo __user *info, struct timespec __user *tp) 489{ 490 long expire = MAX_SCHEDULE_TIMEOUT; 491 sigset_t kset; 492 int i, sig, error, timeo = 0; 493 struct timespec ktp; 494 495#ifdef DEBUG_SIG 496 printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n", 497 current->comm, current->pid, set, info, tp); 498#endif 499 500 /* Must always specify the signal set. */ 501 if (!set) 502 return -EINVAL; 503 504 if (copy_from_user(&kset, set, sizeof(set))) 505 return -EFAULT; 506 507 if (info && clear_user(info, sizeof(*info))) { 508 error = -EFAULT; 509 goto out; 510 } 511 512 if (tp) { 513 if (copy_from_user(&ktp, tp, sizeof(*tp))) 514 return -EFAULT; 515 516 if (!ktp.tv_sec && !ktp.tv_nsec) 517 return -EINVAL; 518 519 expire = timespec_to_jiffies(&ktp) + 520 (ktp.tv_sec || ktp.tv_nsec); 521 } 522 523 while(1) { 524 long tmp = 0; 525 526 expire = schedule_timeout_interruptible(expire); 527 528 for (i=0; i<=4; i++) 529 tmp |= (current->pending.signal.sig[i] & kset.sig[i]); 530 531 if (tmp) 532 break; 533 if (!expire) { 534 timeo = 1; 535 break; 536 } 537 if (signal_pending(current)) 538 return -EINTR; 539 } 540 if (timeo) 541 return -EAGAIN; 542 543 for (sig = 1; i <= 65 /* IRIX_NSIG */; sig++) { 544 if (sigismember (&kset, sig)) 545 continue; 546 if (sigismember (¤t->pending.signal, sig)) { 547 if (info) 548 return copy_to_user(&info->sig, &sig, sizeof(sig)); 549 return 0; 550 } 551 } 552 553 /* Should not get here, but do something sane if we do. */ 554 error = -EINTR; 555 556out: 557 return error; 558} 559 560/* This is here because of irix5_siginfo definition. */ 561#define IRIX_P_PID 0 562#define IRIX_P_PGID 2 563#define IRIX_P_ALL 7 564 565#define W_EXITED 1 566#define W_TRAPPED 2 567#define W_STOPPED 4 568#define W_CONT 8 569#define W_NOHANG 64 570 571#define W_MASK (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG) 572 573asmlinkage int irix_waitsys(int type, int pid, 574 struct irix5_siginfo __user *info, int options, 575 struct rusage __user *ru) 576{ 577 int flag, retval; 578 DECLARE_WAITQUEUE(wait, current); 579 struct task_struct *tsk; 580 struct task_struct *p; 581 struct list_head *_p; 582 583 if (!info) 584 return -EINVAL; 585 586 if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) 587 return -EFAULT; 588 589 if (ru) 590 if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru))) 591 return -EFAULT; 592 593 if (options & ~W_MASK) 594 return -EINVAL; 595 596 if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL) 597 return -EINVAL; 598 599 add_wait_queue(¤t->signal->wait_chldexit, &wait); 600repeat: 601 flag = 0; 602 current->state = TASK_INTERRUPTIBLE; 603 read_lock(&tasklist_lock); 604 tsk = current; 605 list_for_each(_p,&tsk->children) { 606 p = list_entry(_p,struct task_struct,sibling); 607 if ((type == IRIX_P_PID) && p->pid != pid) 608 continue; 609 if ((type == IRIX_P_PGID) && process_group(p) != pid) 610 continue; 611 if ((p->exit_signal != SIGCHLD)) 612 continue; 613 flag = 1; 614 switch (p->state) { 615 case TASK_STOPPED: 616 if (!p->exit_code) 617 continue; 618 if (!(options & (W_TRAPPED|W_STOPPED)) && 619 !(p->ptrace & PT_PTRACED)) 620 continue; 621 read_unlock(&tasklist_lock); 622 623 /* move to end of parent's list to avoid starvation */ 624 write_lock_irq(&tasklist_lock); 625 remove_parent(p); 626 add_parent(p); 627 write_unlock_irq(&tasklist_lock); 628 retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; 629 if (retval) 630 goto end_waitsys; 631 632 retval = __put_user(SIGCHLD, &info->sig); 633 retval |= __put_user(0, &info->code); 634 retval |= __put_user(p->pid, &info->stuff.procinfo.pid); 635 retval |= __put_user((p->exit_code >> 8) & 0xff, 636 &info->stuff.procinfo.procdata.child.status); 637 retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime); 638 retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime); 639 if (retval) 640 goto end_waitsys; 641 642 p->exit_code = 0; 643 goto end_waitsys; 644 645 case EXIT_ZOMBIE: 646 current->signal->cutime += p->utime + p->signal->cutime; 647 current->signal->cstime += p->stime + p->signal->cstime; 648 if (ru != NULL) 649 getrusage(p, RUSAGE_BOTH, ru); 650 retval = __put_user(SIGCHLD, &info->sig); 651 retval |= __put_user(1, &info->code); /* CLD_EXITED */ 652 retval |= __put_user(p->pid, &info->stuff.procinfo.pid); 653 retval |= __put_user((p->exit_code >> 8) & 0xff, 654 &info->stuff.procinfo.procdata.child.status); 655 retval |= __put_user(p->utime, 656 &info->stuff.procinfo.procdata.child.utime); 657 retval |= __put_user(p->stime, 658 &info->stuff.procinfo.procdata.child.stime); 659 if (retval) 660 return retval; 661 662 if (p->real_parent != p->parent) { 663 write_lock_irq(&tasklist_lock); 664 remove_parent(p); 665 p->parent = p->real_parent; 666 add_parent(p); 667 do_notify_parent(p, SIGCHLD); 668 write_unlock_irq(&tasklist_lock); 669 } else 670 release_task(p); 671 goto end_waitsys; 672 default: 673 continue; 674 } 675 tsk = next_thread(tsk); 676 } 677 read_unlock(&tasklist_lock); 678 if (flag) { 679 retval = 0; 680 if (options & W_NOHANG) 681 goto end_waitsys; 682 retval = -ERESTARTSYS; 683 if (signal_pending(current)) 684 goto end_waitsys; 685 current->state = TASK_INTERRUPTIBLE; 686 schedule(); 687 goto repeat; 688 } 689 retval = -ECHILD; 690end_waitsys: 691 current->state = TASK_RUNNING; 692 remove_wait_queue(¤t->signal->wait_chldexit, &wait); 693 694 return retval; 695} 696 697struct irix5_context { 698 u32 flags; 699 u32 link; 700 u32 sigmask[4]; 701 struct { u32 sp, size, flags; } stack; 702 int regs[36]; 703 u32 fpregs[32]; 704 u32 fpcsr; 705 u32 _unused0; 706 u32 _unused1[47]; 707 u32 weird_graphics_thing; 708}; 709 710asmlinkage int irix_getcontext(struct pt_regs *regs) 711{ 712 int error, i, base = 0; 713 struct irix5_context __user *ctx; 714 unsigned long flags; 715 716 if (regs->regs[2] == 1000) 717 base = 1; 718 ctx = (struct irix5_context __user *) regs->regs[base + 4]; 719 720#ifdef DEBUG_SIG 721 printk("[%s:%d] irix_getcontext(%p)\n", 722 current->comm, current->pid, ctx); 723#endif 724 725 if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))); 726 return -EFAULT; 727 728 error = __put_user(current->thread.irix_oldctx, &ctx->link); 729 730 error |= __copy_to_user(&ctx->sigmask, ¤t->blocked, sizeof(irix_sigset_t)) ? -EFAULT : 0; 731 732 error |= __put_user(0, &ctx->stack.sp); 733 error |= __put_user(0, &ctx->stack.size); 734 error |= __put_user(0, &ctx->stack.flags); 735 736 error |= __put_user(0, &ctx->weird_graphics_thing); 737 error |= __put_user(0, &ctx->regs[0]); 738 for (i = 1; i < 32; i++) 739 error |= __put_user(regs->regs[i], &ctx->regs[i]); 740 error |= __put_user(regs->lo, &ctx->regs[32]); 741 error |= __put_user(regs->hi, &ctx->regs[33]); 742 error |= __put_user(regs->cp0_cause, &ctx->regs[34]); 743 error |= __put_user(regs->cp0_epc, &ctx->regs[35]); 744 745 flags = 0x0f; 746 if (!used_math()) { 747 flags &= ~(0x08); 748 } else { 749 printk("Wheee, no code for saving IRIX FPU context yet.\n"); 750 } 751 error |= __put_user(flags, &ctx->flags); 752 753 return error; 754} 755 756asmlinkage void irix_setcontext(struct pt_regs *regs) 757{ 758 struct irix5_context __user *ctx; 759 int err, base = 0; 760 u32 flags; 761 762 if (regs->regs[2] == 1000) 763 base = 1; 764 ctx = (struct irix5_context __user *) regs->regs[base + 4]; 765 766#ifdef DEBUG_SIG 767 printk("[%s:%d] irix_setcontext(%p)\n", 768 current->comm, current->pid, ctx); 769#endif 770 771 if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))) 772 goto segv_and_exit; 773 774 err = __get_user(flags, &ctx->flags); 775 if (flags & 0x02) { 776 printk("Wheee, cannot do sigstack stuff in setcontext\n"); 777 } 778 779 if (flags & 0x04) { 780 int i; 781 782 for (i = 1; i < 32; i++) 783 err |= __get_user(regs->regs[i], &ctx->regs[i]); 784 err |= __get_user(regs->lo, &ctx->regs[32]); 785 err |= __get_user(regs->hi, &ctx->regs[33]); 786 err |= __get_user(regs->cp0_epc, &ctx->regs[35]); 787 } 788 789 if (flags & 0x08) 790 printk(KERN_ERR "Wheee, cannot restore FPU context yet...\n"); 791 792 err |= __get_user(current->thread.irix_oldctx, &ctx->link); 793 if (err) 794 goto segv_and_exit; 795 796 /* 797 * Don't let your children do this ... 798 */ 799 __asm__ __volatile__( 800 "move\t$29,%0\n\t" 801 "j\tsyscall_exit" 802 :/* no outputs */ 803 :"r" (®s)); 804 /* Unreached */ 805 806segv_and_exit: 807 force_sigsegv(SIGSEGV, current); 808} 809 810struct irix_sigstack { 811 unsigned long sp; 812 int status; 813}; 814 815asmlinkage int irix_sigstack(struct irix_sigstack __user *new, 816 struct irix_sigstack __user *old) 817{ 818#ifdef DEBUG_SIG 819 printk("[%s:%d] irix_sigstack(%p,%p)\n", 820 current->comm, current->pid, new, old); 821#endif 822 if (new) { 823 if (!access_ok(VERIFY_READ, new, sizeof(*new))) 824 return -EFAULT; 825 } 826 827 if (old) { 828 if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) 829 return -EFAULT; 830 } 831 832 return 0; 833} 834 835struct irix_sigaltstack { unsigned long sp; int size; int status; }; 836 837asmlinkage int irix_sigaltstack(struct irix_sigaltstack __user *new, 838 struct irix_sigaltstack __user *old) 839{ 840#ifdef DEBUG_SIG 841 printk("[%s:%d] irix_sigaltstack(%p,%p)\n", 842 current->comm, current->pid, new, old); 843#endif 844 if (new) 845 if (!access_ok(VERIFY_READ, new, sizeof(*new))) 846 return -EFAULT; 847 848 if (old) { 849 if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) 850 return -EFAULT; 851 } 852 853 return 0; 854} 855 856struct irix_procset { 857 int cmd, ltype, lid, rtype, rid; 858}; 859 860asmlinkage int irix_sigsendset(struct irix_procset __user *pset, int sig) 861{ 862 if (!access_ok(VERIFY_READ, pset, sizeof(*pset))) 863 return -EFAULT; 864#ifdef DEBUG_SIG 865 printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n", 866 current->comm, current->pid, 867 pset->cmd, pset->ltype, pset->lid, pset->rtype, pset->rid, 868 sig); 869#endif 870 return -EINVAL; 871} 872