xref: /linux/arch/xtensa/kernel/signal.c (revision c537b994505099b7197e7d3125b942ecbcc51eb6)
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 <asm/variant/core.h>
16 #include <asm/coprocessor.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 xtensa_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 xtensa_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 xtensa_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 (!access_ok(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 (!access_ok(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 xtensa_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 & ~PS_CALLINC_MASK)
220 		| (ps & 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 (!access_ok(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_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 xtensa_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 (!access_ok(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 xtensa_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 (!access_ok(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 && ! sas_ss_flags(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 		__invalidate_icache_range((unsigned long)codemem, 6UL);
502 		__flush_invalidate_dcache_range((unsigned long)codemem, 6UL);
503 	}
504 
505 	return err;
506 }
507 
508 static void
509 set_thread_state(struct pt_regs *regs, void *stack, unsigned char *retaddr,
510 	void *handler, unsigned long arg1, void *arg2, void *arg3)
511 {
512 	/* Set up registers for signal handler */
513 	start_thread(regs, (unsigned long) handler, (unsigned long) stack);
514 
515 	/* Set up a stack frame for a call4
516 	 * Note: PS.CALLINC is set to one by start_thread
517 	 */
518 	regs->areg[4] = (((unsigned long) retaddr) & 0x3fffffff) | 0x40000000;
519 	regs->areg[6] = arg1;
520 	regs->areg[7] = (unsigned long) arg2;
521 	regs->areg[8] = (unsigned long) arg3;
522 }
523 
524 static void setup_frame(int sig, struct k_sigaction *ka,
525 			sigset_t *set, struct pt_regs *regs)
526 {
527 	struct sigframe *frame;
528 	int err = 0;
529 	int signal;
530 
531 	frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
532 	if (regs->depc > 64)
533 	{
534 		printk("!!!!!!! DEPC !!!!!!!\n");
535 		return;
536 	}
537 
538 
539 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
540 		goto give_sigsegv;
541 
542 	signal = current_thread_info()->exec_domain
543 		&& current_thread_info()->exec_domain->signal_invmap
544 		&& sig < 32
545 		? current_thread_info()->exec_domain->signal_invmap[sig]
546 		: sig;
547 
548 	err |= setup_sigcontext(&frame->sc, &frame->cpstate, regs, set->sig[0]);
549 
550 	if (_NSIG_WORDS > 1) {
551 		err |= __copy_to_user(frame->extramask, &set->sig[1],
552 				      sizeof(frame->extramask));
553 	}
554 
555 	/* Create sys_sigreturn syscall in stack frame */
556 	err |= gen_return_code(frame->retcode, USE_SIGRETURN);
557 
558 	if (err)
559 		goto give_sigsegv;
560 
561 	/* Create signal handler execution context.
562 	 * Return context not modified until this point.
563 	 */
564 	set_thread_state(regs, frame, frame->retcode,
565 		ka->sa.sa_handler, signal, &frame->sc, NULL);
566 
567 	/* Set access mode to USER_DS.  Nomenclature is outdated, but
568 	 * functionality is used in uaccess.h
569 	 */
570 	set_fs(USER_DS);
571 
572 
573 #if DEBUG_SIG
574 	printk("SIG deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
575 		current->comm, current->pid, signal, frame, regs->pc);
576 #endif
577 
578 	return;
579 
580 give_sigsegv:
581 	if (sig == SIGSEGV)
582 		ka->sa.sa_handler = SIG_DFL;
583 	force_sig(SIGSEGV, current);
584 }
585 
586 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
587 			   sigset_t *set, struct pt_regs *regs)
588 {
589 	struct rt_sigframe *frame;
590 	int err = 0;
591 	int signal;
592 
593 	frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
594 	if (regs->depc > 64)
595 		panic ("Double exception sys_sigreturn\n");
596 
597 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
598 		goto give_sigsegv;
599 
600 	signal = current_thread_info()->exec_domain
601 		&& current_thread_info()->exec_domain->signal_invmap
602 		&& sig < 32
603 		? current_thread_info()->exec_domain->signal_invmap[sig]
604 		: sig;
605 
606 	err |= copy_siginfo_to_user(&frame->info, info);
607 
608 	/* Create the ucontext.  */
609 	err |= __put_user(0, &frame->uc.uc_flags);
610 	err |= __put_user(0, &frame->uc.uc_link);
611 	err |= __put_user((void *)current->sas_ss_sp,
612 			  &frame->uc.uc_stack.ss_sp);
613 	err |= __put_user(sas_ss_flags(regs->areg[1]),
614 			  &frame->uc.uc_stack.ss_flags);
615 	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
616 	err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate,
617 			        regs, set->sig[0]);
618 	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
619 
620 	/* Create sys_rt_sigreturn syscall in stack frame */
621 	err |= gen_return_code(frame->retcode, USE_RT_SIGRETURN);
622 
623 	if (err)
624 		goto give_sigsegv;
625 
626 	/* Create signal handler execution context.
627 	 * Return context not modified until this point.
628 	 */
629 	set_thread_state(regs, frame, frame->retcode,
630 		ka->sa.sa_handler, signal, &frame->info, &frame->uc);
631 
632 	/* Set access mode to USER_DS.  Nomenclature is outdated, but
633 	 * functionality is used in uaccess.h
634 	 */
635 	set_fs(USER_DS);
636 
637 #if DEBUG_SIG
638 	printk("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
639 		current->comm, current->pid, signal, frame, regs->pc);
640 #endif
641 
642 	return;
643 
644 give_sigsegv:
645 	if (sig == SIGSEGV)
646 		ka->sa.sa_handler = SIG_DFL;
647 	force_sig(SIGSEGV, current);
648 }
649 
650 
651 
652 /*
653  * Note that 'init' is a special process: it doesn't get signals it doesn't
654  * want to handle. Thus you cannot kill init even with a SIGKILL even by
655  * mistake.
656  *
657  * Note that we go through the signals twice: once to check the signals that
658  * the kernel can handle, and then we build all the user-level signal handling
659  * stack-frames in one go after that.
660  */
661 int do_signal(struct pt_regs *regs, sigset_t *oldset)
662 {
663 	siginfo_t info;
664 	int signr;
665 	struct k_sigaction ka;
666 
667 	if (!oldset)
668 		oldset = &current->blocked;
669 
670 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
671 
672 	/* Are we from a system call? */
673 	if (regs->syscall >= 0) {
674 		/* If so, check system call restarting.. */
675 		switch (regs->areg[2]) {
676 			case ERESTARTNOHAND:
677 			case ERESTART_RESTARTBLOCK:
678 				regs->areg[2] = -EINTR;
679 				break;
680 
681 			case ERESTARTSYS:
682 				if (!(ka.sa.sa_flags & SA_RESTART)) {
683 					regs->areg[2] = -EINTR;
684 					break;
685 				}
686 			/* fallthrough */
687 			case ERESTARTNOINTR:
688 				regs->areg[2] = regs->syscall;
689 				regs->pc -= 3;
690 		}
691 	}
692 
693 	if (signr == 0)
694 		return 0;		/* no signals delivered */
695 
696 	/* Whee!  Actually deliver the signal.  */
697 
698 	/* Set up the stack frame */
699 	if (ka.sa.sa_flags & SA_SIGINFO)
700 		setup_rt_frame(signr, &ka, &info, oldset, regs);
701 	else
702 		setup_frame(signr, &ka, oldset, regs);
703 
704 	if (ka.sa.sa_flags & SA_ONESHOT)
705 		ka.sa.sa_handler = SIG_DFL;
706 
707 	spin_lock_irq(&current->sighand->siglock);
708 	sigorsets(&current->blocked, &current->blocked, &ka.sa.sa_mask);
709 	if (!(ka.sa.sa_flags & SA_NODEFER))
710 		sigaddset(&current->blocked, signr);
711 	recalc_sigpending();
712 	spin_unlock_irq(&current->sighand->siglock);
713 	return 1;
714 }
715