xref: /openbmc/linux/arch/xtensa/kernel/signal.c (revision 87c2ce3b)
1 // TODO coprocessor stuff
2 /*
3  *  linux/arch/xtensa/kernel/signal.c
4  *
5  *  Copyright (C) 1991, 1992  Linus Torvalds
6  *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
7  *
8  *  Joe Taylor <joe@tensilica.com>
9  *  Chris Zankel <chris@zankel.net>
10  *
11  *
12  *
13  */
14 
15 #include <xtensa/config/core.h>
16 #include <xtensa/hal.h>
17 #include <linux/sched.h>
18 #include <linux/mm.h>
19 #include <linux/smp.h>
20 #include <linux/smp_lock.h>
21 #include <linux/kernel.h>
22 #include <linux/signal.h>
23 #include <linux/errno.h>
24 #include <linux/wait.h>
25 #include <linux/ptrace.h>
26 #include <linux/unistd.h>
27 #include <linux/stddef.h>
28 #include <linux/personality.h>
29 #include <asm/ucontext.h>
30 #include <asm/uaccess.h>
31 #include <asm/pgtable.h>
32 #include <asm/cacheflush.h>
33 
34 #define DEBUG_SIG  0
35 
36 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
37 
38 asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options,
39 			  struct rusage * ru);
40 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
41 
42 extern struct task_struct *coproc_owners[];
43 
44 
45 /*
46  * Atomically swap in the new signal mask, and wait for a signal.
47  */
48 
49 int sys_sigsuspend(struct pt_regs *regs)
50 {
51 	old_sigset_t mask = (old_sigset_t) regs->areg[3];
52 	sigset_t saveset;
53 
54 	mask &= _BLOCKABLE;
55 	spin_lock_irq(&current->sighand->siglock);
56 	saveset = current->blocked;
57 	siginitset(&current->blocked, mask);
58 	recalc_sigpending();
59 	spin_unlock_irq(&current->sighand->siglock);
60 
61 	regs->areg[2] = -EINTR;
62 	while (1) {
63 		current->state = TASK_INTERRUPTIBLE;
64 		schedule();
65 		if (do_signal(regs, &saveset))
66 			return -EINTR;
67 	}
68 }
69 
70 asmlinkage int
71 sys_rt_sigsuspend(struct pt_regs *regs)
72 {
73 	sigset_t *unewset = (sigset_t *) regs->areg[4];
74 	size_t sigsetsize = (size_t) regs->areg[3];
75 	sigset_t saveset, newset;
76 	/* XXX: Don't preclude handling different sized sigset_t's.  */
77 	if (sigsetsize != sizeof(sigset_t))
78 		return -EINVAL;
79 
80 	if (copy_from_user(&newset, unewset, sizeof(newset)))
81 		return -EFAULT;
82 	sigdelsetmask(&newset, ~_BLOCKABLE);
83 	spin_lock_irq(&current->sighand->siglock);
84 	saveset = current->blocked;
85 	current->blocked = newset;
86 	recalc_sigpending();
87 	spin_unlock_irq(&current->sighand->siglock);
88 
89 	regs->areg[2] = -EINTR;
90 	while (1) {
91 		current->state = TASK_INTERRUPTIBLE;
92 		schedule();
93 		if (do_signal(regs, &saveset))
94 			return -EINTR;
95 	}
96 }
97 
98 asmlinkage int
99 sys_sigaction(int sig, const struct old_sigaction *act,
100 	      struct old_sigaction *oact)
101 {
102 	struct k_sigaction new_ka, old_ka;
103 	int ret;
104 
105 	if (act) {
106 		old_sigset_t mask;
107 		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
108 		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
109 		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
110 			return -EFAULT;
111 		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
112 		__get_user(mask, &act->sa_mask);
113 		siginitset(&new_ka.sa.sa_mask, mask);
114 	}
115 
116 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
117 
118 	if (!ret && oact) {
119 		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
120 		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
121 		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
122 			return -EFAULT;
123 		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
124 		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
125 	}
126 
127 	return ret;
128 }
129 
130 asmlinkage int
131 sys_sigaltstack(struct pt_regs *regs)
132 {
133 	const stack_t *uss = (stack_t *) regs->areg[4];
134 	stack_t *uoss = (stack_t *) regs->areg[3];
135 
136 	if (regs->depc > 64)
137 		panic ("Double exception sys_sigreturn\n");
138 
139 
140 	return do_sigaltstack(uss, uoss, regs->areg[1]);
141 }
142 
143 
144 /*
145  * Do a signal return; undo the signal stack.
146  */
147 
148 struct sigframe
149 {
150 	struct sigcontext sc;
151 	struct _cpstate cpstate;
152 	unsigned long extramask[_NSIG_WORDS-1];
153 	unsigned char retcode[6];
154 	unsigned int reserved[4]; /* Reserved area for chaining */
155 	unsigned int window[4]; /* Window of 4 registers for initial context */
156 };
157 
158 struct rt_sigframe
159 {
160 	struct siginfo info;
161 	struct ucontext uc;
162 	struct _cpstate cpstate;
163 	unsigned char retcode[6];
164 	unsigned int reserved[4]; /* Reserved area for chaining */
165 	unsigned int window[4]; /* Window of 4 registers for initial context */
166 };
167 
168 extern void release_all_cp (struct task_struct *);
169 
170 
171 // FIXME restore_cpextra
172 static inline int
173 restore_cpextra (struct _cpstate *buf)
174 {
175 #if 0
176 	/* The signal handler may have used coprocessors in which
177 	 * case they are still enabled.  We disable them to force a
178 	 * reloading of the original task's CP state by the lazy
179 	 * context-switching mechanisms of CP exception handling.
180 	 * Also, we essentially discard any coprocessor state that the
181 	 * signal handler created. */
182 
183 	struct task_struct *tsk = current;
184 	release_all_cp(tsk);
185 	return __copy_from_user(tsk->thread.cpextra, buf, XTENSA_CP_EXTRA_SIZE);
186 #endif
187 	return 0;
188 }
189 
190 /* Note: We don't copy double exception 'tregs', we have to finish double exc. first before we return to signal handler! This dbl.exc.handler might cause another double exception, but I think we are fine as the situation is the same as if we had returned to the signal handerl and got an interrupt immediately...
191  */
192 
193 
194 static int
195 restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
196 {
197 	struct thread_struct *thread;
198 	unsigned int err = 0;
199 	unsigned long ps;
200 	struct _cpstate *buf;
201 
202 #define COPY(x)	err |= __get_user(regs->x, &sc->sc_##x)
203 	COPY(pc);
204 	COPY(depc);
205 	COPY(wmask);
206 	COPY(lbeg);
207 	COPY(lend);
208 	COPY(lcount);
209 	COPY(sar);
210 	COPY(windowbase);
211 	COPY(windowstart);
212 #undef COPY
213 
214 	/* For PS, restore only PS.CALLINC.
215 	 * Assume that all other bits are either the same as for the signal
216 	 * handler, or the user mode value doesn't matter (e.g. PS.OWB).
217 	 */
218 	err |= __get_user(ps, &sc->sc_ps);
219 	regs->ps = (regs->ps & ~XCHAL_PS_CALLINC_MASK)
220 		| (ps & XCHAL_PS_CALLINC_MASK);
221 
222 	/* Additional corruption checks */
223 
224 	if ((regs->windowbase >= (XCHAL_NUM_AREGS/4))
225 	|| ((regs->windowstart & ~((1<<(XCHAL_NUM_AREGS/4)) - 1)) != 0) )
226 		err = 1;
227 	if ((regs->lcount > 0)
228 	&& ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) )
229 		err = 1;
230 
231 	/* Restore extended register state.
232 	 * See struct thread_struct in processor.h.
233 	 */
234 	thread = &current->thread;
235 
236 	err |= __copy_from_user (regs->areg, sc->sc_areg, XCHAL_NUM_AREGS*4);
237 	err |= __get_user(buf, &sc->sc_cpstate);
238 	if (buf) {
239 		if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
240 			goto badframe;
241 		err |= restore_cpextra(buf);
242 	}
243 
244 	regs->syscall = -1;		/* disable syscall checks */
245 	return err;
246 
247 badframe:
248 	return 1;
249 }
250 
251 static inline void
252 flush_my_cpstate(struct task_struct *tsk)
253 {
254 	unsigned long flags;
255 	local_irq_save(flags);
256 
257 #if 0	// FIXME
258 	for (i = 0; i < XCHAL_CP_NUM; i++) {
259 		if (tsk == coproc_owners[i]) {
260 			xthal_validate_cp(i);
261 			xthal_save_cpregs(tsk->thread.cpregs_ptr[i], i);
262 
263 			/* Invalidate and "disown" the cp to allow
264 			 * callers the chance to reset cp state in the
265 			 * task_struct. */
266 
267 			xthal_invalidate_cp(i);
268 			coproc_owners[i] = 0;
269 		}
270 	}
271 #endif
272 	local_irq_restore(flags);
273 }
274 
275 /* Return codes:
276 	0:  nothing saved
277 	1:  stuff to save, successful
278        -1:  stuff to save, error happened
279 */
280 static int
281 save_cpextra (struct _cpstate *buf)
282 {
283 #if (XCHAL_EXTRA_SA_SIZE == 0) && (XCHAL_CP_NUM == 0)
284 	return 0;
285 #else
286 
287 	/* FIXME: If a task has never used a coprocessor, there is
288 	 * no need to save and restore anything.  Tracking this
289 	 * information would allow us to optimize this section.
290 	 * Perhaps we can use current->used_math or (current->flags &
291 	 * PF_USEDFPU) or define a new field in the thread
292 	 * structure. */
293 
294 	/* We flush any live, task-owned cp state to the task_struct,
295 	 * then copy it all to the sigframe.  Then we clear all
296 	 * cp/extra state in the task_struct, effectively
297 	 * clearing/resetting all cp/extra state for the signal
298 	 * handler (cp-exception handling will load these new values
299 	 * into the cp/extra registers.)  This step is important for
300 	 * things like a floating-point cp, where the OS must reset
301 	 * the FCR to the default rounding mode. */
302 
303 	int err = 0;
304 	struct task_struct *tsk = current;
305 
306 	flush_my_cpstate(tsk);
307 	/* Note that we just copy everything: 'extra' and 'cp' state together.*/
308 	err |= __copy_to_user(buf, tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE);
309 	memset(tsk->thread.cp_save, 0, XTENSA_CP_EXTRA_SIZE);
310 
311 #if (XTENSA_CP_EXTRA_SIZE == 0)
312 #error Sanity check on memset above, cpextra_size should not be zero.
313 #endif
314 
315 	return err ? -1 : 1;
316 #endif
317 }
318 
319 static int
320 setup_sigcontext(struct sigcontext *sc, struct _cpstate *cpstate,
321 		 struct pt_regs *regs, unsigned long mask)
322 {
323 	struct thread_struct *thread;
324 	int err = 0;
325 
326 //printk("setup_sigcontext\n");
327 #define COPY(x)	err |= __put_user(regs->x, &sc->sc_##x)
328 	COPY(pc);
329 	COPY(ps);
330 	COPY(depc);
331 	COPY(wmask);
332 	COPY(lbeg);
333 	COPY(lend);
334 	COPY(lcount);
335 	COPY(sar);
336 	COPY(windowbase);
337 	COPY(windowstart);
338 #undef COPY
339 
340 	/* Save extended register state.
341 	 * See struct thread_struct in processor.h.
342 	 */
343 	thread = &current->thread;
344 	err |= __copy_to_user (sc->sc_areg, regs->areg, XCHAL_NUM_AREGS * 4);
345 	err |= save_cpextra(cpstate);
346 	err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate);
347 	/* non-iBCS2 extensions.. */
348 	err |= __put_user(mask, &sc->oldmask);
349 
350 	return err;
351 }
352 
353 asmlinkage int sys_sigreturn(struct pt_regs *regs)
354 {
355 	struct sigframe *frame = (struct sigframe *)regs->areg[1];
356 	sigset_t set;
357 	if (regs->depc > 64)
358 		panic ("Double exception sys_sigreturn\n");
359 
360 	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
361 		goto badframe;
362 
363 	if (__get_user(set.sig[0], &frame->sc.oldmask)
364 	    || (_NSIG_WORDS > 1
365 		&& __copy_from_user(&set.sig[1], &frame->extramask,
366 				    sizeof(frame->extramask))))
367 		goto badframe;
368 
369 	sigdelsetmask(&set, ~_BLOCKABLE);
370 
371 	spin_lock_irq(&current->sighand->siglock);
372 	current->blocked = set;
373 	recalc_sigpending();
374 	spin_unlock_irq(&current->sighand->siglock);
375 
376 	if (restore_sigcontext(regs, &frame->sc))
377 		goto badframe;
378 	return regs->areg[2];
379 
380 badframe:
381 	force_sig(SIGSEGV, current);
382 	return 0;
383 }
384 
385 asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
386 {
387 	struct rt_sigframe *frame = (struct rt_sigframe *)regs->areg[1];
388 	sigset_t set;
389 	stack_t st;
390 	int ret;
391 	if (regs->depc > 64)
392 	{
393 		printk("!!!!!!! DEPC !!!!!!!\n");
394 		return 0;
395 	}
396 
397 	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
398 		goto badframe;
399 
400 	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
401 		goto badframe;
402 
403 	sigdelsetmask(&set, ~_BLOCKABLE);
404 	spin_lock_irq(&current->sighand->siglock);
405 	current->blocked = set;
406 	recalc_sigpending();
407 	spin_unlock_irq(&current->sighand->siglock);
408 
409 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
410 		goto badframe;
411 	ret = regs->areg[2];
412 
413 	if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
414 		goto badframe;
415 	/* It is more difficult to avoid calling this function than to
416 	   call it and ignore errors.  */
417 	do_sigaltstack(&st, NULL, regs->areg[1]);
418 
419 	return ret;
420 
421 badframe:
422 	force_sig(SIGSEGV, current);
423 	return 0;
424 }
425 
426 /*
427  * Set up a signal frame.
428  */
429 
430 /*
431  * Determine which stack to use..
432  */
433 static inline void *
434 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
435 {
436 	if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
437 		sp = current->sas_ss_sp + current->sas_ss_size;
438 
439 	return (void *)((sp - frame_size) & -16ul);
440 }
441 
442 #define USE_SIGRETURN		0
443 #define USE_RT_SIGRETURN	1
444 
445 static int
446 gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn)
447 {
448 	unsigned int retcall;
449 	int err = 0;
450 
451 #if 0
452 	/* Ignoring SA_RESTORER for now; it's supposed to be obsolete,
453 	 * and the xtensa glibc doesn't use it.
454 	 */
455 	if (ka->sa.sa_flags & SA_RESTORER) {
456 		regs->pr = (unsigned long) ka->sa.sa_restorer;
457 	} else
458 #endif /* 0 */
459 	{
460 
461 #if (__NR_sigreturn > 255) || (__NR_rt_sigreturn > 255)
462 
463 /* The 12-bit immediate is really split up within the 24-bit MOVI
464  * instruction.  As long as the above system call numbers fit within
465  * 8-bits, the following code works fine. See the Xtensa ISA for
466  * details.
467  */
468 
469 #error Generating the MOVI instruction below breaks!
470 #endif
471 
472 		retcall = use_rt_sigreturn ? __NR_rt_sigreturn : __NR_sigreturn;
473 
474 #ifdef __XTENSA_EB__   /* Big Endian version */
475 		/* Generate instruction:  MOVI a2, retcall */
476 		err |= __put_user(0x22, &codemem[0]);
477 		err |= __put_user(0x0a, &codemem[1]);
478 		err |= __put_user(retcall, &codemem[2]);
479 		/* Generate instruction:  SYSCALL */
480 		err |= __put_user(0x00, &codemem[3]);
481 		err |= __put_user(0x05, &codemem[4]);
482 		err |= __put_user(0x00, &codemem[5]);
483 
484 #elif defined __XTENSA_EL__   /* Little Endian version */
485 		/* Generate instruction:  MOVI a2, retcall */
486 		err |= __put_user(0x22, &codemem[0]);
487 		err |= __put_user(0xa0, &codemem[1]);
488 		err |= __put_user(retcall, &codemem[2]);
489 		/* Generate instruction:  SYSCALL */
490 		err |= __put_user(0x00, &codemem[3]);
491 		err |= __put_user(0x50, &codemem[4]);
492 		err |= __put_user(0x00, &codemem[5]);
493 #else
494 #error Must use compiler for Xtensa processors.
495 #endif
496 	}
497 
498 	/* Flush generated code out of the data cache */
499 
500 	if (err == 0)
501 		__flush_invalidate_cache_range((unsigned long)codemem, 6UL);
502 
503 	return err;
504 }
505 
506 static void
507 set_thread_state(struct pt_regs *regs, void *stack, unsigned char *retaddr,
508 	void *handler, unsigned long arg1, void *arg2, void *arg3)
509 {
510 	/* Set up registers for signal handler */
511 	start_thread(regs, (unsigned long) handler, (unsigned long) stack);
512 
513 	/* Set up a stack frame for a call4
514 	 * Note: PS.CALLINC is set to one by start_thread
515 	 */
516 	regs->areg[4] = (((unsigned long) retaddr) & 0x3fffffff) | 0x40000000;
517 	regs->areg[6] = arg1;
518 	regs->areg[7] = (unsigned long) arg2;
519 	regs->areg[8] = (unsigned long) arg3;
520 }
521 
522 static void setup_frame(int sig, struct k_sigaction *ka,
523 			sigset_t *set, struct pt_regs *regs)
524 {
525 	struct sigframe *frame;
526 	int err = 0;
527 	int signal;
528 
529 	frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
530 	if (regs->depc > 64)
531 	{
532 		printk("!!!!!!! DEPC !!!!!!!\n");
533 		return;
534 	}
535 
536 
537 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
538 		goto give_sigsegv;
539 
540 	signal = current_thread_info()->exec_domain
541 		&& current_thread_info()->exec_domain->signal_invmap
542 		&& sig < 32
543 		? current_thread_info()->exec_domain->signal_invmap[sig]
544 		: sig;
545 
546 	err |= setup_sigcontext(&frame->sc, &frame->cpstate, regs, set->sig[0]);
547 
548 	if (_NSIG_WORDS > 1) {
549 		err |= __copy_to_user(frame->extramask, &set->sig[1],
550 				      sizeof(frame->extramask));
551 	}
552 
553 	/* Create sys_sigreturn syscall in stack frame */
554 	err |= gen_return_code(frame->retcode, USE_SIGRETURN);
555 
556 	if (err)
557 		goto give_sigsegv;
558 
559 	/* Create signal handler execution context.
560 	 * Return context not modified until this point.
561 	 */
562 	set_thread_state(regs, frame, frame->retcode,
563 		ka->sa.sa_handler, signal, &frame->sc, NULL);
564 
565 	/* Set access mode to USER_DS.  Nomenclature is outdated, but
566 	 * functionality is used in uaccess.h
567 	 */
568 	set_fs(USER_DS);
569 
570 
571 #if DEBUG_SIG
572 	printk("SIG deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
573 		current->comm, current->pid, signal, frame, regs->pc);
574 #endif
575 
576 	return;
577 
578 give_sigsegv:
579 	if (sig == SIGSEGV)
580 		ka->sa.sa_handler = SIG_DFL;
581 	force_sig(SIGSEGV, current);
582 }
583 
584 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
585 			   sigset_t *set, struct pt_regs *regs)
586 {
587 	struct rt_sigframe *frame;
588 	int err = 0;
589 	int signal;
590 
591 	frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
592 	if (regs->depc > 64)
593 		panic ("Double exception sys_sigreturn\n");
594 
595 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
596 		goto give_sigsegv;
597 
598 	signal = current_thread_info()->exec_domain
599 		&& current_thread_info()->exec_domain->signal_invmap
600 		&& sig < 32
601 		? current_thread_info()->exec_domain->signal_invmap[sig]
602 		: sig;
603 
604 	err |= copy_siginfo_to_user(&frame->info, info);
605 
606 	/* Create the ucontext.  */
607 	err |= __put_user(0, &frame->uc.uc_flags);
608 	err |= __put_user(0, &frame->uc.uc_link);
609 	err |= __put_user((void *)current->sas_ss_sp,
610 			  &frame->uc.uc_stack.ss_sp);
611 	err |= __put_user(sas_ss_flags(regs->areg[1]),
612 			  &frame->uc.uc_stack.ss_flags);
613 	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
614 	err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate,
615 			        regs, set->sig[0]);
616 	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
617 
618 	/* Create sys_rt_sigreturn syscall in stack frame */
619 	err |= gen_return_code(frame->retcode, USE_RT_SIGRETURN);
620 
621 	if (err)
622 		goto give_sigsegv;
623 
624 	/* Create signal handler execution context.
625 	 * Return context not modified until this point.
626 	 */
627 	set_thread_state(regs, frame, frame->retcode,
628 		ka->sa.sa_handler, signal, &frame->info, &frame->uc);
629 
630 	/* Set access mode to USER_DS.  Nomenclature is outdated, but
631 	 * functionality is used in uaccess.h
632 	 */
633 	set_fs(USER_DS);
634 
635 #if DEBUG_SIG
636 	printk("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
637 		current->comm, current->pid, signal, frame, regs->pc);
638 #endif
639 
640 	return;
641 
642 give_sigsegv:
643 	if (sig == SIGSEGV)
644 		ka->sa.sa_handler = SIG_DFL;
645 	force_sig(SIGSEGV, current);
646 }
647 
648 
649 
650 /*
651  * Note that 'init' is a special process: it doesn't get signals it doesn't
652  * want to handle. Thus you cannot kill init even with a SIGKILL even by
653  * mistake.
654  *
655  * Note that we go through the signals twice: once to check the signals that
656  * the kernel can handle, and then we build all the user-level signal handling
657  * stack-frames in one go after that.
658  */
659 int do_signal(struct pt_regs *regs, sigset_t *oldset)
660 {
661 	siginfo_t info;
662 	int signr;
663 	struct k_sigaction ka;
664 
665 	if (!oldset)
666 		oldset = &current->blocked;
667 
668 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
669 
670 	/* Are we from a system call? */
671 	if (regs->syscall >= 0) {
672 		/* If so, check system call restarting.. */
673 		switch (regs->areg[2]) {
674 			case ERESTARTNOHAND:
675 			case ERESTART_RESTARTBLOCK:
676 				regs->areg[2] = -EINTR;
677 				break;
678 
679 			case ERESTARTSYS:
680 				if (!(ka.sa.sa_flags & SA_RESTART)) {
681 					regs->areg[2] = -EINTR;
682 					break;
683 				}
684 			/* fallthrough */
685 			case ERESTARTNOINTR:
686 				regs->areg[2] = regs->syscall;
687 				regs->pc -= 3;
688 		}
689 	}
690 
691 	if (signr == 0)
692 		return 0;		/* no signals delivered */
693 
694 	/* Whee!  Actually deliver the signal.  */
695 
696 	/* Set up the stack frame */
697 	if (ka.sa.sa_flags & SA_SIGINFO)
698 		setup_rt_frame(signr, &ka, &info, oldset, regs);
699 	else
700 		setup_frame(signr, &ka, oldset, regs);
701 
702 	if (ka.sa.sa_flags & SA_ONESHOT)
703 		ka.sa.sa_handler = SIG_DFL;
704 
705 	spin_lock_irq(&current->sighand->siglock);
706 	sigorsets(&current->blocked, &current->blocked, &ka.sa.sa_mask);
707 	if (!(ka.sa.sa_flags & SA_NODEFER))
708 		sigaddset(&current->blocked, signr);
709 	recalc_sigpending();
710 	spin_unlock_irq(&current->sighand->siglock);
711 	return 1;
712 }
713