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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [arch/] [s390/] [kernel/] [compat_signal.c] - Blame information for rev 63

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 63 marcus.erl
/*
2
 *  arch/s390/kernel/compat_signal.c
3
 *
4
 *    Copyright (C) IBM Corp. 2000,2006
5
 *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
6
 *               Gerhard Tonn (ton@de.ibm.com)
7
 *
8
 *  Copyright (C) 1991, 1992  Linus Torvalds
9
 *
10
 *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
11
 */
12
 
13
#include <linux/compat.h>
14
#include <linux/sched.h>
15
#include <linux/mm.h>
16
#include <linux/smp.h>
17
#include <linux/kernel.h>
18
#include <linux/signal.h>
19
#include <linux/errno.h>
20
#include <linux/wait.h>
21
#include <linux/ptrace.h>
22
#include <linux/unistd.h>
23
#include <linux/stddef.h>
24
#include <linux/tty.h>
25
#include <linux/personality.h>
26
#include <linux/binfmts.h>
27
#include <asm/ucontext.h>
28
#include <asm/uaccess.h>
29
#include <asm/lowcore.h>
30
#include "compat_linux.h"
31
#include "compat_ptrace.h"
32
 
33
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
34
 
35
typedef struct
36
{
37
        __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
38
        struct sigcontext32 sc;
39
        _sigregs32 sregs;
40
        int signo;
41
        __u8 retcode[S390_SYSCALL_SIZE];
42
} sigframe32;
43
 
44
typedef struct
45
{
46
        __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
47
        __u8 retcode[S390_SYSCALL_SIZE];
48
        compat_siginfo_t info;
49
        struct ucontext32 uc;
50
} rt_sigframe32;
51
 
52
int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
53
{
54
        int err;
55
 
56
        if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
57
                return -EFAULT;
58
 
59
        /* If you change siginfo_t structure, please be sure
60
           this code is fixed accordingly.
61
           It should never copy any pad contained in the structure
62
           to avoid security leaks, but must copy the generic
63
           3 ints plus the relevant union member.
64
           This routine must convert siginfo from 64bit to 32bit as well
65
           at the same time.  */
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
        if (from->si_code < 0)
70
                err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
71
        else {
72
                switch (from->si_code >> 16) {
73
                case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
74
                case __SI_MESGQ >> 16:
75
                        err |= __put_user(from->si_int, &to->si_int);
76
                        /* fallthrough */
77
                case __SI_KILL >> 16:
78
                        err |= __put_user(from->si_pid, &to->si_pid);
79
                        err |= __put_user(from->si_uid, &to->si_uid);
80
                        break;
81
                case __SI_CHLD >> 16:
82
                        err |= __put_user(from->si_pid, &to->si_pid);
83
                        err |= __put_user(from->si_uid, &to->si_uid);
84
                        err |= __put_user(from->si_utime, &to->si_utime);
85
                        err |= __put_user(from->si_stime, &to->si_stime);
86
                        err |= __put_user(from->si_status, &to->si_status);
87
                        break;
88
                case __SI_FAULT >> 16:
89
                        err |= __put_user((unsigned long) from->si_addr,
90
                                          &to->si_addr);
91
                        break;
92
                case __SI_POLL >> 16:
93
                        err |= __put_user(from->si_band, &to->si_band);
94
                        err |= __put_user(from->si_fd, &to->si_fd);
95
                        break;
96
                case __SI_TIMER >> 16:
97
                        err |= __put_user(from->si_tid, &to->si_tid);
98
                        err |= __put_user(from->si_overrun, &to->si_overrun);
99
                        err |= __put_user(from->si_int, &to->si_int);
100
                        break;
101
                default:
102
                        break;
103
                }
104
        }
105
        return err;
106
}
107
 
