Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / arch / sparc / kernel / signal.c
blob6ac8c4b00fa0c654df9bec72c544ac003dae78fb
1 /* $Id: signal.c,v 1.107 2000/09/05 21:44:54 davem Exp $
2 * linux/arch/sparc/kernel/signal.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
7 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
8 */
10 #include <linux/config.h>
11 #include <linux/sched.h>
12 #include <linux/kernel.h>
13 #include <linux/signal.h>
14 #include <linux/errno.h>
15 #include <linux/wait.h>
16 #include <linux/ptrace.h>
17 #include <linux/unistd.h>
18 #include <linux/mm.h>
19 #include <linux/smp.h>
20 #include <linux/smp_lock.h>
22 #include <asm/uaccess.h>
23 #include <asm/bitops.h>
24 #include <asm/ptrace.h>
25 #include <asm/svr4.h>
26 #include <asm/pgalloc.h>
27 #include <asm/pgtable.h>
29 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
31 asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
32 int options, unsigned long *ru);
34 extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
35 void *fpqueue, unsigned long *fpqdepth);
36 extern void fpload(unsigned long *fpregs, unsigned long *fsr);
38 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
39 unsigned long orig_o0, int ret_from_syscall);
41 /* This turned off for production... */
42 /* #define DEBUG_SIGNALS 1 */
43 /* #define DEBUG_SIGNALS_TRACE 1 */
44 /* #define DEBUG_SIGNALS_MAPS 1 */
46 /* Signal frames: the original one (compatible with SunOS):
48 * Set up a signal frame... Make the stack look the way SunOS
49 * expects it to look which is basically:
51 * ---------------------------------- <-- %sp at signal time
52 * Struct sigcontext
53 * Signal address
54 * Ptr to sigcontext area above
55 * Signal code
56 * The signal number itself
57 * One register window
58 * ---------------------------------- <-- New %sp
60 struct signal_sframe {
61 struct reg_window sig_window;
62 int sig_num;
63 int sig_code;
64 struct sigcontext *sig_scptr;
65 int sig_address;
66 struct sigcontext sig_context;
67 unsigned int extramask[_NSIG_WORDS - 1];
70 /*
71 * And the new one, intended to be used for Linux applications only
72 * (we have enough in there to work with clone).
73 * All the interesting bits are in the info field.
76 struct new_signal_frame {
77 struct sparc_stackf ss;
78 __siginfo_t info;
79 __siginfo_fpu_t *fpu_save;
80 unsigned long insns [2] __attribute__ ((aligned (8)));
81 unsigned int extramask[_NSIG_WORDS - 1];
82 unsigned int extra_size; /* Should be 0 */
83 __siginfo_fpu_t fpu_state;
86 struct rt_signal_frame {
87 struct sparc_stackf ss;
88 siginfo_t info;
89 struct pt_regs regs;
90 sigset_t mask;
91 __siginfo_fpu_t *fpu_save;
92 unsigned int insns [2];
93 stack_t stack;
94 unsigned int extra_size; /* Should be 0 */
95 __siginfo_fpu_t fpu_state;
98 int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
100 if (!access_ok(VERIFY_WRITE, to, sizeof(siginfo_t)))
101 return -EFAULT;
102 if (from->si_code < 0)
103 return __copy_to_user(to, from, sizeof(siginfo_t));
104 else {
105 int err;
107 /* If you change siginfo_t structure, please be sure
108 this code is fixed accordingly.
109 It should never copy any pad contained in the structure
110 to avoid security leaks, but must copy the generic
111 3 ints plus the relevant union member. */
112 err = __put_user(from->si_signo, &to->si_signo);
113 err |= __put_user(from->si_errno, &to->si_errno);
114 err |= __put_user((short)from->si_code, &to->si_code);
115 switch (from->si_code >> 16) {
116 case __SI_CHLD >> 16:
117 err |= __put_user(from->si_utime, &to->si_utime);
118 err |= __put_user(from->si_stime, &to->si_stime);
119 /* case __SI_RT: This is not generated by the kernel as of now. */
120 err |= __put_user(from->si_status, &to->si_status);
121 default:
122 err |= __put_user(from->si_uid, &to->si_uid);
123 err |= __put_user(from->si_pid, &to->si_pid);
124 break;
126 return err;
130 /* Align macros */
131 #define SF_ALIGNEDSZ (((sizeof(struct signal_sframe) + 7) & (~7)))
132 #define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame) + 7) & (~7)))
133 #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
136 * atomically swap in the new signal mask, and wait for a signal.
137 * This is really tricky on the Sparc, watch out...
139 asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs)
141 sigset_t saveset;
143 set &= _BLOCKABLE;
144 spin_lock_irq(&current->sigmask_lock);
145 saveset = current->blocked;
146 siginitset(&current->blocked, set);
147 recalc_sigpending(current);
148 spin_unlock_irq(&current->sigmask_lock);
150 regs->pc = regs->npc;
151 regs->npc += 4;
153 /* Condition codes and return value where set here for sigpause,
154 * and so got used by setup_frame, which again causes sigreturn()
155 * to return -EINTR.
157 while (1) {
158 current->state = TASK_INTERRUPTIBLE;
159 schedule();
161 * Return -EINTR and set condition code here,
162 * so the interrupted system call actually returns
163 * these.
165 regs->psr |= PSR_C;
166 regs->u_regs[UREG_I0] = EINTR;
167 if (do_signal(&saveset, regs, 0, 0))
168 return;
172 asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs)
174 _sigpause_common(set, regs);
177 asmlinkage void do_sigsuspend (struct pt_regs *regs)
179 _sigpause_common(regs->u_regs[UREG_I0], regs);
182 asmlinkage void do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize,
183 struct pt_regs *regs)
185 sigset_t oldset, set;
187 /* XXX: Don't preclude handling different sized sigset_t's. */
188 if (sigsetsize != sizeof(sigset_t)) {
189 regs->psr |= PSR_C;
190 regs->u_regs[UREG_I0] = EINVAL;
191 return;
194 if (copy_from_user(&set, uset, sizeof(set))) {
195 regs->psr |= PSR_C;
196 regs->u_regs[UREG_I0] = EFAULT;
197 return;
200 sigdelsetmask(&set, ~_BLOCKABLE);
201 spin_lock_irq(&current->sigmask_lock);
202 oldset = current->blocked;
203 current->blocked = set;
204 recalc_sigpending(current);
205 spin_unlock_irq(&current->sigmask_lock);
207 regs->pc = regs->npc;
208 regs->npc += 4;
210 /* Condition codes and return value where set here for sigpause,
211 * and so got used by setup_frame, which again causes sigreturn()
212 * to return -EINTR.
214 while (1) {
215 current->state = TASK_INTERRUPTIBLE;
216 schedule();
218 * Return -EINTR and set condition code here,
219 * so the interrupted system call actually returns
220 * these.
222 regs->psr |= PSR_C;
223 regs->u_regs[UREG_I0] = EINTR;
224 if (do_signal(&oldset, regs, 0, 0))
225 return;
229 static inline int
230 restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
232 int err;
233 #ifdef CONFIG_SMP
234 if (current->flags & PF_USEDFPU)
235 regs->psr &= ~PSR_EF;
236 #else
237 if (current == last_task_used_math) {
238 last_task_used_math = 0;
239 regs->psr &= ~PSR_EF;
241 #endif
242 current->used_math = 1;
243 current->flags &= ~PF_USEDFPU;
245 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
246 return -EFAULT;
248 err = __copy_from_user(&current->thread.float_regs[0], &fpu->si_float_regs[0],
249 (sizeof(unsigned long) * 32));
250 err |= __get_user(current->thread.fsr, &fpu->si_fsr);
251 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
252 if (current->thread.fpqdepth != 0)
253 err |= __copy_from_user(&current->thread.fpqueue[0],
254 &fpu->si_fpqueue[0],
255 ((sizeof(unsigned long) +
256 (sizeof(unsigned long *)))*16));
257 return err;
260 static inline void do_new_sigreturn (struct pt_regs *regs)
262 struct new_signal_frame *sf;
263 unsigned long up_psr, pc, npc;
264 sigset_t set;
265 __siginfo_fpu_t *fpu_save;
266 int err;
268 sf = (struct new_signal_frame *) regs->u_regs [UREG_FP];
270 /* 1. Make sure we are not getting garbage from the user */
271 if (verify_area (VERIFY_READ, sf, sizeof (*sf)))
272 goto segv_and_exit;
274 if (((uint) sf) & 3)
275 goto segv_and_exit;
277 err = __get_user(pc, &sf->info.si_regs.pc);
278 err |= __get_user(npc, &sf->info.si_regs.npc);
280 if ((pc | npc) & 3)
281 goto segv_and_exit;
283 /* 2. Restore the state */
284 up_psr = regs->psr;
285 err |= __copy_from_user(regs, &sf->info.si_regs, sizeof (struct pt_regs));
287 /* User can only change condition codes and FPU enabling in %psr. */
288 regs->psr = (up_psr & ~(PSR_ICC | PSR_EF))
289 | (regs->psr & (PSR_ICC | PSR_EF));
291 err |= __get_user(fpu_save, &sf->fpu_save);
293 if (fpu_save)
294 err |= restore_fpu_state(regs, fpu_save);
296 /* This is pretty much atomic, no amount locking would prevent
297 * the races which exist anyways.
299 err |= __get_user(set.sig[0], &sf->info.si_mask);
300 err |= __copy_from_user(&set.sig[1], &sf->extramask,
301 (_NSIG_WORDS-1) * sizeof(unsigned int));
303 if (err)
304 goto segv_and_exit;
306 sigdelsetmask(&set, ~_BLOCKABLE);
307 spin_lock_irq(&current->sigmask_lock);
308 current->blocked = set;
309 recalc_sigpending(current);
310 spin_unlock_irq(&current->sigmask_lock);
311 return;
313 segv_and_exit:
314 do_exit(SIGSEGV);
317 asmlinkage void do_sigreturn(struct pt_regs *regs)
319 struct sigcontext *scptr;
320 unsigned long pc, npc, psr;
321 sigset_t set;
322 int err;
324 synchronize_user_stack();
326 if (current->thread.new_signal)
327 return do_new_sigreturn (regs);
329 scptr = (struct sigcontext *) regs->u_regs[UREG_I0];
331 /* Check sanity of the user arg. */
332 if(verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext)) ||
333 (((unsigned long) scptr) & 3))
334 goto segv_and_exit;
336 err = __get_user(pc, &scptr->sigc_pc);
337 err |= __get_user(npc, &scptr->sigc_npc);
339 if((pc | npc) & 3)
340 goto segv_and_exit;
342 /* This is pretty much atomic, no amount locking would prevent
343 * the races which exist anyways.
345 err |= __get_user(set.sig[0], &scptr->sigc_mask);
346 /* Note that scptr + 1 points to extramask */
347 err |= __copy_from_user(&set.sig[1], scptr + 1,
348 (_NSIG_WORDS - 1) * sizeof(unsigned int));
350 if (err)
351 goto segv_and_exit;
353 sigdelsetmask(&set, ~_BLOCKABLE);
354 spin_lock_irq(&current->sigmask_lock);
355 current->blocked = set;
356 recalc_sigpending(current);
357 spin_unlock_irq(&current->sigmask_lock);
359 regs->pc = pc;
360 regs->npc = npc;
362 err = __get_user(regs->u_regs[UREG_FP], &scptr->sigc_sp);
363 err |= __get_user(regs->u_regs[UREG_I0], &scptr->sigc_o0);
364 err |= __get_user(regs->u_regs[UREG_G1], &scptr->sigc_g1);
366 /* User can only change condition codes in %psr. */
367 err |= __get_user(psr, &scptr->sigc_psr);
368 if (err)
369 goto segv_and_exit;
371 regs->psr &= ~(PSR_ICC);
372 regs->psr |= (psr & PSR_ICC);
373 return;
375 segv_and_exit:
376 send_sig(SIGSEGV, current, 1);
379 asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
381 struct rt_signal_frame *sf;
382 unsigned int psr, pc, npc;
383 __siginfo_fpu_t *fpu_save;
384 sigset_t set;
385 stack_t st;
386 int err;
388 synchronize_user_stack();
389 sf = (struct rt_signal_frame *) regs->u_regs[UREG_FP];
390 if(verify_area(VERIFY_READ, sf, sizeof(*sf)) ||
391 (((unsigned long) sf) & 0x03))
392 goto segv;
394 err = __get_user(pc, &sf->regs.pc);
395 err |= __get_user(npc, &sf->regs.npc);
396 err |= ((pc | npc) & 0x03);
398 err |= __get_user(regs->y, &sf->regs.y);
399 err |= __get_user(psr, &sf->regs.psr);
401 err |= __copy_from_user(&regs->u_regs[UREG_G1], &sf->regs.u_regs[UREG_G1], 15*sizeof(u32));
403 regs->psr = (regs->psr & ~PSR_ICC) | (psr & PSR_ICC);
405 err |= __get_user(fpu_save, &sf->fpu_save);
407 if(fpu_save)
408 err |= restore_fpu_state(regs, fpu_save);
409 err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
411 err |= __copy_from_user(&st, &sf->stack, sizeof(stack_t));
413 if (err)
414 goto segv;
416 regs->pc = pc;
417 regs->npc = npc;
419 /* It is more difficult to avoid calling this function than to
420 call it and ignore errors. */
421 do_sigaltstack(&st, NULL, (unsigned long)sf);
423 sigdelsetmask(&set, ~_BLOCKABLE);
424 spin_lock_irq(&current->sigmask_lock);
425 current->blocked = set;
426 recalc_sigpending(current);
427 spin_unlock_irq(&current->sigmask_lock);
428 return;
429 segv:
430 send_sig(SIGSEGV, current, 1);
433 /* Checks if the fp is valid */
434 static inline int invalid_frame_pointer (void *fp, int fplen)
436 if ((((unsigned long) fp) & 7) ||
437 !__access_ok((unsigned long)fp, fplen) ||
438 ((sparc_cpu_model == sun4 || sparc_cpu_model == sun4c) &&
439 ((unsigned long) fp < 0xe0000000 && (unsigned long) fp >= 0x20000000)))
440 return 1;
442 return 0;
445 static inline void *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
447 unsigned long sp;
449 sp = regs->u_regs[UREG_FP];
451 /* This is the X/Open sanctioned signal stack switching. */
452 if (sa->sa_flags & SA_ONSTACK) {
453 if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
454 sp = current->sas_ss_sp + current->sas_ss_size;
456 return (void *)(sp - framesize);
459 static inline void
460 setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info)
462 struct signal_sframe *sframep;
463 struct sigcontext *sc;
464 int window = 0, err;
465 unsigned long pc = regs->pc;
466 unsigned long npc = regs->npc;
467 void *sig_address;
468 int sig_code;
470 synchronize_user_stack();
471 sframep = (struct signal_sframe *)get_sigframe(sa, regs, SF_ALIGNEDSZ);
472 if (invalid_frame_pointer (sframep, sizeof(*sframep))){
473 #ifdef DEBUG_SIGNALS /* fills up the console logs during crashme runs, yuck... */
474 printk("%s [%d]: User has trashed signal stack\n",
475 current->comm, current->pid);
476 printk("Sigstack ptr %p handler at pc<%08lx> for sig<%d>\n",
477 sframep, pc, signr);
478 #endif
479 /* Don't change signal code and address, so that
480 * post mortem debuggers can have a look.
482 goto sigill_and_return;
485 sc = &sframep->sig_context;
487 /* We've already made sure frame pointer isn't in kernel space... */
488 err = __put_user((sas_ss_flags(regs->u_regs[UREG_FP]) == SS_ONSTACK),
489 &sc->sigc_onstack);
490 err |= __put_user(oldset->sig[0], &sc->sigc_mask);
491 err |= __copy_to_user(sframep->extramask, &oldset->sig[1],
492 (_NSIG_WORDS - 1) * sizeof(unsigned int));
493 err |= __put_user(regs->u_regs[UREG_FP], &sc->sigc_sp);
494 err |= __put_user(pc, &sc->sigc_pc);
495 err |= __put_user(npc, &sc->sigc_npc);
496 err |= __put_user(regs->psr, &sc->sigc_psr);
497 err |= __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
498 err |= __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
499 err |= __put_user(current->thread.w_saved, &sc->sigc_oswins);
500 if(current->thread.w_saved)
501 for(window = 0; window < current->thread.w_saved; window++) {
502 sc->sigc_spbuf[window] =
503 (char *)current->thread.rwbuf_stkptrs[window];
504 err |= __copy_to_user(&sc->sigc_wbuf[window],
505 &current->thread.reg_window[window],
506 sizeof(struct reg_window));
508 else
509 err |= __copy_to_user(sframep, (char *)regs->u_regs[UREG_FP],
510 sizeof(struct reg_window));
512 current->thread.w_saved = 0; /* So process is allowed to execute. */
514 err |= __put_user(signr, &sframep->sig_num);
515 sig_address = NULL;
516 sig_code = 0;
517 if (SI_FROMKERNEL (info) && (info->si_code & __SI_MASK) == __SI_FAULT) {
518 sig_address = info->si_addr;
519 switch (signr) {
520 case SIGSEGV:
521 switch (info->si_code) {
522 case SEGV_MAPERR: sig_code = SUBSIG_NOMAPPING; break;
523 default: sig_code = SUBSIG_PROTECTION; break;
525 break;
526 case SIGILL:
527 switch (info->si_code) {
528 case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break;
529 case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break;
530 case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP (info->si_trapno); break;
531 default: sig_code = SUBSIG_STACK; break;
533 break;
534 case SIGFPE:
535 switch (info->si_code) {
536 case FPE_INTDIV: sig_code = SUBSIG_IDIVZERO; break;
537 case FPE_INTOVF: sig_code = SUBSIG_FPINTOVFL; break;
538 case FPE_FLTDIV: sig_code = SUBSIG_FPDIVZERO; break;
539 case FPE_FLTOVF: sig_code = SUBSIG_FPOVFLOW; break;
540 case FPE_FLTUND: sig_code = SUBSIG_FPUNFLOW; break;
541 case FPE_FLTRES: sig_code = SUBSIG_FPINEXACT; break;
542 case FPE_FLTINV: sig_code = SUBSIG_FPOPERROR; break;
543 default: sig_code = SUBSIG_FPERROR; break;
545 break;
546 case SIGBUS:
547 switch (info->si_code) {
548 case BUS_ADRALN: sig_code = SUBSIG_ALIGNMENT; break;
549 case BUS_ADRERR: sig_code = SUBSIG_MISCERROR; break;
550 default: sig_code = SUBSIG_BUSTIMEOUT; break;
552 break;
553 case SIGEMT:
554 switch (info->si_code) {
555 case EMT_TAGOVF: sig_code = SUBSIG_TAG; break;
557 break;
558 case SIGSYS:
559 if (info->si_code == (__SI_FAULT|0x100)) {
560 /* See sys_sunos.c */
561 sig_code = info->si_trapno;
562 break;
564 default:
565 sig_address = NULL;
568 err |= __put_user((long)sig_address, &sframep->sig_address);
569 err |= __put_user(sig_code, &sframep->sig_code);
570 err |= __put_user(sc, &sframep->sig_scptr);
571 if (err)
572 goto sigsegv;
574 regs->u_regs[UREG_FP] = (unsigned long) sframep;
575 regs->pc = (unsigned long) sa->sa_handler;
576 regs->npc = (regs->pc + 4);
577 return;
579 sigill_and_return:
580 do_exit(SIGILL);
581 sigsegv:
582 do_exit(SIGSEGV);
586 static inline int
587 save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
589 int err = 0;
590 #ifdef CONFIG_SMP
591 if (current->flags & PF_USEDFPU) {
592 put_psr(get_psr() | PSR_EF);
593 fpsave(&current->thread.float_regs[0], &current->thread.fsr,
594 &current->thread.fpqueue[0], &current->thread.fpqdepth);
595 regs->psr &= ~(PSR_EF);
596 current->flags &= ~(PF_USEDFPU);
598 #else
599 if (current == last_task_used_math) {
600 put_psr(get_psr() | PSR_EF);
601 fpsave(&current->thread.float_regs[0], &current->thread.fsr,
602 &current->thread.fpqueue[0], &current->thread.fpqdepth);
603 last_task_used_math = 0;
604 regs->psr &= ~(PSR_EF);
606 #endif
607 err |= __copy_to_user(&fpu->si_float_regs[0], &current->thread.float_regs[0],
608 (sizeof(unsigned long) * 32));
609 err |= __put_user(current->thread.fsr, &fpu->si_fsr);
610 err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
611 if (current->thread.fpqdepth != 0)
612 err |= __copy_to_user(&fpu->si_fpqueue[0], &current->thread.fpqueue[0],
613 ((sizeof(unsigned long) +
614 (sizeof(unsigned long *)))*16));
615 current->used_math = 0;
616 return err;
619 static inline void
620 new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
621 int signo, sigset_t *oldset)
623 struct new_signal_frame *sf;
624 int sigframe_size, err;
626 /* 1. Make sure everything is clean */
627 synchronize_user_stack();
629 sigframe_size = NF_ALIGNEDSZ;
630 if (!current->used_math)
631 sigframe_size -= sizeof(__siginfo_fpu_t);
633 sf = (struct new_signal_frame *)get_sigframe(&ka->sa, regs, sigframe_size);
635 if (invalid_frame_pointer (sf, sigframe_size))
636 goto sigill_and_return;
638 if (current->thread.w_saved != 0) {
639 #ifdef DEBUG_SIGNALS
640 printk ("%s [%d]: Invalid user stack frame for "
641 "signal delivery.\n", current->comm, current->pid);
642 #endif
643 goto sigill_and_return;
646 /* 2. Save the current process state */
647 err = __copy_to_user(&sf->info.si_regs, regs, sizeof (struct pt_regs));
649 err |= __put_user(0, &sf->extra_size);
651 if (current->used_math) {
652 err |= save_fpu_state(regs, &sf->fpu_state);
653 err |= __put_user(&sf->fpu_state, &sf->fpu_save);
654 } else {
655 err |= __put_user(0, &sf->fpu_save);
658 err |= __put_user(oldset->sig[0], &sf->info.si_mask);
659 err |= __copy_to_user(sf->extramask, &oldset->sig[1],
660 (_NSIG_WORDS - 1) * sizeof(unsigned int));
661 err |= __copy_to_user(sf, (char *) regs->u_regs [UREG_FP],
662 sizeof (struct reg_window));
663 if (err)
664 goto sigsegv;
666 /* 3. signal handler back-trampoline and parameters */
667 regs->u_regs[UREG_FP] = (unsigned long) sf;
668 regs->u_regs[UREG_I0] = signo;
669 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
671 /* 4. signal handler */
672 regs->pc = (unsigned long) ka->sa.sa_handler;
673 regs->npc = (regs->pc + 4);
675 /* 5. return to kernel instructions */
676 if (ka->ka_restorer)
677 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
678 else {
679 regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2);
681 /* mov __NR_sigreturn, %g1 */
682 err |= __put_user(0x821020d8, &sf->insns[0]);
684 /* t 0x10 */
685 err |= __put_user(0x91d02010, &sf->insns[1]);
686 if (err)
687 goto sigsegv;
689 /* Flush instruction space. */
690 flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
692 return;
694 sigill_and_return:
695 do_exit(SIGILL);
696 sigsegv:
697 do_exit(SIGSEGV);
700 static inline void
701 new_setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
702 int signo, sigset_t *oldset, siginfo_t *info)
704 struct rt_signal_frame *sf;
705 int sigframe_size;
706 unsigned int psr;
707 int err;
709 synchronize_user_stack();
710 sigframe_size = RT_ALIGNEDSZ;
711 if(!current->used_math)
712 sigframe_size -= sizeof(__siginfo_fpu_t);
713 sf = (struct rt_signal_frame *)get_sigframe(&ka->sa, regs, sigframe_size);
714 if(invalid_frame_pointer(sf, sigframe_size))
715 goto sigill;
716 if(current->thread.w_saved != 0)
717 goto sigill;
719 err = __put_user(regs->pc, &sf->regs.pc);
720 err |= __put_user(regs->npc, &sf->regs.npc);
721 err |= __put_user(regs->y, &sf->regs.y);
722 psr = regs->psr;
723 if(current->used_math)
724 psr |= PSR_EF;
725 err |= __put_user(psr, &sf->regs.psr);
726 err |= __copy_to_user(&sf->regs.u_regs, regs->u_regs, sizeof(regs->u_regs));
727 err |= __put_user(0, &sf->extra_size);
729 if(psr & PSR_EF) {
730 err |= save_fpu_state(regs, &sf->fpu_state);
731 err |= __put_user(&sf->fpu_state, &sf->fpu_save);
732 } else {
733 err |= __put_user(0, &sf->fpu_save);
735 err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));
737 /* Setup sigaltstack */
738 err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
739 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
740 err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
742 err |= __copy_to_user(sf, (char *) regs->u_regs [UREG_FP],
743 sizeof (struct reg_window));
745 err |= copy_siginfo_to_user(&sf->info, info);
747 if (err)
748 goto sigsegv;
750 regs->u_regs[UREG_FP] = (unsigned long) sf;
751 regs->u_regs[UREG_I0] = signo;
752 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
754 regs->pc = (unsigned long) ka->sa.sa_handler;
755 regs->npc = (regs->pc + 4);
757 if(ka->ka_restorer)
758 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
759 else {
760 regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2);
762 /* mov __NR_sigreturn, %g1 */
763 err |= __put_user(0x821020d8, &sf->insns[0]);
765 /* t 0x10 */
766 err |= __put_user(0x91d02010, &sf->insns[1]);
767 if (err)
768 goto sigsegv;
770 /* Flush instruction space. */
771 flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
773 return;
775 sigill:
776 do_exit(SIGILL);
777 sigsegv:
778 do_exit(SIGSEGV);
781 /* Setup a Solaris stack frame */
782 static inline void
783 setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
784 struct pt_regs *regs, int signr, sigset_t *oldset)
786 svr4_signal_frame_t *sfp;
787 svr4_gregset_t *gr;
788 svr4_siginfo_t *si;
789 svr4_mcontext_t *mc;
790 svr4_gwindows_t *gw;
791 svr4_ucontext_t *uc;
792 svr4_sigset_t setv;
793 int window = 0, err;
795 synchronize_user_stack();
796 sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, SVR4_SF_ALIGNED + REGWIN_SZ);
798 if (invalid_frame_pointer (sfp, sizeof (*sfp))){
799 #ifdef DEBUG_SIGNALS
800 printk ("Invalid stack frame\n");
801 #endif
802 goto sigill_and_return;
805 /* Start with a clean frame pointer and fill it */
806 err = __clear_user(sfp, sizeof (*sfp));
808 /* Setup convenience variables */
809 si = &sfp->si;
810 uc = &sfp->uc;
811 gw = &sfp->gw;
812 mc = &uc->mcontext;
813 gr = &mc->greg;
815 /* FIXME: where am I supposed to put this?
816 * sc->sigc_onstack = old_status;
817 * anyways, it does not look like it is used for anything at all.
819 setv.sigbits[0] = oldset->sig[0];
820 setv.sigbits[1] = oldset->sig[1];
821 if (_NSIG_WORDS >= 4) {
822 setv.sigbits[2] = oldset->sig[2];
823 setv.sigbits[3] = oldset->sig[3];
824 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
825 } else
826 err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned int));
828 /* Store registers */
829 err |= __put_user(regs->pc, &((*gr) [SVR4_PC]));
830 err |= __put_user(regs->npc, &((*gr) [SVR4_NPC]));
831 err |= __put_user(regs->psr, &((*gr) [SVR4_PSR]));
832 err |= __put_user(regs->y, &((*gr) [SVR4_Y]));
834 /* Copy g [1..7] and o [0..7] registers */
835 err |= __copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs [UREG_G1], sizeof (long) * 7);
836 err |= __copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs [UREG_I0], sizeof (long) * 8);
838 /* Setup sigaltstack */
839 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
840 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
841 err |= __put_user(current->sas_ss_size, &uc->stack.size);
843 /* Save the currently window file: */
845 /* 1. Link sfp->uc->gwins to our windows */
846 err |= __put_user(gw, &mc->gwin);
848 /* 2. Number of windows to restore at setcontext (): */
849 err |= __put_user(current->thread.w_saved, &gw->count);
851 /* 3. Save each valid window
852 * Currently, it makes a copy of the windows from the kernel copy.
853 * David's code for SunOS, makes the copy but keeps the pointer to
854 * the kernel. My version makes the pointer point to a userland
855 * copy of those. Mhm, I wonder if I shouldn't just ignore those
856 * on setcontext and use those that are on the kernel, the signal
857 * handler should not be modyfing those, mhm.
859 * These windows are just used in case synchronize_user_stack failed
860 * to flush the user windows.
862 for(window = 0; window < current->thread.w_saved; window++) {
863 err |= __put_user((int *) &(gw->win [window]), &gw->winptr [window]);
864 err |= __copy_to_user(&gw->win [window],
865 &current->thread.reg_window [window],
866 sizeof (svr4_rwindow_t));
867 err |= __put_user(0, gw->winptr [window]);
870 /* 4. We just pay attention to the gw->count field on setcontext */
871 current->thread.w_saved = 0; /* So process is allowed to execute. */
873 /* Setup the signal information. Solaris expects a bunch of
874 * information to be passed to the signal handler, we don't provide
875 * that much currently, should use siginfo.
877 err |= __put_user(signr, &si->siginfo.signo);
878 err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
879 if (err)
880 goto sigsegv;
882 regs->u_regs[UREG_FP] = (unsigned long) sfp;
883 regs->pc = (unsigned long) sa->sa_handler;
884 regs->npc = (regs->pc + 4);
886 #ifdef DEBUG_SIGNALS
887 printk ("Solaris-frame: %x %x\n", (int) regs->pc, (int) regs->npc);
888 #endif
889 /* Arguments passed to signal handler */
890 if (regs->u_regs [14]){
891 struct reg_window *rw = (struct reg_window *) regs->u_regs [14];
893 err |= __put_user(signr, &rw->ins [0]);
894 err |= __put_user(si, &rw->ins [1]);
895 err |= __put_user(uc, &rw->ins [2]);
896 err |= __put_user(sfp, &rw->ins [6]); /* frame pointer */
897 if (err)
898 goto sigsegv;
900 regs->u_regs[UREG_I0] = signr;
901 regs->u_regs[UREG_I1] = (uint) si;
902 regs->u_regs[UREG_I2] = (uint) uc;
904 return;
906 sigill_and_return:
907 do_exit(SIGILL);
908 sigsegv:
909 do_exit(SIGSEGV);
912 asmlinkage int svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs)
914 svr4_gregset_t *gr;
915 svr4_mcontext_t *mc;
916 svr4_sigset_t setv;
917 int err = 0;
919 synchronize_user_stack();
921 if (current->thread.w_saved)
922 goto sigsegv_and_return;
924 err = clear_user(uc, sizeof (*uc));
925 if (err)
926 return -EFAULT;
928 /* Setup convenience variables */
929 mc = &uc->mcontext;
930 gr = &mc->greg;
932 setv.sigbits[0] = current->blocked.sig[0];
933 setv.sigbits[1] = current->blocked.sig[1];
934 if (_NSIG_WORDS >= 4) {
935 setv.sigbits[2] = current->blocked.sig[2];
936 setv.sigbits[3] = current->blocked.sig[3];
937 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
938 } else
939 err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned int));
941 /* Store registers */
942 err |= __put_user(regs->pc, &uc->mcontext.greg [SVR4_PC]);
943 err |= __put_user(regs->npc, &uc->mcontext.greg [SVR4_NPC]);
944 err |= __put_user(regs->psr, &uc->mcontext.greg [SVR4_PSR]);
945 err |= __put_user(regs->y, &uc->mcontext.greg [SVR4_Y]);
947 /* Copy g [1..7] and o [0..7] registers */
948 err |= __copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs [UREG_G1], sizeof (uint) * 7);
949 err |= __copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs [UREG_I0], sizeof (uint) * 8);
951 /* Setup sigaltstack */
952 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
953 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
954 err |= __put_user(current->sas_ss_size, &uc->stack.size);
956 /* The register file is not saved
957 * we have already stuffed all of it with sync_user_stack
959 return (err ? -EFAULT : 0);
961 sigsegv_and_return:
962 do_exit(SIGSEGV);
965 /* Set the context for a svr4 application, this is Solaris way to sigreturn */
966 asmlinkage int svr4_setcontext (svr4_ucontext_t *c, struct pt_regs *regs)
968 struct thread_struct *tp = &current->thread;
969 svr4_gregset_t *gr;
970 unsigned long pc, npc, psr;
971 sigset_t set;
972 svr4_sigset_t setv;
973 int err;
974 stack_t st;
976 /* Fixme: restore windows, or is this already taken care of in
977 * svr4_setup_frame when sync_user_windows is done?
979 flush_user_windows();
981 if (tp->w_saved)
982 goto sigsegv_and_return;
984 if (((uint) c) & 3)
985 goto sigsegv_and_return;
987 if(!__access_ok((unsigned long)c, sizeof(*c)))
988 goto sigsegv_and_return;
990 /* Check for valid PC and nPC */
991 gr = &c->mcontext.greg;
992 err = __get_user(pc, &((*gr)[SVR4_PC]));
993 err |= __get_user(npc, &((*gr)[SVR4_NPC]));
995 if((pc | npc) & 3)
996 goto sigsegv_and_return;
998 /* Retrieve information from passed ucontext */
999 /* note that nPC is ored a 1, this is used to inform entry.S */
1000 /* that we don't want it to mess with our PC and nPC */
1002 /* This is pretty much atomic, no amount locking would prevent
1003 * the races which exist anyways.
1005 err |= __copy_from_user(&setv, &c->sigmask, sizeof(svr4_sigset_t));
1007 err |= __get_user(st.ss_sp, &c->stack.sp);
1008 err |= __get_user(st.ss_flags, &c->stack.flags);
1009 err |= __get_user(st.ss_size, &c->stack.size);
1011 if (err)
1012 goto sigsegv_and_return;
1014 /* It is more difficult to avoid calling this function than to
1015 call it and ignore errors. */
1016 do_sigaltstack(&st, NULL, regs->u_regs[UREG_I6]);
1018 set.sig[0] = setv.sigbits[0];
1019 set.sig[1] = setv.sigbits[1];
1020 if (_NSIG_WORDS >= 4) {
1021 set.sig[2] = setv.sigbits[2];
1022 set.sig[3] = setv.sigbits[3];
1024 sigdelsetmask(&set, ~_BLOCKABLE);
1025 spin_lock_irq(&current->sigmask_lock);
1026 current->blocked = set;
1027 recalc_sigpending(current);
1028 spin_unlock_irq(&current->sigmask_lock);
1029 regs->pc = pc;
1030 regs->npc = npc | 1;
1031 err |= __get_user(regs->y, &((*gr) [SVR4_Y]));
1032 err |= __get_user(psr, &((*gr) [SVR4_PSR]));
1033 regs->psr &= ~(PSR_ICC);
1034 regs->psr |= (psr & PSR_ICC);
1036 /* Restore g[1..7] and o[0..7] registers */
1037 err |= __copy_from_user(&regs->u_regs [UREG_G1], &(*gr)[SVR4_G1],
1038 sizeof (long) * 7);
1039 err |= __copy_from_user(&regs->u_regs [UREG_I0], &(*gr)[SVR4_O0],
1040 sizeof (long) * 8);
1041 return (err ? -EFAULT : 0);
1043 sigsegv_and_return:
1044 do_exit(SIGSEGV);
1047 static inline void
1048 handle_signal(unsigned long signr, struct k_sigaction *ka,
1049 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs,
1050 int svr4_signal)
1052 if (svr4_signal)
1053 setup_svr4_frame(&ka->sa, regs->pc, regs->npc, regs, signr, oldset);
1054 else {
1055 if (ka->sa.sa_flags & SA_SIGINFO)
1056 new_setup_rt_frame(ka, regs, signr, oldset, info);
1057 else if (current->thread.new_signal)
1058 new_setup_frame (ka, regs, signr, oldset);
1059 else
1060 setup_frame(&ka->sa, regs, signr, oldset, info);
1062 if(ka->sa.sa_flags & SA_ONESHOT)
1063 ka->sa.sa_handler = SIG_DFL;
1064 if(!(ka->sa.sa_flags & SA_NOMASK)) {
1065 spin_lock_irq(&current->sigmask_lock);
1066 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
1067 sigaddset(&current->blocked, signr);
1068 recalc_sigpending(current);
1069 spin_unlock_irq(&current->sigmask_lock);
1073 static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
1074 struct sigaction *sa)
1076 switch(regs->u_regs[UREG_I0]) {
1077 case ERESTARTNOHAND:
1078 no_system_call_restart:
1079 regs->u_regs[UREG_I0] = EINTR;
1080 regs->psr |= PSR_C;
1081 break;
1082 case ERESTARTSYS:
1083 if(!(sa->sa_flags & SA_RESTART))
1084 goto no_system_call_restart;
1085 /* fallthrough */
1086 case ERESTARTNOINTR:
1087 regs->u_regs[UREG_I0] = orig_i0;
1088 regs->pc -= 4;
1089 regs->npc -= 4;
1093 #ifdef DEBUG_SIGNALS_MAPS
1095 #define MAPS_LINE_FORMAT "%08lx-%08lx %s %08lx %s %lu "
1097 static inline void read_maps (void)
1099 struct vm_area_struct * map, * next;
1100 char * buffer;
1101 ssize_t i;
1103 buffer = (char*)__get_free_page(GFP_KERNEL);
1104 if (!buffer)
1105 return;
1107 for (map = current->mm->mmap ; map ; map = next ) {
1108 /* produce the next line */
1109 char *line;
1110 char str[5], *cp = str;
1111 int flags;
1112 kdev_t dev;
1113 unsigned long ino;
1116 * Get the next vma now (but it won't be used if we sleep).
1118 next = map->vm_next;
1119 flags = map->vm_flags;
1121 *cp++ = flags & VM_READ ? 'r' : '-';
1122 *cp++ = flags & VM_WRITE ? 'w' : '-';
1123 *cp++ = flags & VM_EXEC ? 'x' : '-';
1124 *cp++ = flags & VM_MAYSHARE ? 's' : 'p';
1125 *cp++ = 0;
1127 dev = 0;
1128 ino = 0;
1129 if (map->vm_file != NULL) {
1130 dev = map->vm_file->f_dentry->d_inode->i_dev;
1131 ino = map->vm_file->f_dentry->d_inode->i_ino;
1132 line = d_path(map->vm_file->f_dentry,
1133 map->vm_file->f_vfsmnt,
1134 buffer, PAGE_SIZE);
1136 printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
1137 kdevname(dev), ino);
1138 if (map->vm_file != NULL)
1139 printk("%s\n", line);
1140 else
1141 printk("\n");
1143 free_page((unsigned long)buffer);
1144 return;
1146 #endif
1148 /* Note that 'init' is a special process: it doesn't get signals it doesn't
1149 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1150 * mistake.
1152 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
1153 unsigned long orig_i0, int restart_syscall)
1155 unsigned long signr;
1156 struct k_sigaction *ka;
1157 siginfo_t info;
1160 * XXX Disable svr4 signal handling until solaris emulation works.
1161 * It is buggy - Anton
1163 #define SVR4_SIGNAL_BROKEN 1
1164 #ifdef SVR4_SIGNAL_BROKEN
1165 int svr4_signal = 0;
1166 #else
1167 int svr4_signal = current->personality == PER_SVR4;
1168 #endif
1170 if (!oldset)
1171 oldset = &current->blocked;
1173 for (;;) {
1174 spin_lock_irq(&current->sigmask_lock);
1175 signr = dequeue_signal(&current->blocked, &info);
1176 spin_unlock_irq(&current->sigmask_lock);
1178 if (!signr) break;
1180 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
1181 current->exit_code = signr;
1182 current->state = TASK_STOPPED;
1184 /* This happens to be SMP safe so no need to
1185 * grab master kernel lock even in this case.
1187 notify_parent(current, SIGCHLD);
1188 schedule();
1189 if (!(signr = current->exit_code))
1190 continue;
1191 current->exit_code = 0;
1192 if (signr == SIGSTOP)
1193 continue;
1195 /* Update the siginfo structure. Is this good? */
1196 if (signr != info.si_signo) {
1197 info.si_signo = signr;
1198 info.si_errno = 0;
1199 info.si_code = SI_USER;
1200 info.si_pid = current->p_pptr->pid;
1201 info.si_uid = current->p_pptr->uid;
1204 /* If the (new) signal is now blocked, requeue it. */
1205 if (sigismember(&current->blocked, signr)) {
1206 send_sig_info(signr, &info, current);
1207 continue;
1211 ka = &current->sig->action[signr-1];
1213 if(ka->sa.sa_handler == SIG_IGN) {
1214 if(signr != SIGCHLD)
1215 continue;
1217 /* sys_wait4() grabs the master kernel lock, so
1218 * we need not do so, that sucker should be
1219 * threaded and would not be that difficult to
1220 * do anyways.
1222 while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
1224 continue;
1226 if(ka->sa.sa_handler == SIG_DFL) {
1227 unsigned long exit_code = signr;
1229 if(current->pid == 1)
1230 continue;
1231 switch(signr) {
1232 case SIGCONT: case SIGCHLD: case SIGWINCH:
1233 continue;
1235 case SIGTSTP: case SIGTTIN: case SIGTTOU:
1236 /* The operations performed by
1237 * is_orphaned_pgrp() are protected by
1238 * the tasklist_lock.
1240 if (is_orphaned_pgrp(current->pgrp))
1241 continue;
1243 case SIGSTOP:
1244 if (current->ptrace & PT_PTRACED)
1245 continue;
1246 current->state = TASK_STOPPED;
1247 current->exit_code = signr;
1249 /* notify_parent() is SMP safe */
1250 if(!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
1251 SA_NOCLDSTOP))
1252 notify_parent(current, SIGCHLD);
1253 schedule();
1254 continue;
1256 case SIGQUIT: case SIGILL: case SIGTRAP:
1257 case SIGABRT: case SIGFPE: case SIGSEGV:
1258 case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
1259 if (do_coredump(signr, regs))
1260 exit_code |= 0x80;
1261 #ifdef DEBUG_SIGNALS
1262 /* Very useful to debug dynamic linker problems */
1263 printk ("Sig %ld going for %s[%d]...\n", signr, current->comm, current->pid);
1264 show_regs (regs);
1265 #ifdef DEBUG_SIGNALS_TRACE
1267 struct reg_window *rw = (struct reg_window *)regs->u_regs[UREG_FP];
1268 unsigned int ins[8];
1270 while(rw &&
1271 !(((unsigned long) rw) & 0x3)) {
1272 copy_from_user(ins, &rw->ins[0], sizeof(ins));
1273 printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
1274 rw = (struct reg_window *)(unsigned long)ins[6];
1277 #endif
1278 #ifdef DEBUG_SIGNALS_MAPS
1279 printk("Maps:\n");
1280 read_maps();
1281 #endif
1282 #endif
1283 /* fall through */
1284 default:
1285 sigaddset(&current->pending.signal, signr);
1286 recalc_sigpending(current);
1287 current->flags |= PF_SIGNALED;
1288 do_exit(exit_code);
1289 /* NOT REACHED */
1292 if(restart_syscall)
1293 syscall_restart(orig_i0, regs, &ka->sa);
1294 handle_signal(signr, ka, &info, oldset, regs, svr4_signal);
1295 return 1;
1297 if(restart_syscall &&
1298 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
1299 regs->u_regs[UREG_I0] == ERESTARTSYS ||
1300 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
1301 /* replay the system call when we are done */
1302 regs->u_regs[UREG_I0] = orig_i0;
1303 regs->pc -= 4;
1304 regs->npc -= 4;
1306 return 0;
1309 asmlinkage int
1310 do_sys_sigstack(struct sigstack *ssptr, struct sigstack *ossptr, unsigned long sp)
1312 int ret = -EFAULT;
1314 /* First see if old state is wanted. */
1315 if (ossptr) {
1316 if (put_user(current->sas_ss_sp + current->sas_ss_size, &ossptr->the_stack) ||
1317 __put_user(on_sig_stack(sp), &ossptr->cur_status))
1318 goto out;
1321 /* Now see if we want to update the new state. */
1322 if (ssptr) {
1323 void *ss_sp;
1325 if (get_user((long)ss_sp, &ssptr->the_stack))
1326 goto out;
1327 /* If the current stack was set with sigaltstack, don't
1328 swap stacks while we are on it. */
1329 ret = -EPERM;
1330 if (current->sas_ss_sp && on_sig_stack(sp))
1331 goto out;
1333 /* Since we don't know the extent of the stack, and we don't
1334 track onstack-ness, but rather calculate it, we must
1335 presume a size. Ho hum this interface is lossy. */
1336 current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
1337 current->sas_ss_size = SIGSTKSZ;
1339 ret = 0;
1340 out:
1341 return ret;