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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [ppc64/] [kernel/] [signal.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  linux/arch/ppc64/kernel/signal.c
3
 *
4
 *  PowerPC version
5
 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6
 *
7
 *  Derived from "arch/i386/kernel/signal.c"
8
 *    Copyright (C) 1991, 1992 Linus Torvalds
9
 *    1997-11-28  Modified for POSIX.1b signals by Richard Henderson
10
 *
11
 *  This program is free software; you can redistribute it and/or
12
 *  modify it under the terms of the GNU General Public License
13
 *  as published by the Free Software Foundation; either version
14
 *  2 of the License, or (at your option) any later version.
15
 */
16
 
17
#include <linux/sched.h>
18
#include <linux/mm.h>
19
#include <linux/smp.h>
20
#include <linux/smp_lock.h>
21
#include <linux/kernel.h>
22
#include <linux/signal.h>
23
#include <linux/errno.h>
24
#include <linux/wait.h>
25
#include <linux/ptrace.h>
26
#include <linux/unistd.h>
27
#include <linux/stddef.h>
28
#include <linux/elf.h>
29
#include <asm/ppc32.h>
30
#include <asm/sigcontext.h>
31
#include <asm/ucontext.h>
32
#include <asm/uaccess.h>
33
#include <asm/pgtable.h>
34
#include <asm/ppcdebug.h>
35
#include <asm/unistd.h>
36
 
37
#define DEBUG_SIG 0
38
 
39
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
40
 
41
#ifndef MIN
42
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
43
#endif
44
 
45
#define GP_REGS_SIZE    MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs))
46
#define FP_REGS_SIZE    sizeof(elf_fpregset_t)
47
 
48
#define TRAMP_TRACEBACK 3
49
#define TRAMP_SIZE      6
50
 
51
/*
52
 * When we have signals to deliver, we set up on the user stack,
53
 * going down from the original stack pointer:
54
 *      1) a sigframe/rt_sigframe struct which contains the sigcontext/ucontext
55
 *      2) a gap of __SIGNAL_FRAMESIZE bytes which acts as a dummy caller
56
 *         frame for the signal handler.
57
 */
58
 
59
struct sigframe {
60
        /* sys_sigreturn requires the sigcontext be the first field */
61
        struct sigcontext sc;
62
        unsigned int tramp[TRAMP_SIZE];
63
        /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
64
        char abigap[288];
65
};
66
 
67
struct rt_sigframe {
68
        /* sys_rt_sigreturn requires the ucontext be the first field */
69
        struct ucontext uc;
70
        unsigned long _unused[2];
71
        unsigned int tramp[TRAMP_SIZE];
72
        struct siginfo *pinfo;
73
        void *puc;
74
        struct siginfo info;
75
        /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
76
        char abigap[288];
77
};
78
 
79
extern long sys_wait4(pid_t pid, unsigned int *stat_addr,
80
                     int options, /*unsigned long*/ struct rusage *ru);
81
 
82
int
83
copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
84
{
85
        if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
86
                return -EFAULT;
87
        if (from->si_code < 0)
88
                return __copy_to_user(to, from, sizeof(siginfo_t));
89
        else {
90
                int err;
91
 
92
                /* If you change siginfo_t structure, please be sure
93
                   this code is fixed accordingly.
94
                   It should never copy any pad contained in the structure
95
                   to avoid security leaks, but must copy the generic
96
                   3 ints plus the relevant union member.  */
97
                err = __put_user(from->si_signo, &to->si_signo);
98
                err |= __put_user(from->si_errno, &to->si_errno);
99
                err |= __put_user((short)from->si_code, &to->si_code);
100
                /* First 32bits of unions are always present.  */
101
                err |= __put_user(from->si_pid, &to->si_pid);
102
                switch (from->si_code >> 16) {
103
                case __SI_FAULT >> 16:
104
                        err |= __put_user(from->si_addr, &to->si_addr);
105
                        break;
106
                case __SI_CHLD >> 16:
107
                        err |= __put_user(from->si_utime, &to->si_utime);
108
                        err |= __put_user(from->si_stime, &to->si_stime);
109
                        err |= __put_user(from->si_status, &to->si_status);
110
                default:
111
                        err |= __put_user(from->si_uid, &to->si_uid);
112
                        break;
113
                /* case __SI_RT: This is not generated by the kernel as of now.  */
114
                }
115
                return err;
116
        }
117
}
118
 
119
int do_signal(sigset_t *oldset, struct pt_regs *regs);
120
 
121
/*
122
 * Atomically swap in the new signal mask, and wait for a signal.
123
 */
124
asmlinkage long
125
sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
126
               struct pt_regs *regs)