108
int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
109
{
110
        int err;
111
        u32 tmp;
112
 
113
        if (!access_ok (VERIFY_READ, from, sizeof(compat_siginfo_t)))
114
                return -EFAULT;
115
 
116
        err = __get_user(to->si_signo, &from->si_signo);
117
        err |= __get_user(to->si_errno, &from->si_errno);
118
        err |= __get_user(to->si_code, &from->si_code);
119
 
120
        if (to->si_code < 0)
121
                err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
122
        else {
123
                switch (to->si_code >> 16) {
124
                case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
125
                case __SI_MESGQ >> 16:
126
                        err |= __get_user(to->si_int, &from->si_int);
127
                        /* fallthrough */
128
                case __SI_KILL >> 16:
129
                        err |= __get_user(to->si_pid, &from->si_pid);
130
                        err |= __get_user(to->si_uid, &from->si_uid);
131
                        break;
132
                case __SI_CHLD >> 16:
133
                        err |= __get_user(to->si_pid, &from->si_pid);
134
                        err |= __get_user(to->si_uid, &from->si_uid);
135
                        err |= __get_user(to->si_utime, &from->si_utime);
136
                        err |= __get_user(to->si_stime, &from->si_stime);
137
                        err |= __get_user(to->si_status, &from->si_status);
138
                        break;
139
                case __SI_FAULT >> 16:
140
                        err |= __get_user(tmp, &from->si_addr);
141
                        to->si_addr = (void __user *)(u64) (tmp & PSW32_ADDR_INSN);
142
                        break;
143
                case __SI_POLL >> 16:
144
                        err |= __get_user(to->si_band, &from->si_band);
145
                        err |= __get_user(to->si_fd, &from->si_fd);
146
                        break;
147
                case __SI_TIMER >> 16:
148
                        err |= __get_user(to->si_tid, &from->si_tid);
149
                        err |= __get_user(to->si_overrun, &from->si_overrun);
150
                        err |= __get_user(to->si_int, &from->si_int);
151
                        break;
152
                default:
153
                        break;
154
                }
155
        }
156
        return err;
157
}
158
 
159
asmlinkage long
160
sys32_sigaction(int sig, const struct old_sigaction32 __user *act,
161
                 struct old_sigaction32 __user *oact)
162
{
163
        struct k_sigaction new_ka, old_ka;
164
        unsigned long sa_handler, sa_restorer;
165
        int ret;
166
 
167
        if (act) {
168
                compat_old_sigset_t mask;
169
                if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
170
                    __get_user(sa_handler, &act->sa_handler) ||
171
                    __get_user(sa_restorer, &act->sa_restorer) ||
172
                    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
173
                    __get_user(mask, &act->sa_mask))
174
                        return -EFAULT;
175
                new_ka.sa.sa_handler = (__sighandler_t) sa_handler;
176
                new_ka.sa.sa_restorer = (void (*)(void)) sa_restorer;
177
                siginitset(&new_ka.sa.sa_mask, mask);
178
        }
179
 
180
        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
181
 
182
        if (!ret && oact) {
183
                sa_handler = (unsigned long) old_ka.sa.sa_handler;
184
                sa_restorer = (unsigned long) old_ka.sa.sa_restorer;
185
                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
186
                    __put_user(sa_handler, &oact->sa_handler) ||
187
                    __put_user(sa_restorer, &oact->sa_restorer) ||
188
                    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
189
                    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
190
                        return -EFAULT;
191
        }
192
 
193
        return ret;
194
}
195
 
196
asmlinkage long
197
sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
198
           struct sigaction32 __user *oact,  size_t sigsetsize)
199
{
200
        struct k_sigaction new_ka, old_ka;
201
        unsigned long sa_handler;
202
        int ret;
203
        compat_sigset_t set32;
204
 
205
        /* XXX: Don't preclude handling different sized sigset_t's.  */
206
        if (sigsetsize != sizeof(compat_sigset_t))
207
                return -EINVAL;
208
 
209
        if (act) {
210
                ret = get_user(sa_handler, &act->sa_handler);
211
                ret |= __copy_from_user(&set32, &act->sa_mask,
212
                                        sizeof(compat_sigset_t));
213
                switch (_NSIG_WORDS) {
214
                case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
215
                                | (((long)set32.sig[7]) << 32);
216
                case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4]
217
                                | (((long)set32.sig[5]) << 32);
218
                case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2]
219
                                | (((long)set32.sig[3]) << 32);
220
                case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0]
221
                                | (((long)set32.sig[1]) << 32);
222
                }
223
                ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
224
 
225
                if (ret)
226
                        return -EFAULT;
227
                new_ka.sa.sa_handler = (__sighandler_t) sa_handler;
228
        }
229
 
230
        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
231
 
