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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [or32/] [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/or32/kernel/signal.c
3
 *
4
 *  or32 version
5
 *    author(s): Matjaz Breskvar (phoenix@opencores.org)
6
 *
7
 *  derived from cris, i386, m68k, ppc, sh ports.
8
 *
9
 *  changes:
10
 *  18. 11. 2003: Matjaz Breskvar (phoenix@opencores.org)
11
 *    initial port to or32 architecture
12
 *
13
 *  Based on linux/arch/cris/kernel/signal.c
14
 *    Copyright (C) 2000, 2001, 2002 Axis Communications AB
15
 *    Authors:  Bjorn Wesen (bjornw@axis.com)
16
 *
17
 */
18
 
19
#include <linux/sched.h>
20
#include <linux/mm.h>
21
#include <linux/smp.h>
22
#include <linux/smp_lock.h>
23
#include <linux/kernel.h>
24
#include <linux/signal.h>
25
#include <linux/errno.h>
26
#include <linux/wait.h>
27
#include <linux/ptrace.h>
28
#include <linux/unistd.h>
29
#include <linux/stddef.h>
30
 
31
#include <asm/processor.h>
32
#include <asm/ucontext.h>
33
#include <asm/uaccess.h>
34
#include <asm/or32-hf.h>
35
 
36
#define DEBUG_SIG 0
37
 
38
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
39
 
40
/* a syscall in Linux/OR32 is a "l.sys 1" instruction which is 4 bytes */
41
/* manipulate regs so that upon return, it will be re-executed */
42
 
43
/* We rely on that pc points to the instruction after "l.sys 1", so the
44
 * library must never do strange things like putting it in a delay slot.
45
 */
46
#define RESTART_OR32_SYS(regs) regs->gprs[1] = regs->orig_gpr3; regs->pc -= 4;
47
 
48
int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs);
49
 
50
int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
51
{
52
        phx_signal("to %p, from %p", to, from);
53
 
54
        if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
55
                return -EFAULT;
56
        if (from->si_code < 0)
57
                return __copy_to_user(to, from, sizeof(siginfo_t));
58
        else {
59
                int err;
60
 
61
                /* If you change siginfo_t structure, please be sure
62
                   this code is fixed accordingly.
63
                   It should never copy any pad contained in the structure
64
                   to avoid security leaks, but must copy the generic
65
                   3 ints plus the relevant union member.  */
66
                err = __put_user(from->si_signo, &to->si_signo);
67
                err |= __put_user(from->si_errno, &to->si_errno);
68
                err |= __put_user((short)from->si_code, &to->si_code);
69
                /* First 32bits of unions are always present.  */
70
                err |= __put_user(from->si_pid, &to->si_pid);
71
                switch (from->si_code >> 16) {
72
                case __SI_FAULT >> 16:
73
                        err |= __put_user(from->si_addr, &to->si_addr);
74
                        break;
75
                case __SI_CHLD >> 16:
76
                        err |= __put_user(from->si_utime, &to->si_utime);
77
                        err |= __put_user(from->si_stime, &to->si_stime);
78
                        err |= __put_user(from->si_status, &to->si_status);
79
                default:
80
                        err |= __put_user(from->si_uid, &to->si_uid);
81
                        break;
82
                /* case __SI_RT: This is not generated by the kernel as of now.  */
83
                }
84
                return err;
85
        }
86
}
87
 
88
/*
89
 * Atomically swap in the new signal mask, and wait for a signal.  Define
90
 * dummy arguments to be able to reach the regs argument.  (Note that this
91
 * arrangement relies on old_sigset_t occupying one register.)
92
 */
93
int sys_sigsuspend(old_sigset_t mask, long r4, long r5, long mof,
94
                   long srp, struct pt_regs *regs)
