~ubuntu-branches/ubuntu/utopic/xen/utopic

« back to all changes in this revision

Viewing changes to xenolinux-2.4.25-sparse/arch/xeno/kernel/signal.c

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2010-05-06 15:47:38 UTC
  • mto: (1.3.1) (15.1.1 sid) (4.1.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20100506154738-agoz0rlafrh1fnq7
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  linux/arch/i386/kernel/signal.c
3
 
 *
4
 
 *  Copyright (C) 1991, 1992  Linus Torvalds
5
 
 *
6
 
 *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
7
 
 *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes
8
 
 */
9
 
 
10
 
#include <linux/sched.h>
11
 
#include <linux/mm.h>
12
 
#include <linux/smp.h>
13
 
#include <linux/smp_lock.h>
14
 
#include <linux/kernel.h>
15
 
#include <linux/signal.h>
16
 
#include <linux/errno.h>
17
 
#include <linux/wait.h>
18
 
#include <linux/ptrace.h>
19
 
#include <linux/unistd.h>
20
 
#include <linux/stddef.h>
21
 
#include <linux/tty.h>
22
 
#include <linux/personality.h>
23
 
#include <asm/ucontext.h>
24
 
#include <asm/uaccess.h>
25
 
#include <asm/i387.h>
26
 
 
27
 
#define DEBUG_SIG 0
28
 
 
29
 
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
30
 
 
31
 
int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
32
 
 
33
 
int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
34
 
{
35
 
        if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
36
 
                return -EFAULT;
37
 
        if (from->si_code < 0)
38
 
                return __copy_to_user(to, from, sizeof(siginfo_t));
39
 
        else {
40
 
                int err;
41
 
 
42
 
                /* If you change siginfo_t structure, please be sure
43
 
                   this code is fixed accordingly.
44
 
                   It should never copy any pad contained in the structure
45
 
                   to avoid security leaks, but must copy the generic
46
 
                   3 ints plus the relevant union member.  */
47
 
                err = __put_user(from->si_signo, &to->si_signo);
48
 
                err |= __put_user(from->si_errno, &to->si_errno);
49
 
                err |= __put_user((short)from->si_code, &to->si_code);
50
 
                /* First 32bits of unions are always present.  */
51
 
                err |= __put_user(from->si_pid, &to->si_pid);
52
 
                switch (from->si_code >> 16) {
53
 
                case __SI_FAULT >> 16:
54
 
                        break;
55
 
                case __SI_CHLD >> 16:
56
 
                        err |= __put_user(from->si_utime, &to->si_utime);
57
 
                        err |= __put_user(from->si_stime, &to->si_stime);
58
 
                        err |= __put_user(from->si_status, &to->si_status);
59
 
                default:
60
 
                        err |= __put_user(from->si_uid, &to->si_uid);
61
 
                        break;
62
 
                /* case __SI_RT: This is not generated by the kernel as of now.  */
63
 
                }
64
 
                return err;
65
 
        }
66
 
}
67
 
 
68
 
/*
69
 
 * Atomically swap in the new signal mask, and wait for a signal.
70
 
 */
71
 
asmlinkage int
72
 
sys_sigsuspend(int history0, int history1, old_sigset_t mask)
73
 
{
74
 
        struct pt_regs * regs = (struct pt_regs *) &history0;
75
 
        sigset_t saveset;
76
 
 
77
 
        mask &= _BLOCKABLE;
78
 
        spin_lock_irq(&current->sigmask_lock);
79
 
        saveset = current->blocked;
80
 
        siginitset(&current->blocked, mask);
81
 
        recalc_sigpending(current);
82
 
        spin_unlock_irq(&current->sigmask_lock);
83
 
 
84
 
        regs->eax = -EINTR;
85
 
        while (1) {
86
 
                current->state = TASK_INTERRUPTIBLE;
87
 
                schedule();
88
 
                if (do_signal(regs, &saveset))
89
 
                        return -EINTR;
90
 
        }
91
 
}
92
 
 
93
 
asmlinkage int
94
 
sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
95
 
{
96
 
        struct pt_regs * regs = (struct pt_regs *) &unewset;
97
 
        sigset_t saveset, newset;
98
 
 
99
 
        /* XXX: Don't preclude handling different sized sigset_t's.  */
100
 
        if (sigsetsize != sizeof(sigset_t))
101
 
                return -EINVAL;
102
 
 
103
 
        if (copy_from_user(&newset, unewset, sizeof(newset)))
104
 
                return -EFAULT;
105
 
        sigdelsetmask(&newset, ~_BLOCKABLE);
106
 
 
107
 
        spin_lock_irq(&current->sigmask_lock);
108
 
        saveset = current->blocked;
109
 
        current->blocked = newset;
110
 
        recalc_sigpending(current);
111
 
        spin_unlock_irq(&current->sigmask_lock);
112
 
 
113
 
        regs->eax = -EINTR;
114
 
        while (1) {
115
 
                current->state = TASK_INTERRUPTIBLE;
116
 
                schedule();
117
 
                if (do_signal(regs, &saveset))
118
 
                        return -EINTR;
119
 
        }
120
 
}
121
 
 
122
 
asmlinkage int 
123
 
sys_sigaction(int sig, const struct old_sigaction *act,
124
 
              struct old_sigaction *oact)
125
 
{
126
 
        struct k_sigaction new_ka, old_ka;
127
 
        int ret;
128
 
 
129
 
        if (act) {
130
 
                old_sigset_t mask;
131
 
                if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
132
 
                    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
133
 
                    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
134
 
                        return -EFAULT;
135
 
                __get_user(new_ka.sa.sa_flags, &act->sa_flags);
136
 
                __get_user(mask, &act->sa_mask);
137
 
                siginitset(&new_ka.sa.sa_mask, mask);
138
 
        }
139
 
 
140
 
        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
141
 
 
142
 
        if (!ret && oact) {
143
 
                if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
144
 
                    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
145
 
                    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
146
 
                        return -EFAULT;
147
 
                __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
148
 
                __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
149
 
        }
150
 
 
151
 
        return ret;
152
 
}
153
 
 
154
 
asmlinkage int
155
 
sys_sigaltstack(const stack_t *uss, stack_t *uoss)
156
 
{
157
 
        struct pt_regs *regs = (struct pt_regs *) &uss;
158
 
        return do_sigaltstack(uss, uoss, regs->esp);
159
 
}
160
 
 
161
 
 
162
 
/*
163
 
 * Do a signal return; undo the signal stack.
164
 
 */
165
 
 
166
 
struct sigframe
167
 
{
168
 
        char *pretcode;
169
 
        int sig;
170
 
        struct sigcontext sc;
171
 
        struct _fpstate fpstate;
172
 
        unsigned long extramask[_NSIG_WORDS-1];
173
 
        char retcode[8];
174
 
};
175
 
 
176
 
struct rt_sigframe
177
 
{
178
 
        char *pretcode;
179
 
        int sig;
180
 
        struct siginfo *pinfo;
181
 
        void *puc;
182
 
        struct siginfo info;
183
 
        struct ucontext uc;
184
 
        struct _fpstate fpstate;
185
 
        char retcode[8];
186
 
};
187
 
 
188
 
static int
189
 
restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *peax)
190
 
