Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/linville...
[linux-2.6] / arch / mips / kernel / irixsig.c
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
27 typedef struct {
28         unsigned long sig[4];
29 } irix_sigset_t;
30
31 struct 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 */
46 static 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
80 static 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); /* XXX sigstack unimp... todo... */
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; /* XXX sigcode XXX */
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
126 segv_and_exit:
127         force_sigsegv(signr, current);
128         return 0;
129 }
130
131 static int inline
132 setup_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
139 static 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(&current->sighand->siglock);
166         sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
167         if (!(ka->sa.sa_flags & SA_NODEFER))
168                 sigaddset(&current->blocked,sig);
169         recalc_sigpending();
170         spin_unlock_irq(&current->sighand->siglock);
171
172         return ret;
173 }
174
175 void 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 = &current->saved_sigmask;
192         else
193                 oldset = &current->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, &current->saved_sigmask, NULL);
236         }
237 }
238
239 asmlinkage void
240 irix_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 *) &current->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         /* XXX do sigstack crapola here... XXX */
292
293         error |= __copy_from_user(&blocked, &context->sigset, sizeof(blocked)) ? -EFAULT : 0;
294
295         if (error)
296                 goto badframe;
297
298         sigdelsetmask(&blocked, ~_BLOCKABLE);
299         spin_lock_irq(&current->sighand->siglock);
300         current->blocked = blocked;
301         recalc_sigpending();
302         spin_unlock_irq(&current->sighand->siglock);
303
304         /*
305          * Don't let your children do this ...
306          */
307         __asm__ __volatile__(
308                 "move\t$29,%0\n\t"
309                 "j\tsyscall_exit"
310                 :/* no outputs */
311                 :"r" (&regs));
312                 /* Unreached */
313
314 badframe:
315         force_sig(SIGSEGV, current);
316 }
317
318 struct sigact_irix5 {
319         int flags;
320         void (*handler)(int);
321         u32 sigset[4];
322         int _unused0[2];
323 };
324
325 #define SIG_SETMASK32   256     /* Goodie from SGI for BSD compatibility:
326                                    set only the low 32 bit of the sigset.  */
327
328 #ifdef DEBUG_SIG
329 static inline void dump_sigact_irix5(struct sigact_irix5 *p)
330 {
331         printk("<f[%d] hndlr[%08lx] msk[%08lx]>", p->flags,
332                (unsigned long) p->handler,
333                (unsigned long) p->sigset[0]);
334 }
335 #endif
336
337 asmlinkage int
338 irix_sigaction(int sig, const struct sigaction __user *act,
339               struct sigaction __user *oact, void __user *trampoline)
340 {
341         struct k_sigaction new_ka, old_ka;
342         int ret;
343
344 #ifdef DEBUG_SIG
345         printk(" (%d,%s,%s,%08lx) ", sig, (!new ? "0" : "NEW"),
346                (!old ? "0" : "OLD"), trampoline);
347         if(new) {
348                 dump_sigact_irix5(new); printk(" ");
349         }
350 #endif
351         if (act) {
352                 sigset_t mask;
353                 int err;
354
355                 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
356                         return -EFAULT;
357                 err = __get_user(new_ka.sa.sa_handler, &act->sa_handler);
358                 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
359
360                 err |= __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)) ? -EFAULT : 0;
361                 if (err)
362                         return err;
363
364                 /*
365                  * Hmmm... methinks IRIX libc always passes a valid trampoline
366                  * value for all invocations of sigaction.  Will have to
367                  * investigate.  POSIX POSIX, die die die...
368                  */
369                 new_ka.sa_restorer = trampoline;
370         }
371
372 /* XXX Implement SIG_SETMASK32 for IRIX compatibility */
373         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
374
375         if (!ret && oact) {
376                 int err;
377
378                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
379                         return -EFAULT;
380
381                 err = __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
382                 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
383                 err |= __copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask,
384                                sizeof(sigset_t)) ? -EFAULT : 0;
385                 if (err)
386                         return -EFAULT;
387         }
388
389         return ret;
390 }
391
392 asmlinkage int irix_sigpending(irix_sigset_t __user *set)
393 {
394         return do_sigpending(set, sizeof(*set));
395 }
396
397 asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new,
398         irix_sigset_t __user *old)
399 {
400         sigset_t oldbits, newbits;
401
402         if (new) {
403                 if (!access_ok(VERIFY_READ, new, sizeof(*new)))
404                         return -EFAULT;
405                 if (__copy_from_user(&newbits, new, sizeof(unsigned long)*4))
406                         return -EFAULT;
407                 sigdelsetmask(&newbits, ~_BLOCKABLE);
408
409                 spin_lock_irq(&current->sighand->siglock);
410                 oldbits = current->blocked;
411
412                 switch(how) {
413                 case 1:
414                         sigorsets(&newbits, &oldbits, &newbits);
415                         break;
416
417                 case 2:
418                         sigandsets(&newbits, &oldbits, &newbits);
419                         break;
420
421                 case 3:
422                         break;
423
424                 case 256:
425                         siginitset(&newbits, newbits.sig[0]);
426                         break;
427
428                 default:
429                         return -EINVAL;
430                 }
431                 recalc_sigpending();
432                 spin_unlock_irq(&current->sighand->siglock);
433         }
434         if (old)
435                 return copy_to_user(old, &current->blocked,
436                                   sizeof(unsigned long)*4) ? -EFAULT : 0;
437
438         return 0;
439 }
440
441 asmlinkage int irix_sigsuspend(struct pt_regs *regs)
442 {
443         sigset_t newset;
444         sigset_t __user *uset;
445
446         uset = (sigset_t __user *) regs->regs[4];
447         if (copy_from_user(&newset, uset, sizeof(sigset_t)))
448                 return -EFAULT;
449         sigdelsetmask(&newset, ~_BLOCKABLE);
450
451         spin_lock_irq(&current->sighand->siglock);
452         current->saved_sigmask = current->blocked;
453         current->blocked = newset;
454         recalc_sigpending();
455         spin_unlock_irq(&current->sighand->siglock);
456
457         current->state = TASK_INTERRUPTIBLE;
458         schedule();
459         set_thread_flag(TIF_RESTORE_SIGMASK);
460         return -ERESTARTNOHAND;
461 }
462
463 /* hate hate hate... */
464 struct irix5_siginfo {
465         int sig, code, error;
466         union {
467                 char unused[128 - (3 * 4)]; /* Safety net. */
468                 struct {
469                         int pid;
470                         union {
471                                 int uid;
472                                 struct {
473                                         int utime, status, stime;
474                                 } child;
475                         } procdata;
476                 } procinfo;
477
478                 unsigned long fault_addr;
479
480                 struct {
481                         int fd;
482                         long band;
483                 } fileinfo;
484
485                 unsigned long sigval;
486         } stuff;
487 };
488
489 asmlinkage int irix_sigpoll_sys(unsigned long __user *set,
490         struct irix5_siginfo __user *info, struct timespec __user *tp)
491 {
492         long expire = MAX_SCHEDULE_TIMEOUT;
493         sigset_t kset;
494         int i, sig, error, timeo = 0;
495         struct timespec ktp;
496
497 #ifdef DEBUG_SIG
498         printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n",
499                current->comm, current->pid, set, info, tp);
500 #endif
501
502         /* Must always specify the signal set. */
503         if (!set)
504                 return -EINVAL;
505
506         if (copy_from_user(&kset, set, sizeof(set)))
507                 return -EFAULT;
508
509         if (info && clear_user(info, sizeof(*info))) {
510                 error = -EFAULT;
511                 goto out;
512         }
513
514         if (tp) {
515                 if (copy_from_user(&ktp, tp, sizeof(*tp)))
516                         return -EFAULT;
517
518                 if (!ktp.tv_sec && !ktp.tv_nsec)
519                         return -EINVAL;
520
521                 expire = timespec_to_jiffies(&ktp) +
522                          (ktp.tv_sec || ktp.tv_nsec);
523         }
524
525         while(1) {
526                 long tmp = 0;
527
528                 expire = schedule_timeout_interruptible(expire);
529
530                 for (i=0; i<=4; i++)
531                         tmp |= (current->pending.signal.sig[i] & kset.sig[i]);
532
533                 if (tmp)
534                         break;
535                 if (!expire) {
536                         timeo = 1;
537                         break;
538                 }
539                 if (signal_pending(current))
540                         return -EINTR;
541         }
542         if (timeo)
543                 return -EAGAIN;
544
545         for (sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
546                 if (sigismember (&kset, sig))
547                         continue;
548                 if (sigismember (&current->pending.signal, sig)) {
549                         /* XXX need more than this... */
550                         if (info)
551                                 return copy_to_user(&info->sig, &sig, sizeof(sig));
552                         return 0;
553                 }
554         }
555
556         /* Should not get here, but do something sane if we do. */
557         error = -EINTR;
558
559 out:
560         return error;
561 }
562
563 /* This is here because of irix5_siginfo definition. */
564 #define IRIX_P_PID    0
565 #define IRIX_P_PGID   2
566 #define IRIX_P_ALL    7
567
568 #define W_EXITED     1
569 #define W_TRAPPED    2
570 #define W_STOPPED    4
571 #define W_CONT       8
572 #define W_NOHANG    64
573
574 #define W_MASK      (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG)
575
576 asmlinkage int irix_waitsys(int type, int pid,
577         struct irix5_siginfo __user *info, int options,
578         struct rusage __user *ru)
579 {
580         int flag, retval;
581         DECLARE_WAITQUEUE(wait, current);
582         struct task_struct *tsk;
583         struct task_struct *p;
584         struct list_head *_p;
585
586         if (!info)
587                 return -EINVAL;
588
589         if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
590                 return -EFAULT;
591
592         if (ru)
593                 if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)))
594                         return -EFAULT;
595
596         if (options & ~W_MASK)
597                 return -EINVAL;
598
599         if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL)
600                 return -EINVAL;
601
602         add_wait_queue(&current->signal->wait_chldexit, &wait);
603 repeat:
604         flag = 0;
605         current->state = TASK_INTERRUPTIBLE;
606         read_lock(&tasklist_lock);
607         tsk = current;
608         list_for_each(_p,&tsk->children) {
609                 p = list_entry(_p,struct task_struct,sibling);
610                 if ((type == IRIX_P_PID) && p->pid != pid)
611                         continue;
612                 if ((type == IRIX_P_PGID) && process_group(p) != pid)
613                         continue;
614                 if ((p->exit_signal != SIGCHLD))
615                         continue;
616                 flag = 1;
617                 switch (p->state) {
618                 case TASK_STOPPED:
619                         if (!p->exit_code)
620                                 continue;
621                         if (!(options & (W_TRAPPED|W_STOPPED)) &&
622                             !(p->ptrace & PT_PTRACED))
623                                 continue;
624                         read_unlock(&tasklist_lock);
625
626                         /* move to end of parent's list to avoid starvation */
627                         write_lock_irq(&tasklist_lock);
628                         remove_parent(p);
629                         add_parent(p);
630                         write_unlock_irq(&tasklist_lock);
631                         retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
632                         if (retval)
633                                 goto end_waitsys;
634
635                         retval = __put_user(SIGCHLD, &info->sig);
636                         retval |= __put_user(0, &info->code);
637                         retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
638                         retval |= __put_user((p->exit_code >> 8) & 0xff,
639                                    &info->stuff.procinfo.procdata.child.status);
640                         retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime);
641                         retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime);
642                         if (retval)
643                                 goto end_waitsys;
644
645                         p->exit_code = 0;
646                         goto end_waitsys;
647
648                 case EXIT_ZOMBIE:
649                         current->signal->cutime += p->utime + p->signal->cutime;
650                         current->signal->cstime += p->stime + p->signal->cstime;
651                         if (ru != NULL)
652                                 getrusage(p, RUSAGE_BOTH, ru);
653                         retval = __put_user(SIGCHLD, &info->sig);
654                         retval |= __put_user(1, &info->code);      /* CLD_EXITED */
655                         retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
656                         retval |= __put_user((p->exit_code >> 8) & 0xff,
657                                    &info->stuff.procinfo.procdata.child.status);
658                         retval |= __put_user(p->utime,
659                                    &info->stuff.procinfo.procdata.child.utime);
660                         retval |= __put_user(p->stime,
661                                    &info->stuff.procinfo.procdata.child.stime);
662                         if (retval)
663                                 return retval;
664
665                         if (p->real_parent != p->parent) {
666                                 write_lock_irq(&tasklist_lock);
667                                 remove_parent(p);
668                                 p->parent = p->real_parent;
669                                 add_parent(p);
670                                 do_notify_parent(p, SIGCHLD);
671                                 write_unlock_irq(&tasklist_lock);
672                         } else
673                                 release_task(p);
674                         goto end_waitsys;
675                 default:
676                         continue;
677                 }
678                 tsk = next_thread(tsk);
679         }
680         read_unlock(&tasklist_lock);
681         if (flag) {
682                 retval = 0;
683                 if (options & W_NOHANG)
684                         goto end_waitsys;
685                 retval = -ERESTARTSYS;
686                 if (signal_pending(current))
687                         goto end_waitsys;
688                 current->state = TASK_INTERRUPTIBLE;
689                 schedule();
690                 goto repeat;
691         }
692         retval = -ECHILD;
693 end_waitsys:
694         current->state = TASK_RUNNING;
695         remove_wait_queue(&current->signal->wait_chldexit, &wait);
696
697         return retval;
698 }
699
700 struct irix5_context {
701         u32 flags;
702         u32 link;
703         u32 sigmask[4];
704         struct { u32 sp, size, flags; } stack;
705         int regs[36];
706         u32 fpregs[32];
707         u32 fpcsr;
708         u32 _unused0;
709         u32 _unused1[47];
710         u32 weird_graphics_thing;
711 };
712
713 asmlinkage int irix_getcontext(struct pt_regs *regs)
714 {
715         int error, i, base = 0;
716         struct irix5_context __user *ctx;
717         unsigned long flags;
718
719         if (regs->regs[2] == 1000)
720                 base = 1;
721         ctx = (struct irix5_context __user *) regs->regs[base + 4];
722
723 #ifdef DEBUG_SIG
724         printk("[%s:%d] irix_getcontext(%p)\n",
725                current->comm, current->pid, ctx);
726 #endif
727
728         if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)));
729                 return -EFAULT;
730
731         error = __put_user(current->thread.irix_oldctx, &ctx->link);
732
733         error |= __copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t)) ? -EFAULT : 0;
734
735         /* XXX Do sigstack stuff someday... */
736         error |= __put_user(0, &ctx->stack.sp);
737         error |= __put_user(0, &ctx->stack.size);
738         error |= __put_user(0, &ctx->stack.flags);
739
740         error |= __put_user(0, &ctx->weird_graphics_thing);
741         error |= __put_user(0, &ctx->regs[0]);
742         for (i = 1; i < 32; i++)
743                 error |= __put_user(regs->regs[i], &ctx->regs[i]);
744         error |= __put_user(regs->lo, &ctx->regs[32]);
745         error |= __put_user(regs->hi, &ctx->regs[33]);
746         error |= __put_user(regs->cp0_cause, &ctx->regs[34]);
747         error |= __put_user(regs->cp0_epc, &ctx->regs[35]);
748
749         flags = 0x0f;
750         if (!used_math()) {
751                 flags &= ~(0x08);
752         } else {
753                 /* XXX wheee... */
754                 printk("Wheee, no code for saving IRIX FPU context yet.\n");
755         }
756         error |= __put_user(flags, &ctx->flags);
757
758         return error;
759 }
760
761 asmlinkage void irix_setcontext(struct pt_regs *regs)
762 {
763         struct irix5_context __user *ctx;
764         int err, base = 0;
765         u32 flags;
766
767         if (regs->regs[2] == 1000)
768                 base = 1;
769         ctx = (struct irix5_context __user *) regs->regs[base + 4];
770
771 #ifdef DEBUG_SIG
772         printk("[%s:%d] irix_setcontext(%p)\n",
773                current->comm, current->pid, ctx);
774 #endif
775
776         if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx)))
777                 goto segv_and_exit;
778
779         err = __get_user(flags, &ctx->flags);
780         if (flags & 0x02) {
781                 /* XXX sigstack garbage, todo... */
782                 printk("Wheee, cannot do sigstack stuff in setcontext\n");
783         }
784
785         if (flags & 0x04) {
786                 int i;
787
788                 /* XXX extra control block stuff... todo... */
789                 for (i = 1; i < 32; i++)
790                         err |= __get_user(regs->regs[i], &ctx->regs[i]);
791                 err |= __get_user(regs->lo, &ctx->regs[32]);
792                 err |= __get_user(regs->hi, &ctx->regs[33]);
793                 err |= __get_user(regs->cp0_epc, &ctx->regs[35]);
794         }
795
796         if (flags & 0x08)
797                 /* XXX fpu context, blah... */
798                 printk(KERN_ERR "Wheee, cannot restore FPU context yet...\n");
799
800         err |= __get_user(current->thread.irix_oldctx, &ctx->link);
801         if (err)
802                 goto segv_and_exit;
803
804         /*
805          * Don't let your children do this ...
806          */
807         __asm__ __volatile__(
808                 "move\t$29,%0\n\t"
809                 "j\tsyscall_exit"
810                 :/* no outputs */
811                 :"r" (&regs));
812                 /* Unreached */
813
814 segv_and_exit:
815         force_sigsegv(SIGSEGV, current);
816 }
817
818 struct irix_sigstack {
819         unsigned long sp;
820         int status;
821 };
822
823 asmlinkage int irix_sigstack(struct irix_sigstack __user *new,
824         struct irix_sigstack __user *old)
825 {
826 #ifdef DEBUG_SIG
827         printk("[%s:%d] irix_sigstack(%p,%p)\n",
828                current->comm, current->pid, new, old);
829 #endif
830         if (new) {
831                 if (!access_ok(VERIFY_READ, new, sizeof(*new)))
832                         return -EFAULT;
833         }
834
835         if (old) {
836                 if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
837                         return -EFAULT;
838         }
839
840         return 0;
841 }
842
843 struct irix_sigaltstack { unsigned long sp; int size; int status; };
844
845 asmlinkage int irix_sigaltstack(struct irix_sigaltstack __user *new,
846                                 struct irix_sigaltstack __user *old)
847 {
848 #ifdef DEBUG_SIG
849         printk("[%s:%d] irix_sigaltstack(%p,%p)\n",
850                current->comm, current->pid, new, old);
851 #endif
852         if (new)
853                 if (!access_ok(VERIFY_READ, new, sizeof(*new)))
854                         return -EFAULT;
855
856         if (old) {
857                 if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
858                         return -EFAULT;
859         }
860
861         return 0;
862 }
863
864 struct irix_procset {
865         int cmd, ltype, lid, rtype, rid;
866 };
867
868 asmlinkage int irix_sigsendset(struct irix_procset __user *pset, int sig)
869 {
870         if (!access_ok(VERIFY_READ, pset, sizeof(*pset)))
871                 return -EFAULT;
872 #ifdef DEBUG_SIG
873         printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n",
874                current->comm, current->pid,
875                pset->cmd, pset->ltype, pset->lid, pset->rtype, pset->rid,
876                sig);
877 #endif
878         return -EINVAL;
879 }