127
{
128
        sigset_t saveset;
129
 
130
        mask &= _BLOCKABLE;
131
        spin_lock_irq(&current->sigmask_lock);
132
        saveset = current->blocked;
133
        siginitset(&current->blocked, mask);
134
        recalc_sigpending(current);
135
        spin_unlock_irq(&current->sigmask_lock);
136
 
137
        regs->result = -EINTR;
138
        regs->gpr[3] = EINTR;
139
        regs->ccr |= 0x10000000;
140
        while (1) {
141
                current->state = TASK_INTERRUPTIBLE;
142
                schedule();
143
                if (do_signal(&saveset, regs))
144
                        /*
145
                         * If a signal handler needs to be called,
146
                         * do_signal() has set R3 to the signal number (the
147
                         * first argument of the signal handler), so don't
148
                         * overwrite that with EINTR !
149
                         * In the other cases, do_signal() doesn't touch
150
                         * R3, so it's still set to -EINTR (see above).
151
                         */
152
                        return regs->gpr[3];
153
        }
154
}
155
 
156
asmlinkage long
157
sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6,
158
                  int p7, struct pt_regs *regs)
159
{
160
        sigset_t saveset, newset;
161
 
162
        /* XXX: Don't preclude handling different sized sigset_t's.  */
163
        if (sigsetsize != sizeof(sigset_t))
164
                return -EINVAL;
165
 
166
        if (copy_from_user(&newset, unewset, sizeof(newset)))
167
                return -EFAULT;
168
        sigdelsetmask(&newset, ~_BLOCKABLE);
169
 
170
        spin_lock_irq(&current->sigmask_lock);
171
        saveset = current->blocked;
172
        current->blocked = newset;
173
        recalc_sigpending(current);
174
        spin_unlock_irq(&current->sigmask_lock);
175
 
176
        regs->result = -EINTR;
177
        regs->gpr[3] = EINTR;
178
        regs->ccr |= 0x10000000;
179
        while (1) {
180
                current->state = TASK_INTERRUPTIBLE;
181
                schedule();
182
                if (do_signal(&saveset, regs))
183
                        return regs->gpr[3];
184
        }
185
}
186
 
187
asmlinkage long
188
sys_sigaltstack(const stack_t *uss, stack_t *uoss, unsigned long r5,
189
                unsigned long r6, unsigned long r7, unsigned long r8,
190
                struct pt_regs *regs)
191
{
192
        return do_sigaltstack(uss, uoss, regs->gpr[1]);
193
}
194
 
195
asmlinkage long
196
sys_sigaction(int sig, const struct old_sigaction *act,
197
              struct old_sigaction *oact)
198
{
199
        struct k_sigaction new_ka, old_ka;
200
        int ret;
201
 
202
        if (act) {
203
                old_sigset_t mask;
204
 
205
                if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
206
                    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
207
                    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
208
                        return -EFAULT;
209
                __get_user(new_ka.sa.sa_flags, &act->sa_flags);
210
                __get_user(mask, &act->sa_mask);
211
                siginitset(&new_ka.sa.sa_mask, mask);
212
        }
213
 
214
        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
215
        if (!ret && oact) {
216
                if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
217
                    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
218
                    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
219
                        return -EFAULT;
220
                __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
221
                __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
222
        }
223
 
224
        return ret;
225
}
226
 
227
/*
228
 * Set up the sigcontext for the signal frame.
229
 */
230
 
231
static int
232
setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
233
                 int signr, sigset_t *set, unsigned long handler)