{
191
 
        unsigned int err = 0;
192
 
 
193
 
#define COPY(x)         err |= __get_user(regs->x, &sc->x)
194
 
 
195
 
#define COPY_SEG(seg)                                                   \
196
 
        { unsigned short tmp;                                           \
197
 
          err |= __get_user(tmp, &sc->seg);                             \
198
 
          regs->x##seg = tmp; }
199
 
 
200
 
#define COPY_SEG_STRICT(seg)                                            \
201
 
        { unsigned short tmp;                                           \
202
 
          err |= __get_user(tmp, &sc->seg);                             \
203
 
          regs->x##seg = tmp|3; }
204
 
 
205
 
#define GET_SEG(seg)                                                    \
206
 
        { unsigned short tmp;                                           \
207
 
          err |= __get_user(tmp, &sc->seg);                             \
208
 
          loadsegment(seg,tmp); }
209
 
 
210
 
        GET_SEG(gs);
211
 
        GET_SEG(fs);
212
 
        COPY_SEG(es);
213
 
        COPY_SEG(ds);
214
 
        COPY(edi);
215
 
        COPY(esi);
216
 
        COPY(ebp);
217
 
        COPY(esp);
218
 
        COPY(ebx);
219
 
        COPY(edx);
220
 
        COPY(ecx);
221
 
        COPY(eip);
222
 
        COPY_SEG_STRICT(cs);
223
 
        COPY_SEG_STRICT(ss);
224
 
        
225
 
        {
226
 
                unsigned int tmpflags;
227
 
                err |= __get_user(tmpflags, &sc->eflags);
228
 
                regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
229
 
                regs->orig_eax = -1;            /* disable syscall checks */
230
 
        }
231
 
 
232
 
        {
233
 
                struct _fpstate * buf;
234
 
                err |= __get_user(buf, &sc->fpstate);
235
 
                if (buf) {
236
 
                        if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
237
 
                                goto badframe;
238
 
                        err |= restore_i387(buf);
239
 
                }
240
 
        }
241
 
 
242
 
        err |= __get_user(*peax, &sc->eax);
243
 
        return err;
244
 
 
245
 
badframe:
246
 
        return 1;
247
 
}
248
 
 
249
 
asmlinkage int sys_sigreturn(unsigned long __unused)
250
 
{
251
 
        struct pt_regs *regs = (struct pt_regs *) &__unused;
252
 
        struct sigframe *frame = (struct sigframe *)(regs->esp - 8);
253
 
        sigset_t set;
254
 
        int eax;
255
 
 
256
 
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
257
 
                goto badframe;
258
 
        if (__get_user(set.sig[0], &frame->sc.oldmask)
259
 
            || (_NSIG_WORDS > 1
260
 
                && __copy_from_user(&set.sig[1], &frame->extramask,
261
 
                                    sizeof(frame->extramask))))
262
 
                goto badframe;
263
 
 
264
 
        sigdelsetmask(&set, ~_BLOCKABLE);
265
 
        spin_lock_irq(&current->sigmask_lock);
266
 
        current->blocked = set;
267
 
        recalc_sigpending(current);
268
 
        spin_unlock_irq(&current->sigmask_lock);
269
 
        
270
 
        if (restore_sigcontext(regs, &frame->sc, &eax))
271
 
                goto badframe;
272
 
        return eax;
273
 
 
274
 
badframe:
275
 
        force_sig(SIGSEGV, current);
276
 
        return 0;
277
 
}       
278
 
 
279
 
asmlinkage int sys_rt_sigreturn(unsigned long __unused)
280
 
{
281
 
        struct pt_regs *regs = (struct pt_regs *) &__unused;
282
 
        struct rt_sigframe *frame = (struct rt_sigframe *)(regs->esp - 4);
283
 
        sigset_t set;
284
 
        stack_t st;
285
 
        int eax;
286
 
 
287
 
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
288
 
                goto badframe;
289
 
        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
290
 
                goto badframe;
291
 
 
292
 
        sigdelsetmask(&set, ~_BLOCKABLE);
293
 
        spin_lock_irq(&current->sigmask_lock);
294
 
        current->blocked = set;
295
 
        recalc_sigpending(current);
296
 
        spin_unlock_irq(&current->sigmask_lock);
297
 
        
298
 
        if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax))
299
 
                goto badframe;
300
 
 
301
 
        if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
302
 
                goto badframe;
303
 
        /* It is more difficult to avoid calling this function than to
304
 
           call it and ignore errors.  */
305
 
        do_sigaltstack(&st, NULL, regs->esp);
306
 
 
307
 
        return eax;
308
 
 
309
 
badframe:
310
 
        force_sig(SIGSEGV, current);
311
 
        return 0;
312
 
}       
313
 
 
314
 