95
{
96
        sigset_t saveset;
97
        phx_signal("mask 0x%x, r4 0x%x, r5 0x%x, mof 0x%x, srp 0x%x, regs %p",
98
                   mask, r4, r5, mof, srp, regs);
99
 
100
 
101
        mask &= _BLOCKABLE;
102
        spin_lock_irq(&current->sigmask_lock);
103
        saveset = current->blocked;
104
        siginitset(&current->blocked, mask);
105
        recalc_sigpending(current);
106
        spin_unlock_irq(&current->sigmask_lock);
107
 
108
        regs->gprs[1] = -EINTR;
109
        while (1) {
110
                current->state = TASK_INTERRUPTIBLE;
111
                schedule();
112
                if (do_signal(0, &saveset, regs))
113
                        /* We will get here twice: once to call the signal
114
                           handler, then again to return from the
115
                           sigsuspend system call.  When calling the
116
                           signal handler, R10 holds the signal number as
117
                           set through do_signal.  The sigsuspend call
118
                           will return with the restored value set above;
119
                           always -EINTR.  */
120
                        return regs->gprs[1];
121
        }
122
}
123
 
124
/* Define dummy arguments to be able to reach the regs argument.  (Note that
125
 * this arrangement relies on size_t occupying one register.)
126
 */
127
int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r5,
128
                      long mof, long srp, struct pt_regs *regs)
129
{
130
        sigset_t saveset, newset;
131
 
132
        phx_signal("unewset %p, sigsetsize 0x%x, r5 0x%x, mof 0x%x, srp 0x%x, regs %p",
133
                   unewset, sigsetsize, r5, mof, srp, regs);
134
 
135
        /* XXX: Don't preclude handling different sized sigset_t's.  */
136
        if (sigsetsize != sizeof(sigset_t))
137
                return -EINVAL;
138
 
139
        if (copy_from_user(&newset, unewset, sizeof(newset)))
140
                return -EFAULT;
141
        sigdelsetmask(&newset, ~_BLOCKABLE);
142
 
143
        spin_lock_irq(&current->sigmask_lock);
144
        saveset = current->blocked;
145
        current->blocked = newset;
146
        recalc_sigpending(current);
147
        spin_unlock_irq(&current->sigmask_lock);
148
 
149
        regs->gprs[1] = -EINTR;
150
        while (1) {
151
                current->state = TASK_INTERRUPTIBLE;
152
                schedule();
153
                if (do_signal(0, &saveset, regs))
154
                        /* We will get here twice: once to call the signal
155
                           handler, then again to return from the
156
                           sigsuspend system call.  When calling the
157
                           signal handler, R10 holds the signal number as
158
                           set through do_signal.  The sigsuspend call
159
                           will return with the restored value set above;
160
                           always -EINTR.  */
161
                        return regs->gprs[1];
162
        }
163
}
164
 
165
int sys_sigaction(int sig, const struct old_sigaction *act,
166
                  struct old_sigaction *oact)
167
{
168
        struct k_sigaction new_ka, old_ka;
169
        int ret;
170
 
171
        phx_signal("sig %d, old act %p, old oact %p",
172
                   sig, act, oact);
173
 
174
        if (act) {
175
                old_sigset_t mask;
176
                if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
177
                    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
178
                    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
179
                        return -EFAULT;
180
                __get_user(new_ka.sa.sa_flags, &act->sa_flags);
181
                __get_user(mask, &act->sa_mask);
182
                siginitset(&new_ka.sa.sa_mask, mask);
183
        }
184
 
185
        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
186
 
187
        if (!ret && oact) {
188
                if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
189
                    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
190
                    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
191
                        return -EFAULT;
192
                __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
193
                __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
194
        }
195
 
196
        return ret;
197
}
198
 
199
int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
200
{
201
        struct pt_regs *regs = (struct pt_regs *) &uss;
202
        phx_signal("uss %p, uoss %p",
203
                   uss, uoss);
204
 
205
        return do_sigaltstack(uss, uoss, regs->sp);
206
}
207
 
208
 
209
/*
210
 * Do a signal return; undo the signal stack.
211
 */
212
 
213
struct sigframe {
214
        struct sigcontext sc;
215
        unsigned long extramask[_NSIG_WORDS-1];
216
        unsigned char retcode[16];  /* trampoline code */
217
};
218
 