234
{
235
        int err = 0;
236
 
237
        if (regs->msr & MSR_FP)
238
                giveup_fpu(current);
239
 
240
        current->thread.saved_msr = regs->msr & ~(MSR_FP | MSR_FE0 | MSR_FE1);
241
        regs->msr = current->thread.saved_msr | current->thread.fpexc_mode;
242
        current->thread.saved_softe = regs->softe;
243
 
244
        err |= __put_user(&sc->gp_regs, &sc->regs);
245
        err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
246
        err |= __copy_to_user(&sc->fp_regs, &current->thread.fpr, FP_REGS_SIZE);
247
        err |= __put_user(signr, &sc->signal);
248
        err |= __put_user(handler, &sc->handler);
249
        if (set != NULL)
250
                err |=  __put_user(set->sig[0], &sc->oldmask);
251
 
252
        regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
253
        current->thread.fpscr = 0;
254
 
255
        return err;
256
}
257
 
258
/*
259
 * Restore the sigcontext from the signal frame.
260
 */
261
 
262
static int
263
restore_sigcontext(struct pt_regs *regs, sigset_t *set, struct sigcontext *sc)
264
{
265
        unsigned int err = 0;
266
 
267
        if (regs->msr & MSR_FP)
268
                giveup_fpu(current);
269
 
270
        err |= __copy_from_user(regs, &sc->gp_regs, GP_REGS_SIZE);
271
        err |= __copy_from_user(&current->thread.fpr, &sc->fp_regs, FP_REGS_SIZE);
272
        current->thread.fpexc_mode = regs->msr & (MSR_FE0 | MSR_FE1);
273
        if (set != NULL)
274
                err |=  __get_user(set->sig[0], &sc->oldmask);
275
 
276
        /* Don't allow the signal handler to change these modulo FE{0,1} */
277
        regs->msr = current->thread.saved_msr & ~(MSR_FP | MSR_FE0 | MSR_FE1);
278
        regs->softe = current->thread.saved_softe;
279
 
280
        return err;
281
}
282
 
283
/*
284
 * Allocate space for the signal frame
285
 */
286
static inline void *
287
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
288
{
289
        unsigned long newsp;
290
 
291
        /* Default to using normal stack */
292
        newsp = regs->gpr[1];
293
 
294
        if (ka->sa.sa_flags & SA_ONSTACK) {
295
                if (! on_sig_stack(regs->gpr[1]))
296
                        newsp = (current->sas_ss_sp + current->sas_ss_size);
297
        }
298
 
299
        /* The ABI requires quadword alignment for the stack. */
300
        return (void *)((newsp - frame_size) & -16ul);
301
 
302
}
303
 
304
static int
305
setup_trampoline(unsigned int syscall, unsigned int *tramp)
306
{
307
        int i, err = 0;
308
 
309
        /* addi r1, r1, __SIGNAL_FRAMESIZE  # Pop the dummy stackframe */
310
        err |= __put_user(0x38210000UL | (__SIGNAL_FRAMESIZE & 0xffff), &tramp[0]);
311
        /* li r0, __NR_[rt_]sigreturn| */
312
        err |= __put_user(0x38000000UL | (syscall & 0xffff), &tramp[1]);
313
        /* sc */
314
        err |= __put_user(0x44000002UL, &tramp[2]);
315
 
316
        /* Minimal traceback info */
317
        for (i=TRAMP_TRACEBACK; i < TRAMP_SIZE ;i++)
318
                err |= __put_user(0, &tramp[i]);
319
 
320
        if (!err)
321
                flush_icache_range((unsigned long) &tramp[0],
322
                           (unsigned long) &tramp[TRAMP_SIZE]);
323
 
324
        return err;
325
}
326
 
327
 
328
asmlinkage int
329
sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
330
                 unsigned long r6, unsigned long r7, unsigned long r8,
331
                 struct pt_regs *regs)
332
{
333
        struct ucontext *uc = (struct ucontext *)regs->gpr[1];
334
        sigset_t set;
335
        stack_t st;
336
 
337
        if (verify_area(VERIFY_READ, uc, sizeof(*uc)))
338
                goto badframe;
339
 
340
        if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
341
                goto badframe;
342
 
343
        sigdelsetmask(&set, ~_BLOCKABLE);
344
        spin_lock_irq(&current->sigmask_lock);
345
        current->blocked = set;
346
        recalc_sigpending(current);
347
        spin_unlock_irq(&current->sigmask_lock);
348
 
349
        if (restore_sigcontext(regs, NULL, &uc->uc_mcontext))
350
                goto badframe;
351
 
352
        if (__copy_from_user(&st, &uc->uc_stack, sizeof(st)))
353
                goto badframe;
354
 
355
        /* This function sets back the stack flags into
356
           the current task structure.  */
357
        sys_sigaltstack(&st, NULL, 0, 0, 0, 0, regs);
358
 
359
        return regs->result;
360
 
361
badframe:
362
        do_exit(SIGSEGV);
363
}
364
 