/*
315
 
 * Set up a signal frame.
316
 
 */
317
 
 
318
 
static int
319
 
setup_sigcontext(struct sigcontext *sc, struct _fpstate *fpstate,
320
 
                 struct pt_regs *regs, unsigned long mask)
321
 
{
322
 
        int tmp, err = 0;
323
 
 
324
 
        tmp = 0;
325
 
        __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
326
 
        err |= __put_user(tmp, (unsigned int *)&sc->gs);
327
 
        __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
328
 
        err |= __put_user(tmp, (unsigned int *)&sc->fs);
329
 
 
330
 
        err |= __put_user(regs->xes, (unsigned int *)&sc->es);
331
 
        err |= __put_user(regs->xds, (unsigned int *)&sc->ds);
332
 
        err |= __put_user(regs->edi, &sc->edi);
333
 
        err |= __put_user(regs->esi, &sc->esi);
334
 
        err |= __put_user(regs->ebp, &sc->ebp);
335
 
        err |= __put_user(regs->esp, &sc->esp);
336
 
        err |= __put_user(regs->ebx, &sc->ebx);
337
 
        err |= __put_user(regs->edx, &sc->edx);
338
 
        err |= __put_user(regs->ecx, &sc->ecx);
339
 
        err |= __put_user(regs->eax, &sc->eax);
340
 
        err |= __put_user(current->thread.trap_no, &sc->trapno);
341
 
        err |= __put_user(current->thread.error_code, &sc->err);
342
 
        err |= __put_user(regs->eip, &sc->eip);
343
 
        err |= __put_user(regs->xcs, (unsigned int *)&sc->cs);
344
 
        err |= __put_user(regs->eflags, &sc->eflags);
345
 
        err |= __put_user(regs->esp, &sc->esp_at_signal);
346
 
        err |= __put_user(regs->xss, (unsigned int *)&sc->ss);
347
 
 
348
 
        tmp = save_i387(fpstate);
349
 
        if (tmp < 0)
350
 
          err = 1;
351
 
        else
352
 
          err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
353
 
 
354
 
        /* non-iBCS2 extensions.. */
355
 
        err |= __put_user(mask, &sc->oldmask);
356
 
        err |= __put_user(current->thread.cr2, &sc->cr2);
357
 
 
358
 
        return err;
359
 
}
360
 
 
361
 