219
struct rt_sigframe {
220
        struct siginfo *pinfo;
221
        void *puc;
222
        struct siginfo info;
223
        struct ucontext uc;
224
        unsigned char retcode[16];  /* trampoline code */
225
};
226
 
227
 
228
static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
229
{
230
        unsigned int err = 0;
231
        unsigned long old_usp;
232
 
233
        phx_signal("regs %p, sc %p",
234
                   regs, sc);
235
 
236
        /* restore the regs from &sc->regs (same as sc, since regs is first)
237
         * (sc is already checked for VERIFY_READ since the sigframe was
238
         *  checked in sys_sigreturn previously)
239
         */
240
 
241
        if (__copy_from_user(regs, sc, sizeof(struct pt_regs)))
242
                goto badframe;
243
 
244
        /* make sure the U-flag is set so user-mode cannot fool us */
245
 
246
        regs->sr &= ~SPR_SR_SM;
247
//      __PHX__ FIXME   
248
//      regs->dccr |= 1 << 8;
249
 
250
        /* restore the old USP as it was before we stacked the sc etc.
251
         * (we cannot just pop the sigcontext since we aligned the sp and
252
         *  stuff after pushing it)
253
         */
254
 
255
        err |= __get_user(old_usp, &sc->usp);
256
        phx_signal("old_usp 0x%x", old_usp);
257
 
258
//      __PHX__ REALLY ???
259
//      wrusp(old_usp);
260
        regs->sp = old_usp;
261
 
262
        /* TODO: the other ports use regs->orig_XX to disable syscall checks
263
         * after this completes, but we don't use that mechanism. maybe we can
264
         * use it now ?
265
         */
266
 
267
        return err;
268
 
269
badframe:
270
        return 1;
271
}
272
 
273
/* Define dummy arguments to be able to reach the regs argument.  */
274
 
275
asmlinkage int sys_sigreturn(long r3, long r4, long r5, long mof,
276
                             long srp, struct pt_regs *regs)
277
{
278
  //    struct sigframe *frame = (struct sigframe *)rdusp();
279
        struct sigframe *frame = (struct sigframe *)regs->sp;
280
 
281
        phx_signal("r3 0x%x, r4 0x%x, r5 0x%x, mof 0x%x, srp 0x%x, regs %p (regs->sp 0x%x)",
282
                   r3, r4, r5, mof, srp, regs, regs->sp);
283
 
284
        sigset_t set;
285
 
286
        /*
287
         * Since we stacked the signal on a dword boundary,
288
         * then frame should be dword aligned here.  If it's
289
         * not, then the user is trying to mess with us.
290
         */
291
        if (((long)frame) & 3)
292
                goto badframe;
293
 
294
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
295
                goto badframe;
296
        if (__get_user(set.sig[0], &frame->sc.oldmask)
297
            || (_NSIG_WORDS > 1
298
                && __copy_from_user(&set.sig[1], &frame->extramask,
299
                                    sizeof(frame->extramask))))
300
                goto badframe;
301
 
302
        sigdelsetmask(&set, ~_BLOCKABLE);
303
        spin_lock_irq(&current->sigmask_lock);
304
        current->blocked = set;
305
        recalc_sigpending(current);
306
 
307
        /* __PHX__ throw this out */
308
        phx_signal("SIGPENDING: %d", signal_pending(current));
309
 
310
        spin_unlock_irq(&current->sigmask_lock);
311
 
312
        if (restore_sigcontext(regs, &frame->sc))
313
                goto badframe;
314
 
315
        /* TODO: SIGTRAP when single-stepping as in arm ? */
316
 
317
        return regs->gprs[1];
318
 
319
badframe:
320
        force_sig(SIGSEGV, current);
321
        return 0;
322
}
323
 
324
/* Define dummy arguments to be able to reach the regs argument.  */
325
 
326
asmlinkage int sys_rt_sigreturn(long r3, long r4, long r5,
327
                                long mof, long srp, struct pt_regs *regs)