232
        if (!ret && oact) {
233
                switch (_NSIG_WORDS) {
234
                case 4:
235
                        set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32);
236
                        set32.sig[6] = old_ka.sa.sa_mask.sig[3];
237
                case 3:
238
                        set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32);
239
                        set32.sig[4] = old_ka.sa.sa_mask.sig[2];
240
                case 2:
241
                        set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32);
242
                        set32.sig[2] = old_ka.sa.sa_mask.sig[1];
243
                case 1:
244
                        set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32);
245
                        set32.sig[0] = old_ka.sa.sa_mask.sig[0];
246
                }
247
                ret = put_user((unsigned long)old_ka.sa.sa_handler, &oact->sa_handler);
248
                ret |= __copy_to_user(&oact->sa_mask, &set32,
249
                                      sizeof(compat_sigset_t));
250
                ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
251
        }
252
 
253
        return ret;
254
}
255
 
256
asmlinkage long
257
sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss)
258
{
259
        struct pt_regs *regs = task_pt_regs(current);
260
        stack_t kss, koss;
261
        unsigned long ss_sp;
262
        int ret, err = 0;
263
        mm_segment_t old_fs = get_fs();
264
 
265
        if (uss) {
266
                if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
267
                        return -EFAULT;
268
                err |= __get_user(ss_sp, &uss->ss_sp);
269
                err |= __get_user(kss.ss_size, &uss->ss_size);
270
                err |= __get_user(kss.ss_flags, &uss->ss_flags);
271
                if (err)
272
                        return -EFAULT;
273
                kss.ss_sp = (void __user *) ss_sp;
274
        }
275
 
276
        set_fs (KERNEL_DS);
277
        ret = do_sigaltstack((stack_t __force __user *) (uss ? &kss : NULL),
278
                             (stack_t __force __user *) (uoss ? &koss : NULL),
279
                             regs->gprs[15]);
280
        set_fs (old_fs);
281
 
282
        if (!ret && uoss) {
283
                if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
284
                        return -EFAULT;
285
                ss_sp = (unsigned long) koss.ss_sp;
286
                err |= __put_user(ss_sp, &uoss->ss_sp);
287
                err |= __put_user(koss.ss_size, &uoss->ss_size);
288
                err |= __put_user(koss.ss_flags, &uoss->ss_flags);
289
                if (err)
290
                        return -EFAULT;
291
        }
292
        return ret;
293
}
294
 
295
static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
296
{
297
        _s390_regs_common32 regs32;
298
        int err, i;
299
 
300
        regs32.psw.mask = PSW32_MASK_MERGE(psw32_user_bits,
301
                                           (__u32)(regs->psw.mask >> 32));
302
        regs32.psw.addr = PSW32_ADDR_AMODE31 | (__u32) regs->psw.addr;
303
        for (i = 0; i < NUM_GPRS; i++)
304
                regs32.gprs[i] = (__u32) regs->gprs[i];
305
        save_access_regs(current->thread.acrs);
306
        memcpy(regs32.acrs, current->thread.acrs, sizeof(regs32.acrs));
307
        err = __copy_to_user(&sregs->regs, &regs32, sizeof(regs32));
308
        if (err)
309
                return err;
310
        save_fp_regs(&current->thread.fp_regs);
311
        /* s390_fp_regs and _s390_fp_regs32 are the same ! */
312
        return __copy_to_user(&sregs->fpregs, &current->thread.fp_regs,
313
                              sizeof(_s390_fp_regs32));
314
}
315
 
316
static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
317
{
318
        _s390_regs_common32 regs32;
319
        int err, i;
320
 
321
        /* Alwys make any pending restarted system call return -EINTR */
322
        current_thread_info()->restart_block.fn = do_no_restart_syscall;
323
 
324
        err = __copy_from_user(&regs32, &sregs->regs, sizeof(regs32));
325
        if (err)
326
                return err;
327
        regs->psw.mask = PSW_MASK_MERGE(regs->psw.mask,
328
                                        (__u64)regs32.psw.mask << 32);
329
        regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
330
        for (i = 0; i < NUM_GPRS; i++)
331
                regs->gprs[i] = (__u64) regs32.gprs[i];
332
        memcpy(current->thread.acrs, regs32.acrs, sizeof(current->thread.acrs));
333
        restore_access_regs(current->thread.acrs);
334
 
335
        err = __copy_from_user(&current->thread.fp_regs, &sregs->fpregs,
336
                               sizeof(_s390_fp_regs32));
337
        current->thread.fp_regs.fpc &= FPC_VALID_MASK;
338
        if (err)
339
                return err;
340
 
341
        restore_fp_regs(&current->thread.fp_regs);
342
        regs->trap = -1;        /* disable syscall checks */
343
        return 0;
344
}
345
 