/*
362
 
 * Determine which stack to use..
363
 
 */
364
 
static inline void *
365
 
get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
366
 
{
367
 
        unsigned long esp;
368
 
 
369
 
        /* Default to using normal stack */
370
 
        esp = regs->esp;
371
 
 
372
 
        /* This is the X/Open sanctioned signal stack switching.  */
373
 
        if (ka->sa.sa_flags & SA_ONSTACK) {
374
 
                if (sas_ss_flags(esp) == 0)
375
 
                        esp = current->sas_ss_sp + current->sas_ss_size;
376
 
        }
377
 
 
378
 
        /* This is the legacy signal stack switching. */
379
 
        else if ((regs->xss & 0xffff) != __USER_DS &&
380
 
                 !(ka->sa.sa_flags & SA_RESTORER) &&
381
 
                 ka->sa.sa_restorer) {
382
 
                esp = (unsigned long) ka->sa.sa_restorer;
383
 
        }
384
 
 
385
 
        return (void *)((esp - frame_size) & -8ul);
386
 
}
387
 
 
388
 
static void setup_frame(int sig, struct k_sigaction *ka,
389
 
                        sigset_t *set, struct pt_regs * regs)
390
 
{
391
 
        struct sigframe *frame;
392
 
        int err = 0;
393
 
 
394
 
        frame = get_sigframe(ka, regs, sizeof(*frame));
395
 
 
396
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
397
 
                goto give_sigsegv;
398
 
 
399
 
        err |= __put_user((current->exec_domain
400
 
                           && current->exec_domain->signal_invmap
401
 
                           && sig < 32
402
 
                           ? current->exec_domain->signal_invmap[sig]
403
 
                           : sig),
404
 
                          &frame->sig);
405
 
        if (err)
406
 
                goto give_sigsegv;
407
 
 
408
 
        err |= setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
409
 
        if (err)
410
 
                goto give_sigsegv;
411
 
 
412
 
        if (_NSIG_WORDS > 1) {
413
 
                err |= __copy_to_user(frame->extramask, &set->sig[1],
414
 
                                      sizeof(frame->extramask));
415
 
        }
416
 
        if (err)
417
 
                goto give_sigsegv;
418
 
 
419
 
        /* Set up to return from userspace.  If provided, use a stub
420
 
           already in userspace.  */
421
 
        if (ka->sa.sa_flags & SA_RESTORER) {
422
 
                err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
423
 
        } else {
424
 
                err |= __put_user(frame->retcode, &frame->pretcode);
425
 
                /* This is popl %eax ; movl $,%eax ; int $0x80 */
426
 
                err |= __put_user(0xb858, (short *)(frame->retcode+0));
427
 
                err |= __put_user(__NR_sigreturn, (int *)(frame->retcode+2));
428
 
                err |= __put_user(0x80cd, (short *)(frame->retcode+6));
429
 
        }
430
 
 
431
 
        if (err)
432
 
                goto give_sigsegv;
433
 
 
434
 
        /* Set up registers for signal handler */
435
 
        regs->esp = (unsigned long) frame;
436
 
        regs->eip = (unsigned long) ka->sa.sa_handler;
437
 
 
438
 
        set_fs(USER_DS);
439
 
        regs->xds = __USER_DS;
440
 
        regs->xes = __USER_DS;
441
 
        regs->xss = __USER_DS;
442
 
        regs->xcs = __USER_CS;
443
 
        regs->eflags &= ~TF_MASK;
444
 
 
445
 
#if DEBUG_SIG
446
 
        printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
447
 
                current->comm, current->pid, frame, regs->eip, frame->pretcode);
