OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [mips/] [kernel/] [irixsig.c] - Blame information for rev 3

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.