365
static void
366
setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
367
                sigset_t *set, struct pt_regs *regs)
368
{
369
        /* Handler is *really* a pointer to the function descriptor for
370
         * the signal routine.  The first entry in the function
371
         * descriptor is the entry address of signal and the second
372
         * entry is the TOC value we need to use.
373
         */
374
        func_descr_t *funct_desc_ptr;
375
        struct rt_sigframe *frame;
376
        unsigned long newsp;
377
        int err = 0;
378
 
379
        frame = get_sigframe(ka, regs, sizeof(*frame));
380
 
381
        if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
382
                goto give_sigsegv;
383
 
384
        err |= __put_user(&frame->info, &frame->pinfo);
385
        err |= __put_user(&frame->uc, &frame->puc);
386
        err |= copy_siginfo_to_user(&frame->info, info);
387
        if (err)
388
                goto give_sigsegv;
389
 
390
        /* Create the ucontext.  */
391
        err |= __put_user(0, &frame->uc.uc_flags);
392
        err |= __put_user(0, &frame->uc.uc_link);
393
        err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
394
        err |= __put_user(sas_ss_flags(regs->gpr[1]),
395
                          &frame->uc.uc_stack.ss_flags);
396
        err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
397
        err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL,
398
                                (unsigned long)ka->sa.sa_handler);
399
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
400
        if (err)
401
                goto give_sigsegv;
402
 
403
        /* Set up to return from userspace. */
404
        err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
405
        if (err)
406
                goto give_sigsegv;
407
 
408
        funct_desc_ptr = (func_descr_t *) ka->sa.sa_handler;
409
 
410
        /* Allocate a dummy caller frame for the signal handler. */
411
        newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE;
412
        err |= put_user(0, (unsigned long *)newsp);
413
 
414
        /* Set up "regs" so we "return" to the signal handler. */
415
        err |= get_user(regs->nip, &funct_desc_ptr->entry);
416
        regs->link = (unsigned long) &frame->tramp[0];
417
        regs->gpr[1] = newsp;
418
        err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
419
        regs->gpr[3] = signr;
420
        err |= get_user(regs->gpr[4], (unsigned long *)&frame->pinfo);
421
        err |= get_user(regs->gpr[5], (unsigned long *)&frame->puc);
422
        regs->gpr[6] = (unsigned long) frame;
423
        if (err)
424
                goto give_sigsegv;
425
 
426
        return;
427
 
428
give_sigsegv:
429
#if DEBUG_SIG
430
        printk("badframe in setup_rt_frame, regs=%p frame=%p, newsp=0x%lx\n",
431
                regs, frame, newsp);
432
#endif
433
        do_exit(SIGSEGV);
434
}
435
 
436
/*
437
 * Do a signal return; undo the signal stack.
438
 */
439
asmlinkage long
440
sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
441
              unsigned long r6, unsigned long r7, unsigned long r8,
442
              struct pt_regs *regs)
443
{
444
        struct sigcontext *sc = (struct sigcontext *)regs->gpr[1];
445
        sigset_t set;
446
 
447
        if (verify_area(VERIFY_READ, sc, sizeof(*sc)))
448
                goto badframe;
449
 
450
        if (restore_sigcontext(regs, &set, sc))
451
                goto badframe;
452
 
453
        sigdelsetmask(&set, ~_BLOCKABLE);
454
        spin_lock_irq(&current->sigmask_lock);
455
        current->blocked = set;
456
        recalc_sigpending(current);
457
        spin_unlock_irq(&current->sigmask_lock);
458
 
459
        return regs->result;
460
 
461
badframe:
462
        do_exit(SIGSEGV);
463
}
464
 
465
 
466
static void
467
setup_frame(int signr, struct k_sigaction *ka, sigset_t *set,
468
            struct pt_regs *regs)