448
 
#endif
449
 
 
450
 
        return;
451
 
 
452
 
give_sigsegv:
453
 
        if (sig == SIGSEGV)
454
 
                ka->sa.sa_handler = SIG_DFL;
455
 
        force_sig(SIGSEGV, current);
456
 
}
457
 
 
458
 
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
459
 
                           sigset_t *set, struct pt_regs * regs)
460
 
{
461
 
        struct rt_sigframe *frame;
462
 
        int err = 0;
463
 
 
464
 
        frame = get_sigframe(ka, regs, sizeof(*frame));
465
 
 
466
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
467
 
                goto give_sigsegv;
468
 
 
469
 
        err |= __put_user((current->exec_domain
470
 
                           && current->exec_domain->signal_invmap
471
 
                           && sig < 32
472
 
                           ? current->exec_domain->signal_invmap[sig]
473
 
                           : sig),
474
 
                          &frame->sig);
475
 
        err |= __put_user(&frame->info, &frame->pinfo);
476
 
        err |= __put_user(&frame->uc, &frame->puc);
477
 
        err |= copy_siginfo_to_user(&frame->info, info);
478
 
        if (err)
479
 
                goto give_sigsegv;
480
 
 
481
 
        /* Create the ucontext.  */
482
 
        err |= __put_user(0, &frame->uc.uc_flags);
483
 
        err |= __put_user(0, &frame->uc.uc_link);
484
 
        err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
485
 
        err |= __put_user(sas_ss_flags(regs->esp),
486
 
                          &frame->uc.uc_stack.ss_flags);
487
 
        err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
488
 
        err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
489
 
                                regs, set->sig[0]);
490
 
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
491
 
        if (err)
492
 
                goto give_sigsegv;
493
 
 
494
 
        /* Set up to return from userspace.  If provided, use a stub
495
 
           already in userspace.  */
496
 
        if (ka->sa.sa_flags & SA_RESTORER) {
497
 
                err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
498
 
        } else {
499
 
                err |= __put_user(frame->retcode, &frame->pretcode);
500
 
                /* This is movl $,%eax ; int $0x80 */
501
 
                err |= __put_user(0xb8, (char *)(frame->retcode+0));
502
 
                err |= __put_user(__NR_rt_sigreturn, (int *)(frame->retcode+1));
503
 
                err |= __put_user(0x80cd, (short *)(frame->retcode+5));
504
 
        }
505
 
 
506
 
        if (err)
507
 
                goto give_sigsegv;
508
 
 
509
 
        /* Set up registers for signal handler */