328
{
329
//      struct rt_sigframe *frame = (struct rt_sigframe *)rdusp();
330
        struct rt_sigframe *frame = (struct rt_sigframe *)regs->sp;
331
        sigset_t set;
332
        stack_t st;
333
 
334
        phx_signal("r3 0x%x, r4 0x%x, r5 0x%x, mof 0x%x, srp 0x%x, regs %p (regs->sp 0x%x)",
335
                   r3, r4, r5, mof, srp, regs, regs->sp);
336
 
337
        /*
338
         * Since we stacked the signal on a dword boundary,
339
         * then frame should be dword aligned here.  If it's
340
         * not, then the user is trying to mess with us.
341
         */
342
        if (((long)frame) & 3)
343
                goto badframe;
344
 
345
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
346
                goto badframe;
347
        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
348
                goto badframe;
349
 
350
        sigdelsetmask(&set, ~_BLOCKABLE);
351
        spin_lock_irq(&current->sigmask_lock);
352
        current->blocked = set;
353
        recalc_sigpending(current);
354
        spin_unlock_irq(&current->sigmask_lock);
355
 
356
        if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
357
                goto badframe;
358
 
359
        if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
360
                goto badframe;
361
        /* It is more difficult to avoid calling this function than to
362
           call it and ignore errors.  */
363
        do_sigaltstack(&st, NULL, regs->sp);
364
 
365
        return regs->gprs[1];
366
 
367
badframe:
368
        force_sig(SIGSEGV, current);
369
        return 0;
370
}
371
 
372
/*
373
 * Set up a signal frame.
374
 */
375
 
376
static int setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
377
                            unsigned long mask)
378
{
379
        int err = 0;
380
        unsigned long usp = regs->sp;
381
 
382
        phx_signal("sc %p, regs %p, mask 0x%x",
383
                   sc, regs, mask);
384
 
385
        /* copy the regs. they are first in sc so we can use sc directly */
386
 
387
        err |= __copy_to_user(sc, regs, sizeof(struct pt_regs));
388
 
389
        /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
390
           the signal handler. The frametype will be restored to its previous
391
           value in restore_sigcontext. */
392
        //        regs->frametype = CRIS_FRAME_NORMAL;
393
 
394
        /* then some other stuff */
395
 
396
        err |= __put_user(mask, &sc->oldmask);
397
 
398
        err |= __put_user(usp, &sc->usp);
399
 
400
        return err;
401
}
402
 
403
/* figure out where we want to put the new signal frame - usually on the stack */
404
 
405
static inline void * get_sigframe(struct k_sigaction *ka,
406
                                  struct pt_regs * regs, size_t frame_size)
407
{
408
        unsigned long sp = regs->sp;
409
 
410
        phx_signal("ka %p, regs %p, frame_size 0x%x (sp 0x%x)",
411
                   ka, regs, frame_size, sp);
412
 
413
        /* This is the X/Open sanctioned signal stack switching.  */
414
        if (ka->sa.sa_flags & SA_ONSTACK) {
415
                if (! on_sig_stack(sp))
416
                        sp = current->sas_ss_sp + current->sas_ss_size;
417
        }
418
 
419
        /* make sure the frame is dword-aligned */
420
 
421
        sp &= ~3;
422
 
423
        return (void *)(sp - frame_size);
424
}
425
 
426
/* grab and setup a signal frame.
427
 *
428
 * basically we stack a lot of state info, and arrange for the
429
 * user-mode program to return to the kernel using either a
430
 * trampoline which performs the syscall sigreturn, or a provided
431
 * user-mode trampoline.
432
 */
433
 
434
static void setup_frame(int sig, struct k_sigaction *ka,
435
                        sigset_t *set, struct pt_regs * regs)
