Linux 2.1.127
[davej-history.git] / arch / mips / kernel / irixsig.c
blob86a9a5c72e74bbf31fbd51d6662eb493c3343eff
1 /*
2 * irixsig.c: WHEEE, IRIX signals! YOW, am I compatable or what?!?!
4 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
6 * $Id: irixsig.c,v 1.11 1998/03/26 07:39:09 ralf Exp $
7 */
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/mm.h>
12 #include <linux/errno.h>
13 #include <linux/smp.h>
14 #include <linux/smp_lock.h>
15 #include <linux/time.h>
17 #include <asm/ptrace.h>
18 #include <asm/uaccess.h>
20 asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
21 int options, unsigned long *ru);
23 #undef DEBUG_SIG
25 #define _S(nr) (1<<((nr)-1))
27 #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
29 typedef struct {
30 unsigned long sig[4];
31 } irix_sigset_t;
33 struct sigctx_irix5 {
34 u32 rmask, cp0_status;
35 u64 pc;
36 u64 regs[32];
37 u64 fpregs[32];
38 u32 usedfp, fpcsr, fpeir, sstk_flags;
39 u64 hi, lo;
40 u64 cp0_cause, cp0_badvaddr, _unused0;
41 irix_sigset_t sigset;
42 u64 weird_fpu_thing;
43 u64 _unused1[31];
46 #ifdef DEBUG_SIG
47 /* Debugging */
48 static inline void dump_irix5_sigctx(struct sigctx_irix5 *c)
50 int i;
52 printk("misc: rmask[%08lx] status[%08lx] pc[%08lx]\n",
53 (unsigned long) c->rmask,
54 (unsigned long) c->cp0_status,
55 (unsigned long) c->pc);
56 printk("regs: ");
57 for(i = 0; i < 16; i++)
58 printk("[%d]<%08lx> ", i, (unsigned long) c->regs[i]);
59 printk("\nregs: ");
60 for(i = 16; i < 32; i++)
61 printk("[%d]<%08lx> ", i, (unsigned long) c->regs[i]);
62 printk("\nfpregs: ");
63 for(i = 0; i < 16; i++)
64 printk("[%d]<%08lx> ", i, (unsigned long) c->fpregs[i]);
65 printk("\nfpregs: ");
66 for(i = 16; i < 32; i++)
67 printk("[%d]<%08lx> ", i, (unsigned long) c->fpregs[i]);
68 printk("misc: usedfp[%d] fpcsr[%08lx] fpeir[%08lx] stk_flgs[%08lx]\n",
69 (int) c->usedfp, (unsigned long) c->fpcsr,
70 (unsigned long) c->fpeir, (unsigned long) c->sstk_flags);
71 printk("misc: hi[%08lx] lo[%08lx] cause[%08lx] badvaddr[%08lx]\n",
72 (unsigned long) c->hi, (unsigned long) c->lo,
73 (unsigned long) c->cp0_cause, (unsigned long) c->cp0_badvaddr);
74 printk("misc: sigset<0>[%08lx] sigset<1>[%08lx] sigset<2>[%08lx] "
75 "sigset<3>[%08lx]\n", (unsigned long) c->sigset.sig[0],
76 (unsigned long) c->sigset.sig[1],
77 (unsigned long) c->sigset.sig[2],
78 (unsigned long) c->sigset.sig[3]);
80 #endif
82 static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
83 int signr, sigset_t *oldmask)
85 unsigned long sp;
86 struct sigctx_irix5 *ctx;
87 int i;
89 sp = regs->regs[29];
90 sp -= sizeof(struct sigctx_irix5);
91 sp &= ~(0xf);
92 ctx = (struct sigctx_irix5 *) sp;
93 if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))
94 goto segv_and_exit;
96 __put_user(0, &ctx->weird_fpu_thing);
97 __put_user(~(0x00000001), &ctx->rmask);
98 __put_user(0, &ctx->regs[0]);
99 for(i = 1; i < 32; i++)
100 __put_user((u64) regs->regs[i], &ctx->regs[i]);
102 __put_user((u64) regs->hi, &ctx->hi);
103 __put_user((u64) regs->lo, &ctx->lo);
104 __put_user((u64) regs->cp0_epc, &ctx->pc);
105 __put_user(current->used_math, &ctx->usedfp);
106 __put_user((u64) regs->cp0_cause, &ctx->cp0_cause);
107 __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);
109 __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */
111 __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t));
113 #ifdef DEBUG_SIG
114 dump_irix5_sigctx(ctx);
115 #endif
117 regs->regs[5] = 0; /* XXX sigcode XXX */
118 regs->regs[4] = (unsigned long) signr;
119 regs->regs[6] = regs->regs[29] = sp;
120 regs->regs[7] = (unsigned long) ka->sa.sa_handler;
121 regs->regs[25] = regs->cp0_epc = current->tss.irix_trampoline;
122 return;
124 segv_and_exit:
125 lock_kernel();
126 do_exit(SIGSEGV);
127 unlock_kernel();
130 static void inline
131 setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
132 int signr, sigset_t *oldmask, siginfo_t *info)
134 lock_kernel();
135 printk("Aiee: setup_tr_frame wants to be written");
136 do_exit(SIGSEGV);
137 unlock_kernel();
140 static inline void handle_signal(unsigned long sig, struct k_sigaction *ka,
141 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
143 if (ka->sa.sa_flags & SA_SIGINFO)
144 setup_irix_rt_frame(ka, regs, sig, oldset, info);
145 else
146 setup_irix_frame(ka, regs, sig, oldset);
148 if (ka->sa.sa_flags & SA_ONESHOT)
149 ka->sa.sa_handler = SIG_DFL;
150 if (!(ka->sa.sa_flags & SA_NODEFER)) {
151 spin_lock_irq(&current->sigmask_lock);
152 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
153 sigaddset(&current->blocked,sig);
154 recalc_sigpending(current);
155 spin_unlock_irq(&current->sigmask_lock);
159 static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
161 switch(regs->regs[0]) {
162 case ERESTARTNOHAND:
163 regs->regs[2] = EINTR;
164 break;
165 case ERESTARTSYS:
166 if(!(ka->sa.sa_flags & SA_RESTART)) {
167 regs->regs[2] = EINTR;
168 break;
170 /* fallthrough */
171 case ERESTARTNOINTR: /* Userland will reload $v0. */
172 regs->cp0_epc -= 8;
175 regs->regs[0] = 0; /* Don't deal with this again. */
178 asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
180 struct k_sigaction *ka;
181 siginfo_t info;
183 if (!oldset)
184 oldset = &current->blocked;
186 for (;;) {
187 unsigned long signr;
189 spin_lock_irq(&current->sigmask_lock);
190 signr = dequeue_signal(&current->blocked, &info);
191 spin_unlock_irq(&current->sigmask_lock);
193 if (!signr)
194 break;
196 if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
197 /* Let the debugger run. */
198 current->exit_code = signr;
199 current->state = TASK_STOPPED;
200 notify_parent(current, SIGCHLD);
201 schedule();
203 /* We're back. Did the debugger cancel the sig? */
204 if (!(signr = current->exit_code))
205 continue;
206 current->exit_code = 0;
208 /* The debugger continued. Ignore SIGSTOP. */
209 if (signr == SIGSTOP)
210 continue;
212 /* Update the siginfo structure. Is this good? */
213 if (signr != info.si_signo) {
214 info.si_signo = signr;
215 info.si_errno = 0;
216 info.si_code = SI_USER;
217 info.si_pid = current->p_pptr->pid;
218 info.si_uid = current->p_pptr->uid;
221 /* If the (new) signal is now blocked, requeue it. */
222 if (sigismember(&current->blocked, signr)) {
223 send_sig_info(signr, &info, current);
224 continue;
228 ka = &current->sig->action[signr-1];
229 if (ka->sa.sa_handler == SIG_IGN) {
230 if (signr != SIGCHLD)
231 continue;
232 /* Check for SIGCHLD: it's special. */
233 while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
234 /* nothing */;
235 continue;
238 if (ka->sa.sa_handler == SIG_DFL) {
239 int exit_code = signr;
241 /* Init gets no signals it doesn't want. */
242 if (current->pid == 1)
243 continue;
245 switch (signr) {
246 case SIGCONT: case SIGCHLD: case SIGWINCH:
247 continue;
249 case SIGTSTP: case SIGTTIN: case SIGTTOU:
250 if (is_orphaned_pgrp(current->pgrp))
251 continue;
252 /* FALLTHRU */
254 case SIGSTOP:
255 current->state = TASK_STOPPED;
256 current->exit_code = signr;
257 if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
258 notify_parent(current, SIGCHLD);
259 schedule();
260 continue;
262 case SIGQUIT: case SIGILL: case SIGTRAP:
263 case SIGABRT: case SIGFPE: case SIGSEGV:
264 lock_kernel();
265 if (current->binfmt
266 && current->binfmt->core_dump
267 && current->binfmt->core_dump(signr, regs))
268 exit_code |= 0x80;
269 unlock_kernel();
270 /* FALLTHRU */
272 default:
273 lock_kernel();
274 sigaddset(&current->signal, signr);
275 current->flags |= PF_SIGNALED;
276 do_exit(exit_code);
277 /* NOTREACHED */
281 if (regs->regs[0])
282 syscall_restart(regs, ka);
283 /* Whee! Actually deliver the signal. */
284 handle_signal(signr, ka, &info, oldset, regs);
285 return 1;
289 * Who's code doesn't conform to the restartable syscall convention
290 * dies here!!! The li instruction, a single machine instruction,
291 * must directly be followed by the syscall instruction.
293 if (regs->regs[0]) {
294 if (regs->regs[2] == ERESTARTNOHAND ||
295 regs->regs[2] == ERESTARTSYS ||
296 regs->regs[2] == ERESTARTNOINTR) {
297 regs->cp0_epc -= 8;
300 return 0;
303 asmlinkage unsigned long irix_sigreturn(struct pt_regs *regs)
305 struct sigctx_irix5 *context, *magic;
306 unsigned long umask, mask;
307 u64 *fregs, res;
308 int sig, i, base = 0;
309 sigset_t blocked;
311 if(regs->regs[2] == 1000)
312 base = 1;
314 context = (struct sigctx_irix5 *) regs->regs[base + 4];
315 magic = (struct sigctx_irix5 *) regs->regs[base + 5];
316 sig = (int) regs->regs[base + 6];
317 #ifdef DEBUG_SIG
318 printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n",
319 current->comm, current->pid, context, magic, sig);
320 #endif
321 if (!context)
322 context = magic;
323 if (!access_ok(VERIFY_READ, context, sizeof(struct sigctx_irix5)))
324 goto badframe;
326 #ifdef DEBUG_SIG
327 dump_irix5_sigctx(context);
328 #endif
330 __get_user(regs->cp0_epc, &context->pc);
331 umask = context->rmask; mask = 2;
332 for (i = 1; i < 32; i++, mask <<= 1) {
333 if(umask & mask)
334 __get_user(regs->regs[i], &context->regs[i]);
336 __get_user(regs->hi, &context->hi);
337 __get_user(regs->lo, &context->lo);
339 if ((umask & 1) && context->usedfp) {
340 fregs = (u64 *) &current->tss.fpu;
341 for(i = 0; i < 32; i++)
342 fregs[i] = (u64) context->fpregs[i];
343 __get_user(current->tss.fpu.hard.control, &context->fpcsr);
346 /* XXX do sigstack crapola here... XXX */
348 if (__copy_from_user(&blocked, &context->sigset, sizeof(blocked)))
349 goto badframe;
351 sigdelsetmask(&blocked, ~_BLOCKABLE);
352 spin_lock_irq(&current->sigmask_lock);
353 current->blocked = blocked;
354 recalc_sigpending(current);
355 spin_unlock_irq(&current->sigmask_lock);
358 * Don't let your children do this ...
360 __asm__ __volatile__(
361 "move\t$29,%0\n\t"
362 "j\tret_from_sys_call"
363 :/* no outputs */
364 :"r" (&regs));
365 /* Unreached */
367 badframe:
368 lock_kernel();
369 do_exit(SIGSEGV);
370 unlock_kernel();
372 return res;
375 struct sigact_irix5 {
376 int flags;
377 void (*handler)(int);
378 u32 sigset[4];
379 int _unused0[2];
382 #ifdef DEBUG_SIG
383 static inline void dump_sigact_irix5(struct sigact_irix5 *p)
385 printk("<f[%d] hndlr[%08lx] msk[%08lx]>", p->flags,
386 (unsigned long) p->handler,
387 (unsigned long) p->sigset[0]);
389 #endif
391 asmlinkage int
392 irix_sigaction(int sig, const struct sigaction *act,
393 struct sigaction *oact, unsigned long trampoline)
395 struct k_sigaction new_ka, old_ka;
396 int ret;
398 #ifdef DEBUG_SIG
399 printk(" (%d,%s,%s,%08lx) ", sig, (!new ? "0" : "NEW"),
400 (!old ? "0" : "OLD"), trampoline);
401 if(new) {
402 dump_sigact_irix5(new); printk(" ");
404 #endif
405 if (act) {
406 sigset_t mask;
407 if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
408 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
409 __get_user(new_ka.sa.sa_flags, &act->sa_flags))
410 return -EFAULT;
412 __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t));
413 new_ka.ka_restorer = NULL;
417 * Hmmm... methinks IRIX libc always passes a valid trampoline
418 * value for all invocations of sigaction. Will have to
419 * investigate. POSIX POSIX, die die die...
421 current->tss.irix_trampoline = trampoline;
423 /* XXX Implement SIG_SETMASK32 for IRIX compatibility */
424 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
426 if (!ret && oact) {
427 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
428 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
429 __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
430 return -EFAULT;
431 __copy_to_user(&old_ka.sa.sa_mask, &oact->sa_mask,
432 sizeof(sigset_t));
435 return ret;
438 asmlinkage int irix_sigpending(irix_sigset_t *set)
440 lock_kernel();
441 if (verify_area(VERIFY_WRITE, set, sizeof(*set)) < 0)
442 return -EFAULT;
444 /* fill in "set" with signals pending but blocked. */
445 spin_lock_irq(&current->sigmask_lock);
446 __put_user(current->blocked.sig[0] & current->signal.sig[0],
447 &set->sig[0]);
448 __put_user(current->blocked.sig[1] & current->signal.sig[1],
449 &set->sig[1]);
450 __put_user(current->blocked.sig[2] & current->signal.sig[2],
451 &set->sig[2]);
452 __put_user(current->blocked.sig[3] & current->signal.sig[3],
453 &set->sig[3]);
454 spin_unlock_irq(&current->sigmask_lock);
456 return 0;
459 asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
461 sigset_t oldbits, newbits;
462 int error;
465 if(new) {
466 error = verify_area(VERIFY_READ, new, sizeof(*new));
467 if(error)
468 return error;
469 __copy_from_user(&newbits, new, sizeof(unsigned long)*4);
470 sigdelsetmask(&newbits, ~_BLOCKABLE);
472 spin_lock_irq(&current->sigmask_lock);
473 oldbits = current->blocked;
475 switch(how) {
476 case 1:
477 sigorsets(&newbits, &oldbits, &newbits);
478 break;
480 case 2:
481 sigandsets(&newbits, &oldbits, &newbits);
482 break;
484 case 3:
485 break;
487 case 256:
488 siginitset(&newbits, newbits.sig[0]);
489 break;
491 default:
492 return -EINVAL;
494 recalc_sigpending(current);
495 spin_unlock_irq(&current->sigmask_lock);
497 if(old) {
498 error = verify_area(VERIFY_WRITE, old, sizeof(*old));
499 if(error)
500 return error;
501 __copy_to_user(old, &current->blocked, sizeof(unsigned long)*4);
504 return 0;
507 asmlinkage int irix_sigsuspend(struct pt_regs *regs)
509 sigset_t *uset, saveset, newset;
511 uset = (sigset_t *) regs->regs[4];
512 if (copy_from_user(&newset, uset, sizeof(sigset_t)))
513 return -EFAULT;
514 sigdelsetmask(&newset, ~_BLOCKABLE);
516 spin_lock_irq(&current->sigmask_lock);
517 saveset = current->blocked;
518 current->blocked = newset;
519 spin_unlock_irq(&current->sigmask_lock);
521 regs->regs[2] = -EINTR;
522 while (1) {
523 current->state = TASK_INTERRUPTIBLE;
524 schedule();
525 if (do_irix_signal(&saveset, regs))
526 return -EINTR;
530 /* hate hate hate... */
531 struct irix5_siginfo {
532 int sig, code, error;
533 union {
534 char unused[128 - (3 * 4)]; /* Safety net. */
535 struct {
536 int pid;
537 union {
538 int uid;
539 struct {
540 int utime, status, stime;
541 } child;
542 } procdata;
543 } procinfo;
545 unsigned long fault_addr;
547 struct {
548 int fd;
549 long band;
550 } fileinfo;
552 unsigned long sigval;
553 } stuff;
556 static inline unsigned long timespectojiffies(struct timespec *value)
558 unsigned long sec = (unsigned) value->tv_sec;
559 long nsec = value->tv_nsec;
561 if (sec > (LONG_MAX / HZ))
562 return LONG_MAX;
563 nsec += 1000000000L / HZ - 1;
564 nsec /= 1000000000L / HZ;
565 return HZ * sec + nsec;
568 asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
569 struct timespec *tp)
571 long expire = MAX_SCHEDULE_TIMEOUT;
572 sigset_t kset;
573 int i, sig, error, timeo = 0;
575 lock_kernel();
576 #ifdef DEBUG_SIG
577 printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n",
578 current->comm, current->pid, set, info, tp);
579 #endif
581 /* Must always specify the signal set. */
582 if(!set)
583 return -EINVAL;
585 error = verify_area(VERIFY_READ, set, sizeof(kset));
586 if (error)
587 goto out;
589 __copy_from_user(&kset, set, sizeof(set));
590 if (error)
591 goto out;
593 if (info && clear_user(info, sizeof(*info))) {
594 error = -EFAULT;
595 goto out;
598 if(tp) {
599 error = verify_area(VERIFY_READ, tp, sizeof(*tp));
600 if(error)
601 return error;
602 if(!tp->tv_sec && !tp->tv_nsec) {
603 error = -EINVAL;
604 goto out;
606 expire = timespectojiffies(tp)+(tp->tv_sec||tp->tv_nsec);
609 while(1) {
610 long tmp = 0;
612 current->state = TASK_INTERRUPTIBLE;
613 expire = schedule_timeout(expire);
615 for (i=0; i<=4; i++)
616 tmp |= (current->signal.sig[i] & kset.sig[i]);
618 if (tmp)
619 break;
620 if (!expire) {
621 timeo = 1;
622 break;
624 if (signal_pending(current))
625 return -EINTR;
627 if (timeo)
628 return -EAGAIN;
630 for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
631 if (sigismember (&kset, sig))
632 continue;
633 if (sigismember (&current->signal, sig)) {
634 /* XXX need more than this... */
635 if (info)
636 info->sig = sig;
637 error = 0;
638 goto out;
642 /* Should not get here, but do something sane if we do. */
643 error = -EINTR;
645 out:
646 unlock_kernel();
647 return error;
650 /* This is here because of irix5_siginfo definition. */
651 #define P_PID 0
652 #define P_PGID 2
653 #define P_ALL 7
655 extern int getrusage(struct task_struct *, int, struct rusage *);
657 #define W_EXITED 1
658 #define W_TRAPPED 2
659 #define W_STOPPED 4
660 #define W_CONT 8
661 #define W_NOHANG 64
663 #define W_MASK (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG)
665 asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info,
666 int options, struct rusage *ru)
668 int flag, retval;
669 struct wait_queue wait = { current, NULL };
670 struct task_struct *p;
672 lock_kernel();
673 if(!info) {
674 retval = -EINVAL;
675 goto out;
677 retval = verify_area(VERIFY_WRITE, info, sizeof(*info));
678 if(retval)
679 goto out;
680 if(ru) {
681 retval = verify_area(VERIFY_WRITE, ru, sizeof(*ru));
682 if(retval)
683 goto out;
685 if(options & ~(W_MASK)) {
686 retval = -EINVAL;
687 goto out;
689 if(type != P_PID && type != P_PGID && type != P_ALL) {
690 retval = -EINVAL;
691 goto out;
693 add_wait_queue(&current->wait_chldexit, &wait);
694 repeat:
695 flag = 0;
696 for(p = current->p_cptr; p; p = p->p_osptr) {
697 if((type == P_PID) && p->pid != pid)
698 continue;
699 if((type == P_PGID) && p->pgrp != pid)
700 continue;
701 if((p->exit_signal != SIGCHLD))
702 continue;
703 flag = 1;
704 switch(p->state) {
705 case TASK_STOPPED:
706 if (!p->exit_code)
707 continue;
708 if (!(options & (W_TRAPPED|W_STOPPED)) &&
709 !(p->flags & PF_PTRACED))
710 continue;
711 if (ru != NULL)
712 getrusage(p, RUSAGE_BOTH, ru);
713 __put_user(SIGCHLD, &info->sig);
714 __put_user(0, &info->code);
715 __put_user(p->pid, &info->stuff.procinfo.pid);
716 __put_user((p->exit_code >> 8) & 0xff,
717 &info->stuff.procinfo.procdata.child.status);
718 __put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime);
719 __put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime);
720 p->exit_code = 0;
721 retval = 0;
722 goto end_waitsys;
723 case TASK_ZOMBIE:
724 current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime;
725 current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime;
726 if (ru != NULL)
727 getrusage(p, RUSAGE_BOTH, ru);
728 __put_user(SIGCHLD, &info->sig);
729 __put_user(1, &info->code); /* CLD_EXITED */
730 __put_user(p->pid, &info->stuff.procinfo.pid);
731 __put_user((p->exit_code >> 8) & 0xff,
732 &info->stuff.procinfo.procdata.child.status);
733 __put_user(p->times.tms_utime,
734 &info->stuff.procinfo.procdata.child.utime);
735 __put_user(p->times.tms_stime,
736 &info->stuff.procinfo.procdata.child.stime);
737 retval = 0;
738 if (p->p_opptr != p->p_pptr) {
739 REMOVE_LINKS(p);
740 p->p_pptr = p->p_opptr;
741 SET_LINKS(p);
742 notify_parent(p, SIGCHLD);
743 } else
744 release(p);
745 goto end_waitsys;
746 default:
747 continue;
750 if(flag) {
751 retval = 0;
752 if(options & W_NOHANG)
753 goto end_waitsys;
754 retval = -ERESTARTSYS;
755 if(signal_pending(current))
756 goto end_waitsys;
757 current->state = TASK_INTERRUPTIBLE;
758 schedule();
759 goto repeat;
761 retval = -ECHILD;
762 end_waitsys:
763 remove_wait_queue(&current->wait_chldexit, &wait);
765 out:
766 unlock_kernel();
767 return retval;
770 struct irix5_context {
771 u32 flags;
772 u32 link;
773 u32 sigmask[4];
774 struct { u32 sp, size, flags; } stack;
775 int regs[36];
776 u32 fpregs[32];
777 u32 fpcsr;
778 u32 _unused0;
779 u32 _unused1[47];
780 u32 weird_graphics_thing;
783 asmlinkage int irix_getcontext(struct pt_regs *regs)
785 int error, i, base = 0;
786 struct irix5_context *ctx;
787 unsigned long flags;
789 lock_kernel();
790 if(regs->regs[2] == 1000)
791 base = 1;
792 ctx = (struct irix5_context *) regs->regs[base + 4];
794 #ifdef DEBUG_SIG
795 printk("[%s:%d] irix_getcontext(%p)\n",
796 current->comm, current->pid, ctx);
797 #endif
799 error = verify_area(VERIFY_WRITE, ctx, sizeof(*ctx));
800 if(error)
801 goto out;
802 __put_user(current->tss.irix_oldctx, &ctx->link);
804 __copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t));
806 /* XXX Do sigstack stuff someday... */
807 __put_user(0, &ctx->stack.sp);
808 __put_user(0, &ctx->stack.size);
809 __put_user(0, &ctx->stack.flags);
811 __put_user(0, &ctx->weird_graphics_thing);
812 __put_user(0, &ctx->regs[0]);
813 for(i = 1; i < 32; i++)
814 __put_user(regs->regs[i], &ctx->regs[i]);
815 __put_user(regs->lo, &ctx->regs[32]);
816 __put_user(regs->hi, &ctx->regs[33]);
817 __put_user(regs->cp0_cause, &ctx->regs[34]);
818 __put_user(regs->cp0_epc, &ctx->regs[35]);
820 flags = 0x0f;
821 if(!current->used_math) {
822 flags &= ~(0x08);
823 } else {
824 /* XXX wheee... */
825 printk("Wheee, no code for saving IRIX FPU context yet.\n");
827 __put_user(flags, &ctx->flags);
828 error = 0;
830 out:
831 unlock_kernel();
832 return error;
835 asmlinkage unsigned long irix_setcontext(struct pt_regs *regs)
837 int error, base = 0;
838 struct irix5_context *ctx;
840 lock_kernel();
841 if(regs->regs[2] == 1000)
842 base = 1;
843 ctx = (struct irix5_context *) regs->regs[base + 4];
845 #ifdef DEBUG_SIG
846 printk("[%s:%d] irix_setcontext(%p)\n",
847 current->comm, current->pid, ctx);
848 #endif
850 error = verify_area(VERIFY_READ, ctx, sizeof(*ctx));
851 if(error)
852 goto out;
854 if(ctx->flags & 0x02) {
855 /* XXX sigstack garbage, todo... */
856 printk("Wheee, cannot do sigstack stuff in setcontext\n");
859 if(ctx->flags & 0x04) {
860 int i;
862 /* XXX extra control block stuff... todo... */
863 for(i = 1; i < 32; i++)
864 regs->regs[i] = ctx->regs[i];
865 regs->lo = ctx->regs[32];
866 regs->hi = ctx->regs[33];
867 regs->cp0_epc = ctx->regs[35];
870 if(ctx->flags & 0x08) {
871 /* XXX fpu context, blah... */
872 printk("Wheee, cannot restore FPU context yet...\n");
874 current->tss.irix_oldctx = ctx->link;
875 error = regs->regs[2];
877 out:
878 unlock_kernel();
879 return error;
882 struct irix_sigstack { unsigned long sp; int status; };
884 asmlinkage int irix_sigstack(struct irix_sigstack *new, struct irix_sigstack *old)
886 int error;
888 lock_kernel();
889 #ifdef DEBUG_SIG
890 printk("[%s:%d] irix_sigstack(%p,%p)\n",
891 current->comm, current->pid, new, old);
892 #endif
893 if(new) {
894 error = verify_area(VERIFY_READ, new, sizeof(*new));
895 if(error)
896 goto out;
899 if(old) {
900 error = verify_area(VERIFY_WRITE, old, sizeof(*old));
901 if(error)
902 goto out;
904 error = 0;
905 out:
906 unlock_kernel();
907 return error;
910 struct irix_sigaltstack { unsigned long sp; int size; int status; };
912 asmlinkage int irix_sigaltstack(struct irix_sigaltstack *new,
913 struct irix_sigaltstack *old)
915 int error;
917 lock_kernel();
918 #ifdef DEBUG_SIG
919 printk("[%s:%d] irix_sigaltstack(%p,%p)\n",
920 current->comm, current->pid, new, old);
921 #endif
922 if(new) {
923 error = verify_area(VERIFY_READ, new, sizeof(*new));
924 if(error)
925 goto out;
928 if(old) {
929 error = verify_area(VERIFY_WRITE, old, sizeof(*old));
930 if(error)
931 goto out;
933 error = 0;
935 out:
936 error = 0;
937 unlock_kernel();
939 return error;
942 struct irix_procset {
943 int cmd, ltype, lid, rtype, rid;
946 asmlinkage int irix_sigsendset(struct irix_procset *pset, int sig)
948 int error;
950 lock_kernel();
951 error = verify_area(VERIFY_READ, pset, sizeof(*pset));
952 if(error)
953 goto out;
954 #ifdef DEBUG_SIG
955 printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n",
956 current->comm, current->pid,
957 pset->cmd, pset->ltype, pset->lid, pset->rtype, pset->rid,
958 sig);
959 #endif
961 error = -EINVAL;
963 out:
964 unlock_kernel();
965 return error;