510
 
        regs->esp = (unsigned long) frame;
511
 
        regs->eip = (unsigned long) ka->sa.sa_handler;
512
 
 
513
 
        set_fs(USER_DS);
514
 
        regs->xds = __USER_DS;
515
 
        regs->xes = __USER_DS;
516
 
        regs->xss = __USER_DS;
517
 
        regs->xcs = __USER_CS;
518
 
        regs->eflags &= ~TF_MASK;
519
 
 
520
 
#if DEBUG_SIG
521
 
        printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
522
 
                current->comm, current->pid, frame, regs->eip, frame->pretcode);
523
 
#endif
524
 
 
525
 
        return;
526
 
 
527
 
give_sigsegv:
528
 
        if (sig == SIGSEGV)
529
 
                ka->sa.sa_handler = SIG_DFL;
530
 
        force_sig(SIGSEGV, current);
531
 
}
532
 
 
533
 
/*
534
 
 * OK, we're invoking a handler
535
 
 */     
536
 
 
537
 
static void
538
 
handle_signal(unsigned long sig, struct k_sigaction *ka,
539
 
              siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
540
 
{
541
 
        /* Are we from a system call? */
542
 
        if (regs->orig_eax >= 0) {
543
 
                /* If so, check system call restarting.. */
544
 
                switch (regs->eax) {
545
 
                        case -ERESTARTNOHAND:
546
 
                                regs->eax = -EINTR;
547
 
                                break;
548
 
 
549
 
                        case -ERESTARTSYS:
550
 
                                if (!(ka->sa.sa_flags & SA_RESTART)) {
551
 
                                        regs->eax = -EINTR;
552
 
                                        break;
553
 
                                }
554
 
                        /* fallthrough */
555
 
                        case -ERESTARTNOINTR:
556
 
                                regs->eax = regs->orig_eax;
557
 
                                regs->eip -= 2;
558
 
                }
559
 
        }
560
 
 
561
 
        /* Set up the stack frame */
562
 
        if (ka->sa.sa_flags & SA_SIGINFO)
563
 
                setup_rt_frame(sig, ka, info, oldset, regs);
564
 
        else
565
 
                setup_frame(sig, ka, oldset, regs);
566
 
 
567
 
        if (ka->sa.sa_flags & SA_ONESHOT)
568
 
                ka->sa.sa_handler = SIG_DFL;
569
 
 
570
 
        if (!(ka->sa.sa_flags & SA_NODEFER)) {
571
 
                spin_lock_irq(&current->sigmask_lock);
572
 
                sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
573
 
                sigaddset(&current->blocked,sig);
574
 
                recalc_sigpending(current);
575
 
                spin_unlock_irq(&current->sigmask_lock);
576
 
        }
577
 
}
578
 
 
579
 
/*
580
 
 * Note that 'init' is a special process: it doesn't get signals it doesn't
581
 
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
582
 
 * mistake.
583
 
 */
584
 
int do_signal(struct pt_regs *regs, sigset_t *oldset)
585
 
{
586
 
        siginfo_t info;
587
 
        struct k_sigaction *ka;
588
 
 
589
 
        /*
590
 
         * We want the common case to go fast, which
591
 
         * is why we may in certain cases get here from
592
 
         * kernel mode. Just return without doing anything
593
 
         * if so.
594
 
         */
595
 
        if ((regs->xcs & 2) != 2)
596
 
                return 1;
597
 
 
598
 
        if (!oldset)
599
 
                oldset = &current->blocked;
600
 
 
601
 
        for (;;) {
602
 
                unsigned long signr;
603
 
 
604
 
                spin_lock_irq(&current->sigmask_lock);
605
 
                signr = dequeue_signal(&current->blocked, &info);
606
 
                spin_unlock_irq(&current->sigmask_lock);
607
 
 
608
 
                if (!signr)
609
 
                        break;
610
 
 
611
 
                if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
612
 
                        /* Let the debugger run.  */
613
 
                        current->exit_code = signr;
614
 
                        current->state = TASK_STOPPED;
615
 
                        notify_parent(current, SIGCHLD);
616
 
                        schedule();
617
 
 
618
 
                        /* We're back.  Did the debugger cancel the sig?  */
619
 
                        if (!(signr = current->exit_code))
620
 
                                continue;
621
 
                        current->exit_code = 0;
622
 
 
623
 
                        /* The debugger continued.  Ignore SIGSTOP.  */
624
 
                        if (signr == SIGSTOP)
625
 
                                continue;
626
 
 
627
 
                        /* Update the siginfo structure.  Is this good?  */
628
 
                        if (signr != info.si_signo) {
629
 
                                info.si_signo = signr;
630
 
                                info.si_errno = 0;
631
 
                                info.si_code = SI_USER;
632
 
                                info.si_pid = current->p_pptr->pid;
633
 
                                info.si_uid = current->p_pptr->uid;
634
 
                        }
635
 
 
636
 
                        /* If the (new) signal is now blocked, requeue it.  */
637
 
                        if (sigismember(&current->blocked, signr)) {
638
 
                                send_sig_info(signr, &info, current);
639
 
                                continue;
640
 
                        }
641
 
                }
642
 
 
643
 
                ka = &current->sig->action[signr-1];
644
 
                if (ka->sa.sa_handler == SIG_IGN) {
645
 
                        if (signr != SIGCHLD)
646
 
                                continue;
647
 
                        /* Check for SIGCHLD: it's special.  */
648
 
                        while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
649
 
                                /* nothing */;
650
 
                        continue;
651
 
                }
652
 
 
653
 
                if (ka->sa.sa_handler == SIG_DFL) {
654
 
                        int exit_code = signr;
655
 
 
656
 
                        /* Init gets no signals it doesn't want.  */
657
 
                        if (current->pid == 1)
658
 
                                continue;
659
 
 
660
 
                        switch (signr) {
661
 
                        case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
662
 
                                continue;
663
 
 
664
 
                        case SIGTSTP: case SIGTTIN: case SIGTTOU:
665
 
                                if (is_orphaned_pgrp(current->pgrp))
666
 
                                        continue;
667
 
                                /* FALLTHRU */
668
 
 
669
 
                        case SIGSTOP: {
670
 
                                struct signal_struct *sig;
671
 
                                current->state = TASK_STOPPED;
672
 
                                current->exit_code = signr;
673
 
                                sig = current->p_pptr->sig;
674
 
                                if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
675
 
                                        notify_parent(current, SIGCHLD);
676
 
                                schedule();
677
 
                                continue;
678
 
                        }
679
 
 
680
 
                        case SIGQUIT: case SIGILL: case SIGTRAP:
681
 
                        case SIGABRT: case SIGFPE: case SIGSEGV:
682
 
                        case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
683
 
                                if (do_coredump(signr, regs))
684
 
                                        exit_code |= 0x80;
685
 
                                /* FALLTHRU */
686
 
 
687
 
                        default:
688
 
                                sig_exit(signr, exit_code, &info);
689
 
                                /* NOTREACHED */
690
 
                        }
691
 
                }
692
 
 
693
 
                /* Reenable any watchpoints before delivering the
694
 
                 * signal to user space. The processor register will
695
 
                 * have been cleared if the watchpoint triggered
696
 
                 * inside the kernel.
697
 
                 */
698
 
                if ( current->thread.debugreg[7] != 0 )
699
 
                    HYPERVISOR_set_debugreg(7, current->thread.debugreg[7]);
700
 
 
701
 
                /* Whee!  Actually deliver the signal.  */
702
 
                handle_signal(signr, ka, &info, oldset, regs);
703
 
                return 1;
704
 
        }
705
 
 
706
 
        /* Did we come from a system call? */
707
 
        if (regs->orig_eax >= 0) {
708
 
                /* Restart the system call - no handlers present */
709
 
                if (regs->eax == -ERESTARTNOHAND ||
710
 
                    regs->eax == -ERESTARTSYS ||
711
 
                    regs->eax == -ERESTARTNOINTR) {
712
 
                        regs->eax = regs->orig_eax;
713
 
                        regs->eip -= 2;
714
 
                }
715
 
        }
716
 
        return 0;
717
 
}