436
{
437
        struct sigframe *frame;
438
        unsigned long return_ip;
439
        int err = 0;
440
 
441
        phx_signal("sig %d, ka %p, set %p, regs %p",
442
                   sig, ka, set, regs);
443
 
444
        frame = get_sigframe(ka, regs, sizeof(*frame));
445
 
446
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
447
                goto give_sigsegv;
448
 
449
        err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
450
        if (err)
451
                goto give_sigsegv;
452
 
453
        if (_NSIG_WORDS > 1) {
454
                err |= __copy_to_user(frame->extramask, &set->sig[1],
455
                                      sizeof(frame->extramask));
456
        }
457
        if (err)
458
                goto give_sigsegv;
459
 
460
        /* Set up to return from userspace.  If provided, use a stub
461
           already in userspace.  */
462
        if (ka->sa.sa_flags & SA_RESTORER) {
463
                return_ip = (unsigned long)ka->sa.sa_restorer;
464
                phx_signal("SA_RESTORER: return_ip 0x%x", return_ip);
465
        } else {
466
                /* trampoline - the desired return ip is the retcode itself */
467
                return_ip = (unsigned long)&frame->retcode;
468
                phx_signal("ktrampoline: return_ip 0x%x", return_ip);
469
                /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
470
                err |= __put_user(0xa960        , (short *)(frame->retcode+0));
471
                err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2));
472
                err |= __put_user(0x20000001, (unsigned long *)(frame->retcode+4));
473
                err |= __put_user(0x15000000, (unsigned long *)(frame->retcode+8));
474
        }
475
 
476
        if (err)
477
                goto give_sigsegv;
478
 
479
        /* Set up registers for signal handler */
480
 
481
        regs->pc = (unsigned long) ka->sa.sa_handler;       /* what we enter NOW   */
482
        regs->gprs[7] = return_ip;                          /* what we enter LATER */
483
        regs->gprs[1] = sig;                                /* first argument is signo */
484
 
485
        /* actually move the usp to reflect the stacked frame */
486
 
487
        //      wrusp((unsigned long)frame);
488
        regs->sp=(unsigned long) frame;
489
 
490
        return;
491
 
492
give_sigsegv:
493
        if (sig == SIGSEGV)
494
                ka->sa.sa_handler = SIG_DFL;
495
        force_sig(SIGSEGV, current);
496
}
497
 
498
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
499
                           sigset_t *set, struct pt_regs * regs)
500
{
501
        struct rt_sigframe *frame;
502
        unsigned long return_ip;
503
        int err = 0;
504
 
505
        phx_signal("sig %d, ka %p, info %p, set %p, regs %p",
506
                   sig, ka, info, set, regs);
507
 
508
        frame = get_sigframe(ka, regs, sizeof(*frame));
509
 
510
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
511
                goto give_sigsegv;
512
 
513
        err |= __put_user(&frame->info, &frame->pinfo);
514
        err |= __put_user(&frame->uc, &frame->puc);
515
        err |= copy_siginfo_to_user(&frame->info, info);
516
        if (err)
517
                goto give_sigsegv;
518
 
519
        /* Clear all the bits of the ucontext we don't use.  */
520
        err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
521
 
522
        err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
523
 
524
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
525
 
526
        if (err)
527
                goto give_sigsegv;
528
 
529
        if (ka->sa.sa_flags & SA_RESTORER) {
530
                return_ip = (unsigned long)ka->sa.sa_restorer;
531
                phx_signal("SA_RESTORER: return_ip 0x%x", return_ip);
532
        } else {
533
                /* trampoline - the desired return ip is the retcode itself */
534
                return_ip = (unsigned long)&frame->retcode;
535
                phx_signal("ktrampoline: return_ip 0x%x", return_ip);
536
                /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
537
                err |= __put_user(0xa960        , (short *)(frame->retcode+0));
538
                err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2));
539
                err |= __put_user(0x20000001, (unsigned long *)(frame->retcode+4));
540
                err |= __put_user(0x15000000, (unsigned long *)(frame->retcode+8));
541
        }
542
 
543
        if (err)
544
                goto give_sigsegv;
545
 
546
        /* TODO what is the current->exec_domain stuff and invmap ? */
547
 
548
        /* Set up registers for signal handler */
549
 
550
        regs->pc = (unsigned long) ka->sa.sa_handler;  /* what we enter NOW   */
551
        regs->gprs[7] = return_ip;                          /* what we enter LATER */