346
asmlinkage long sys32_sigreturn(void)
347
{
348
        struct pt_regs *regs = task_pt_regs(current);
349
        sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
350
        sigset_t set;
351
 
352
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
353
                goto badframe;
354
        if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
355
                goto badframe;
356
 
357
        sigdelsetmask(&set, ~_BLOCKABLE);
358
        spin_lock_irq(&current->sighand->siglock);
359
        current->blocked = set;
360
        recalc_sigpending();
361
        spin_unlock_irq(&current->sighand->siglock);
362
 
363
        if (restore_sigregs32(regs, &frame->sregs))
364
                goto badframe;
365
 
366
        return regs->gprs[2];
367
 
368
badframe:
369
        force_sig(SIGSEGV, current);
370
        return 0;
371
}
372
 
373
asmlinkage long sys32_rt_sigreturn(void)
374
{
375
        struct pt_regs *regs = task_pt_regs(current);
376
        rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
377
        sigset_t set;
378
        stack_t st;
379
        __u32 ss_sp;
380
        int err;
381
        mm_segment_t old_fs = get_fs();
382
 
383
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
384
                goto badframe;
385
        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
386
                goto badframe;
387
 
388
        sigdelsetmask(&set, ~_BLOCKABLE);
389
        spin_lock_irq(&current->sighand->siglock);
390
        current->blocked = set;
391
        recalc_sigpending();
392
        spin_unlock_irq(&current->sighand->siglock);
393
 
394
        if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
395
                goto badframe;
396
 
397
        err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp);
398
        st.ss_sp = compat_ptr(ss_sp);
399
        err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size);
400
        err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags);
401
        if (err)
402
                goto badframe;
403
 
404
        set_fs (KERNEL_DS);
405
        do_sigaltstack((stack_t __force __user *)&st, NULL, regs->gprs[15]);
406
        set_fs (old_fs);
407
 
408
        return regs->gprs[2];
409
 
410
badframe:
411
        force_sig(SIGSEGV, current);
412
        return 0;
413
}
414
 
415
/*
416
 * Set up a signal frame.
417
 */
418
 
419
 
420
/*
421
 * Determine which stack to use..
422
 */
423
static inline void __user *
424
get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
425
{
426
        unsigned long sp;
427
 
428
        /* Default to using normal stack */
429
        sp = (unsigned long) A(regs->gprs[15]);
430
 
431
        /* This is the X/Open sanctioned signal stack switching.  */
432
        if (ka->sa.sa_flags & SA_ONSTACK) {
433
                if (! sas_ss_flags(sp))
434
                        sp = current->sas_ss_sp + current->sas_ss_size;
435
        }
436
 
437
        /* This is the legacy signal stack switching. */
438
        else if (!user_mode(regs) &&
439
                 !(ka->sa.sa_flags & SA_RESTORER) &&
440
                 ka->sa.sa_restorer) {
441
                sp = (unsigned long) ka->sa.sa_restorer;
442
        }
443
 
444
        return (void __user *)((sp - frame_size) & -8ul);
445
}
446
 
447
static inline int map_signal(int sig)
448
{
449
        if (current_thread_info()->exec_domain
450
            && current_thread_info()->exec_domain->signal_invmap
451
            && sig < 32)
452
                return current_thread_info()->exec_domain->signal_invmap[sig];
453
        else
454
                return sig;
455
}
456
 
457
static int setup_frame32(int sig, struct k_sigaction *ka,
458
                        sigset_t *set, struct pt_regs * regs)
459
{
460
        sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32));
461
        if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32)))
462
                goto give_sigsegv;
463
 
464
        if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32))
465
                goto give_sigsegv;
466
 
467
        if (save_sigregs32(regs, &frame->sregs))