469
{
470
        /* Handler is *really* a pointer to the function descriptor for
471
         * the signal routine.  The first entry in the function
472
         * descriptor is the entry address of signal and the second
473
         * entry is the TOC value we need to use.
474
         */
475
        func_descr_t *funct_desc_ptr;
476
        struct sigframe *frame;
477
        unsigned long newsp;
478
        int err = 0;
479
 
480
        frame = get_sigframe(ka, regs, sizeof(*frame));
481
 
482
        if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
483
                goto badframe;
484
 
485
        err |= setup_sigcontext(&frame->sc, regs, signr, set,
486
                                (unsigned long)ka->sa.sa_handler);
487
 
488
        /* Set up to return from userspace. */
489
        err |= setup_trampoline(__NR_sigreturn, &frame->tramp[0]);
490
        if (err)
491
                goto badframe;
492
 
493
        funct_desc_ptr = (func_descr_t *) ka->sa.sa_handler;
494
 
495
        /* Allocate a dummy caller frame for the signal handler. */
496
        newsp = (unsigned long)frame - __SIGNAL_FRAMESIZE;
497
        err |= put_user(0, (unsigned long *)newsp);
498
 
499
        /* Set up "regs" so we "return" to the signal handler. */
500
        err |= get_user(regs->nip, &funct_desc_ptr->entry);
501
        regs->link = (unsigned long) &frame->tramp[0];
502
        regs->gpr[1] = newsp;
503
        err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
504
        regs->gpr[3] = signr;
505
        regs->gpr[4] = (unsigned long) &frame->sc;
506
        if (err)
507
                goto badframe;
508
 
509
        return;
510
 
511
badframe:
512
#if DEBUG_SIG
513
        printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
514
               regs, frame, newsp);
515
#endif
516
        do_exit(SIGSEGV);
517
}
518
 
519
/*
520
 * OK, we're invoking a handler
521
 */