552
        regs->gprs[1] = sig;                                /* first argument is signo */
553
        regs->gprs[3] = (unsigned long) &frame->info;       /* second argument is (siginfo_t *) */
554
        regs->gprs[4] = 0;                                  /* third argument is unused */
555
 
556
        /* actually move the usp to reflect the stacked frame */
557
 
558
        //      wrusp((unsigned long)frame);
559
        regs->sp = (unsigned long)frame;
560
 
561
        return;
562
 
563
give_sigsegv:
564
        if (sig == SIGSEGV)
565
                ka->sa.sa_handler = SIG_DFL;
566
        force_sig(SIGSEGV, current);
567
}
568
 
569
/*
570
 * OK, we're invoking a handler
571
 */
572
 
573
static inline void handle_signal(int canrestart, unsigned long sig,
574
                                 struct k_sigaction *ka, siginfo_t *info,
575
                                 sigset_t *oldset, struct pt_regs * regs)
576
{
577
        phx_signal("canrestart %d, sig %d, ka %p, info %p, oldset %p, regs %p",
578
                   canrestart, sig, ka, info, oldset, regs);
579
 
580
        phx_signal("(regs->pc 0x%x, regs->sp 0x%x, regs->gprs[7] 0x%x)",
581
                   regs->pc, regs->sp, regs->gprs[7]);
582
 
583
        /* Are we from a system call? */
584
        if (canrestart) {
585
                /* If so, check system call restarting.. */
586
                switch (regs->gprs[1]) {
587
                        case -ERESTARTNOHAND:
588
                                /* ERESTARTNOHAND means that the syscall should only be
589
                                   restarted if there was no handler for the signal, and since
590
                                   we only get here if there is a handler, we dont restart */
591
                                regs->gprs[1] = -EINTR;
592
                                break;
593
 
594
                        case -ERESTARTSYS:
595
                                /* ERESTARTSYS means to restart the syscall if there is no
596
                                   handler or the handler was registered with SA_RESTART */
597
                                if (!(ka->sa.sa_flags & SA_RESTART)) {
598
                                        regs->gprs[1] = -EINTR;
599
                                        break;
600
                                }
601
                        /* fallthrough */
602
                        case -ERESTARTNOINTR:
603
                                /* ERESTARTNOINTR means that the syscall should be called again
604
                                   after the signal handler returns. */
605
                                RESTART_OR32_SYS(regs);
606
                }
607
        }
608
 
609
        /* Set up the stack frame */
610
        if (ka->sa.sa_flags & SA_SIGINFO)
611
                setup_rt_frame(sig, ka, info, oldset, regs);
612
        else
613
                setup_frame(sig, ka, oldset, regs);
614
 
615
        if (ka->sa.sa_flags & SA_ONESHOT)
616
                ka->sa.sa_handler = SIG_DFL;
617
 
618
        if (!(ka->sa.sa_flags & SA_NODEFER)) {
619
                spin_lock_irq(&current->sigmask_lock);
620
                sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
621
                sigaddset(&current->blocked,sig);
622
                recalc_sigpending(current);
623
                spin_unlock_irq(&current->sigmask_lock);
624
        }
625
}
626
 
627
/*
628
 * Note that 'init' is a special process: it doesn't get signals it doesn't
629
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
630
 * mistake.
631
 *
632
 * Also note that the regs structure given here as an argument, is the latest
633
 * pushed pt_regs. It may or may not be the same as the first pushed registers
634
 * when the initial usermode->kernelmode transition took place. Therefore
635
 * we can use user_mode(regs) to see if we came directly from kernel or user
636
 * mode below.
637
 */
638
 