468
                goto give_sigsegv;
469
        if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs))
470
                goto give_sigsegv;
471
 
472
        /* Set up to return from userspace.  If provided, use a stub
473
           already in userspace.  */
474
        if (ka->sa.sa_flags & SA_RESTORER) {
475
                regs->gprs[14] = (__u64) ka->sa.sa_restorer;
476
        } else {
477
                regs->gprs[14] = (__u64) frame->retcode;
478
                if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
479
                               (u16 __user *)(frame->retcode)))
480
                        goto give_sigsegv;
481
        }
482
 
483
        /* Set up backchain. */
484
        if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
485
                goto give_sigsegv;
486
 
487
        /* Set up registers for signal handler */
488
        regs->gprs[15] = (__u64) frame;
489
        regs->psw.addr = (__u64) ka->sa.sa_handler;
490
 
491
        regs->gprs[2] = map_signal(sig);
492
        regs->gprs[3] = (__u64) &frame->sc;
493
 
494
        /* We forgot to include these in the sigcontext.
495
           To avoid breaking binary compatibility, they are passed as args. */
496
        regs->gprs[4] = current->thread.trap_no;
497
        regs->gprs[5] = current->thread.prot_addr;
498
 
499
        /* Place signal number on stack to allow backtrace from handler.  */
500
        if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
501
                goto give_sigsegv;
502
        return 0;
503
 
504
give_sigsegv:
505
        force_sigsegv(sig, current);
506
        return -EFAULT;
507
}
508
 
509
static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
510
                           sigset_t *set, struct pt_regs * regs)
511
{
512
        int err = 0;
513
        rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
514
        if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32)))
515
                goto give_sigsegv;
516
 
517
        if (copy_siginfo_to_user32(&frame->info, info))
518
                goto give_sigsegv;
519
 
520
        /* Create the ucontext.  */
521
        err |= __put_user(0, &frame->uc.uc_flags);
522
        err |= __put_user(0, &frame->uc.uc_link);
523
        err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
524
        err |= __put_user(sas_ss_flags(regs->gprs[15]),
525
                          &frame->uc.uc_stack.ss_flags);
526
        err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
527
        err |= save_sigregs32(regs, &frame->uc.uc_mcontext);
528
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
529
        if (err)
530
                goto give_sigsegv;
531
 
532
        /* Set up to return from userspace.  If provided, use a stub
533
           already in userspace.  */
534
        if (ka->sa.sa_flags & SA_RESTORER) {
535
                regs->gprs[14] = (__u64) ka->sa.sa_restorer;
536
        } else {
537
                regs->gprs[14] = (__u64) frame->retcode;
538
                err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
539
                                  (u16 __user *)(frame->retcode));
540
        }
541
 
542
        /* Set up backchain. */
543
        if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
544
                goto give_sigsegv;
545
 
546
        /* Set up registers for signal handler */
547
        regs->gprs[15] = (__u64) frame;
548
        regs->psw.addr = (__u64) ka->sa.sa_handler;
549
 
550
        regs->gprs[2] = map_signal(sig);
551
        regs->gprs[3] = (__u64) &frame->info;
552
        regs->gprs[4] = (__u64) &frame->uc;
553
        return 0;
554
 
555
give_sigsegv:
556
        force_sigsegv(sig, current);
557
        return -EFAULT;
558
}
559
 
560
/*
561
 * OK, we're invoking a handler
562
 */
563
 
564
int
565
handle_signal32(unsigned long sig, struct k_sigaction *ka,
566
                siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
567
{
568
        int ret;
569
 
570
        /* Set up the stack frame */
571
        if (ka->sa.sa_flags & SA_SIGINFO)
572
                ret = setup_rt_frame32(sig, ka, info, oldset, regs);
573
        else
574
                ret = setup_frame32(sig, ka, oldset, regs);
575
 
576
        if (ret == 0) {
577
                spin_lock_irq(&current->sighand->siglock);
578
                sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
579
                if (!(ka->sa.sa_flags & SA_NODEFER))
580
                        sigaddset(&current->blocked,sig);
581
                recalc_sigpending();
582
                spin_unlock_irq(&current->sighand->siglock);
583
        }
584
        return ret;
585
}
586
 

powered by: WebSVN 2.1.0

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