522
static void
523
handle_signal(unsigned long sig, struct k_sigaction *ka,
524
              siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
525
{
526
        /* Set up Signal Frame */
527
        if (ka->sa.sa_flags & SA_SIGINFO)
528
                setup_rt_frame(sig, ka, info, oldset, regs);
529
        else
530
                setup_frame(sig, ka, oldset, regs);
531
 
532
        if (ka->sa.sa_flags & SA_ONESHOT)
533
                ka->sa.sa_handler = SIG_DFL;
534
 
535
        if (!(ka->sa.sa_flags & SA_NODEFER)) {
536
                spin_lock_irq(&current->sigmask_lock);
537
                sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
538
                sigaddset(&current->blocked,sig);
539
                recalc_sigpending(current);
540
                spin_unlock_irq(&current->sigmask_lock);
541
        }
542
}
543
 
544
static inline void
545
syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
546
{
547
        switch ((int)regs->result) {
548
                case -ERESTARTNOHAND:
549
                        /* ERESTARTNOHAND means that the syscall should only
550
                           be restarted if there was no handler for the signal,
551
                           and since we only get here if there is a handler,
552
                           we dont restart */
553
                        regs->result = -EINTR;
554
                        break;
555
 
556
                case -ERESTARTSYS:
557
                        /* ERESTARTSYS means to restart the syscall if there is
558
                           no handler or the handler was registered with SA_RESTART */
559
                        if (!(ka->sa.sa_flags & SA_RESTART)) {
560
                                regs->result = -EINTR;
561
                                break;
562
                        }
563
                /* fallthrough */
564
                case -ERESTARTNOINTR:
565
                        /* ERESTARTNOINTR means that the syscall should be
566
                           called again after the signal handler returns */
567
                        regs->gpr[3] = regs->orig_gpr3;
568
                        regs->nip -= 4;
569
                        regs->result = 0;
570
        }
571
}
572
 
573
static int
574
get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs)
575
{
576
        for (;;) {
577
                unsigned long signr;
578
                struct k_sigaction *ka;
579
 
580
                spin_lock_irq(&current->sigmask_lock);
581
                signr = dequeue_signal(&current->blocked, info);
582
                spin_unlock_irq(&current->sigmask_lock);
583
 
584
                if (!signr)
585
                        break;
586
 
587
                if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
588
                        /* Let the debugger run.  */
589
                        current->exit_code = signr;
590
                        current->state = TASK_STOPPED;
591
                        notify_parent(current, SIGCHLD);
592
                        schedule();
593
 
594
                        /* We're back.  Did the debugger cancel the sig?  */
595
                        signr = current->exit_code;
596
                        if (signr == 0)
597
                                continue;
598
                        current->exit_code = 0;
599
 
600
                        /* The debugger continued.  Ignore SIGSTOP.  */
601
                        if (signr == SIGSTOP)
602
                                continue;
603
 
604
                        /* Update the siginfo structure.  Is this good?  */
605
                        if (signr != info->si_signo) {
606
                                info->si_signo = signr;
607
                                info->si_errno = 0;
608
                                info->si_code = SI_USER;
609
                                info->si_pid = current->p_pptr->pid;
610
                                info->si_uid = current->p_pptr->uid;
611
                        }
612
 
613
                        /* If the (new) signal is now blocked, requeue it.  */
614
                        if (sigismember(&current->blocked, signr)) {
615
                                send_sig_info(signr, info, current);
616
                                continue;
617
                        }
618
                }
619
 
620
                ka = &current->sig->action[signr-1];
621
 
622
                if (ka->sa.sa_handler == SIG_IGN) {
623
                        if (signr != SIGCHLD)
624
                                continue;
625
                        /* Check for SIGCHLD: it's special.  */
626
                        while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
627
                                /* nothing */;
628
                        continue;
629
                }
630
 
631
                if (ka->sa.sa_handler == SIG_DFL) {
632
                        int exit_code = signr;
633
 
634
                        /* Init gets no signals it doesn't want.  */
635
                        if (current->pid == 1)
636
                                continue;
637
 
638
                        switch (signr) {
639
                        case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
640
                                continue;
641
 
642
                        case SIGTSTP: case SIGTTIN: case SIGTTOU:
643
                                if (is_orphaned_pgrp(current->pgrp))
644
                                        continue;
645
                                /* FALLTHRU */
646
 
647
                        case SIGSTOP: {
648
                                struct signal_struct *sig;
649
                                current->state = TASK_STOPPED;
650
                                current->exit_code = signr;
651
                                sig = current->p_pptr->sig;
652
                                if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
653
                                        notify_parent(current, SIGCHLD);
654
                                schedule();
655
                                continue;
656
                        }
657
 
658
                        case SIGQUIT: case SIGILL: case SIGTRAP:
659
                        case SIGABRT: case SIGFPE: case SIGSEGV:
660
                        case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
661
                                if (do_coredump(signr, regs))
662
                                        exit_code |= 0x80;
663
                                /* FALLTHRU */
664
 
665
                        default:
666
                                sig_exit(signr, exit_code, info);
667
                                /* NOTREACHED */
668
                        }
669
                }
670
                return signr;
671
        }
672
        return 0;
673
}
674
 
675
/*
676
 * Note that 'init' is a special process: it doesn't get signals it doesn't
677
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
678
 * mistake.
679
 */
680
extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
681
 
682
int
683
do_signal(sigset_t *oldset, struct pt_regs *regs)
684
{
685
        siginfo_t info;
686
        int signr;
687
 
688
        /*
689
         * If the current thread is 32 bit - invoke the
690
         * 32 bit signal handling code
691
         */
692
        if (current->thread.flags & PPC_FLAG_32BIT)
693
                return do_signal32(oldset, regs);
694
 
695
        if (!oldset)
696
                oldset = &current->blocked;
697
 
698
        signr = get_signal_to_deliver(&info, regs);
699
        if (signr > 0) {
700
                struct k_sigaction *ka = &current->sig->action[signr-1];
701
 
702
                /* Whee!  Actually deliver the signal.  */
703
                if (regs->trap == 0x0C00)
704
                        syscall_restart(regs, ka);
705
                handle_signal(signr, ka, &info, oldset, regs);
706
                return 1;
707
        }
708
 
709
        if (regs->trap == 0x0C00 /* System Call! */ &&
710
            ((int)regs->result == -ERESTARTNOHAND ||
711
             (int)regs->result == -ERESTARTSYS ||
712
             (int)regs->result == -ERESTARTNOINTR)) {
713
                regs->gpr[3] = regs->orig_gpr3;
714
                regs->nip -= 4;         /* Back up & retry system call */
715
                regs->result = 0;
716
        }
717
 
718
        return 0;
719
}
720
 
721
 
722
 

powered by: WebSVN 2.1.0

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