639
int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
640
{
641
        siginfo_t info;
642
        struct k_sigaction *ka;
643
 
644
        check_stack(NULL, __FILE__, __FUNCTION__, __LINE__);
645
 
646
        phx_signal("canrestart %d, oldset %p, regs %p",
647
                   canrestart, oldset, regs);
648
 
649
        /*
650
         * We want the common case to go fast, which
651
         * is why we may in certain cases get here from
652
         * kernel mode. Just return without doing anything
653
         * if so.
654
         */
655
        if (!user_mode(regs))
656
                return 1;
657
 
658
        if (!oldset)
659
                oldset = &current->blocked;
660
 
661
        for (;;) {
662
                unsigned long signr;
663
 
664
                spin_lock_irq(&current->sigmask_lock);
665
                signr = dequeue_signal(&current->blocked, &info);
666
                spin_unlock_irq(&current->sigmask_lock);
667
 
668
                if (!signr)
669
                        break;
670
 
671
                if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
672
                        /* Let the debugger run.  */
673
                        current->exit_code = signr;
674
                        current->state = TASK_STOPPED;
675
                        notify_parent(current, SIGCHLD);
676
                        schedule();
677
 
678
                        /* We're back.  Did the debugger cancel the sig?  */
679
                        if (!(signr = current->exit_code))
680
                                continue;
681
                        current->exit_code = 0;
682
 
683
                        /* The debugger continued.  Ignore SIGSTOP.  */
684
                        if (signr == SIGSTOP)
685
                                continue;
686
 
687
                        /* Update the siginfo structure.  Is this good?  */
688
                        if (signr != info.si_signo) {
689
                                info.si_signo = signr;
690
                                info.si_errno = 0;
691
                                info.si_code = SI_USER;
692
                                info.si_pid = current->p_pptr->pid;
693
                                info.si_uid = current->p_pptr->uid;
694
                        }
695
 
696
                        /* If the (new) signal is now blocked, requeue it.  */
697
                        if (sigismember(&current->blocked, signr)) {
698
                                send_sig_info(signr, &info, current);
699
                                continue;
700
                        }
701
                }
702
 
703
                ka = &current->sig->action[signr-1];
704
                if (ka->sa.sa_handler == SIG_IGN) {
705
                        if (signr != SIGCHLD)
706
                                continue;
707
                        /* Check for SIGCHLD: it's special.  */
708
                        while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
709
                                /* nothing */;
710
                        continue;
711
                }
712
 
713
                if (ka->sa.sa_handler == SIG_DFL) {
714
                        int exit_code = signr;
715
 
716
                        /* Init gets no signals it doesn't want.  */
717
                        if (current->pid == 1)
718
                                continue;
719
 
720
                        switch (signr) {
721
                        case SIGCONT: case SIGCHLD: case SIGWINCH:
722
                                continue;
723
 
724
                        case SIGTSTP: case SIGTTIN: case SIGTTOU:
725
                                if (is_orphaned_pgrp(current->pgrp))
726
                                        continue;
727
                                /* FALLTHRU */
728
 
729
                        case SIGSTOP:
730
                                current->state = TASK_STOPPED;
731
                                current->exit_code = signr;
732
                                if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
733
                                        notify_parent(current, SIGCHLD);
734
                                schedule();
735
                                continue;
736
 
737
                        case SIGQUIT: case SIGILL: case SIGTRAP:
738
                        case SIGABRT: case SIGFPE: case SIGSEGV:
739
                        case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
740
                                if (do_coredump(signr, regs))
741
                                        exit_code |= 0x80;
742
                                /* FALLTHRU */
743
 
744
                        default:
745
                                lock_kernel();
746
                                sig_exit(signr, exit_code, &info);
747
                                /* NOTREACHED */
748
                        }
749
                }
750
 
751
                /* Whee!  Actually deliver the signal.  */
752
                handle_signal(canrestart, signr, ka, &info, oldset, regs);
753
                return 1;
754
        }
755
 
756
        /* Did we come from a system call? */
757
        if (canrestart) {
758
                /* Restart the system call - no handlers present */
759
                if (regs->gprs[1] == -ERESTARTNOHAND ||
760
                    regs->gprs[1] == -ERESTARTSYS ||
761
                    regs->gprs[1] == -ERESTARTNOINTR) {
762
                        RESTART_OR32_SYS(regs);
763
                }
764
        }
765
        return 0;
766
}

powered by: WebSVN 2.1.0

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