• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/sparc/kernel/
1/*
2 *  arch/sparc64/kernel/signal.c
3 *
4 *  Copyright (C) 1991, 1992  Linus Torvalds
5 *  Copyright (C) 1995, 2008 David S. Miller (davem@davemloft.net)
6 *  Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
7 *  Copyright (C) 1997 Eddie C. Dost   (ecd@skynet.be)
8 *  Copyright (C) 1997,1998 Jakub Jelinek   (jj@sunsite.mff.cuni.cz)
9 */
10
11#ifdef CONFIG_COMPAT
12#include <linux/compat.h>	/* for compat_old_sigset_t */
13#endif
14#include <linux/sched.h>
15#include <linux/kernel.h>
16#include <linux/signal.h>
17#include <linux/errno.h>
18#include <linux/wait.h>
19#include <linux/ptrace.h>
20#include <linux/tracehook.h>
21#include <linux/unistd.h>
22#include <linux/mm.h>
23#include <linux/tty.h>
24#include <linux/binfmts.h>
25#include <linux/bitops.h>
26
27#include <asm/uaccess.h>
28#include <asm/ptrace.h>
29#include <asm/pgtable.h>
30#include <asm/fpumacro.h>
31#include <asm/uctx.h>
32#include <asm/siginfo.h>
33#include <asm/visasm.h>
34
35#include "entry.h"
36#include "systbls.h"
37
38#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
39
40/* {set, get}context() needed for 64-bit SparcLinux userland. */
41asmlinkage void sparc64_set_context(struct pt_regs *regs)
42{
43	struct ucontext __user *ucp = (struct ucontext __user *)
44		regs->u_regs[UREG_I0];
45	mc_gregset_t __user *grp;
46	unsigned long pc, npc, tstate;
47	unsigned long fp, i7;
48	unsigned char fenab;
49	int err;
50
51	flush_user_windows();
52	if (get_thread_wsaved()					||
53	    (((unsigned long)ucp) & (sizeof(unsigned long)-1))	||
54	    (!__access_ok(ucp, sizeof(*ucp))))
55		goto do_sigsegv;
56	grp  = &ucp->uc_mcontext.mc_gregs;
57	err  = __get_user(pc, &((*grp)[MC_PC]));
58	err |= __get_user(npc, &((*grp)[MC_NPC]));
59	if (err || ((pc | npc) & 3))
60		goto do_sigsegv;
61	if (regs->u_regs[UREG_I1]) {
62		sigset_t set;
63
64		if (_NSIG_WORDS == 1) {
65			if (__get_user(set.sig[0], &ucp->uc_sigmask.sig[0]))
66				goto do_sigsegv;
67		} else {
68			if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(sigset_t)))
69				goto do_sigsegv;
70		}
71		sigdelsetmask(&set, ~_BLOCKABLE);
72		spin_lock_irq(&current->sighand->siglock);
73		current->blocked = set;
74		recalc_sigpending();
75		spin_unlock_irq(&current->sighand->siglock);
76	}
77	if (test_thread_flag(TIF_32BIT)) {
78		pc &= 0xffffffff;
79		npc &= 0xffffffff;
80	}
81	regs->tpc = pc;
82	regs->tnpc = npc;
83	err |= __get_user(regs->y, &((*grp)[MC_Y]));
84	err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
85	regs->tstate &= ~(TSTATE_ASI | TSTATE_ICC | TSTATE_XCC);
86	regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));
87	err |= __get_user(regs->u_regs[UREG_G1], (&(*grp)[MC_G1]));
88	err |= __get_user(regs->u_regs[UREG_G2], (&(*grp)[MC_G2]));
89	err |= __get_user(regs->u_regs[UREG_G3], (&(*grp)[MC_G3]));
90	err |= __get_user(regs->u_regs[UREG_G4], (&(*grp)[MC_G4]));
91	err |= __get_user(regs->u_regs[UREG_G5], (&(*grp)[MC_G5]));
92	err |= __get_user(regs->u_regs[UREG_G6], (&(*grp)[MC_G6]));
93
94	/* Skip %g7 as that's the thread register in userspace.  */
95
96	err |= __get_user(regs->u_regs[UREG_I0], (&(*grp)[MC_O0]));
97	err |= __get_user(regs->u_regs[UREG_I1], (&(*grp)[MC_O1]));
98	err |= __get_user(regs->u_regs[UREG_I2], (&(*grp)[MC_O2]));
99	err |= __get_user(regs->u_regs[UREG_I3], (&(*grp)[MC_O3]));
100	err |= __get_user(regs->u_regs[UREG_I4], (&(*grp)[MC_O4]));
101	err |= __get_user(regs->u_regs[UREG_I5], (&(*grp)[MC_O5]));
102	err |= __get_user(regs->u_regs[UREG_I6], (&(*grp)[MC_O6]));
103	err |= __get_user(regs->u_regs[UREG_I7], (&(*grp)[MC_O7]));
104
105	err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
106	err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
107	err |= __put_user(fp,
108	      (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[6])));
109	err |= __put_user(i7,
110	      (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
111
112	err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
113	if (fenab) {
114		unsigned long *fpregs = current_thread_info()->fpregs;
115		unsigned long fprs;
116
117		fprs_write(0);
118		err |= __get_user(fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
119		if (fprs & FPRS_DL)
120			err |= copy_from_user(fpregs,
121					      &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs),
122					      (sizeof(unsigned int) * 32));
123		if (fprs & FPRS_DU)
124			err |= copy_from_user(fpregs+16,
125			 ((unsigned long __user *)&(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs))+16,
126			 (sizeof(unsigned int) * 32));
127		err |= __get_user(current_thread_info()->xfsr[0],
128				  &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
129		err |= __get_user(current_thread_info()->gsr[0],
130				  &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
131		regs->tstate &= ~TSTATE_PEF;
132	}
133	if (err)
134		goto do_sigsegv;
135
136	return;
137do_sigsegv:
138	force_sig(SIGSEGV, current);
139}
140
141asmlinkage void sparc64_get_context(struct pt_regs *regs)
142{
143	struct ucontext __user *ucp = (struct ucontext __user *)
144		regs->u_regs[UREG_I0];
145	mc_gregset_t __user *grp;
146	mcontext_t __user *mcp;
147	unsigned long fp, i7;
148	unsigned char fenab;
149	int err;
150
151	synchronize_user_stack();
152	if (get_thread_wsaved() || clear_user(ucp, sizeof(*ucp)))
153		goto do_sigsegv;
154
155	fenab = 0; /* IMO get_context is like any other system call, thus modifies FPU state -jj */
156
157	mcp = &ucp->uc_mcontext;
158	grp = &mcp->mc_gregs;
159
160	/* Skip over the trap instruction, first. */
161	if (test_thread_flag(TIF_32BIT)) {
162		regs->tpc   = (regs->tnpc & 0xffffffff);
163		regs->tnpc  = (regs->tnpc + 4) & 0xffffffff;
164	} else {
165		regs->tpc   = regs->tnpc;
166		regs->tnpc += 4;
167	}
168	err = 0;
169	if (_NSIG_WORDS == 1)
170		err |= __put_user(current->blocked.sig[0],
171				  (unsigned long __user *)&ucp->uc_sigmask);
172	else
173		err |= __copy_to_user(&ucp->uc_sigmask, &current->blocked,
174				      sizeof(sigset_t));
175
176	err |= __put_user(regs->tstate, &((*grp)[MC_TSTATE]));
177	err |= __put_user(regs->tpc, &((*grp)[MC_PC]));
178	err |= __put_user(regs->tnpc, &((*grp)[MC_NPC]));
179	err |= __put_user(regs->y, &((*grp)[MC_Y]));
180	err |= __put_user(regs->u_regs[UREG_G1], &((*grp)[MC_G1]));
181	err |= __put_user(regs->u_regs[UREG_G2], &((*grp)[MC_G2]));
182	err |= __put_user(regs->u_regs[UREG_G3], &((*grp)[MC_G3]));
183	err |= __put_user(regs->u_regs[UREG_G4], &((*grp)[MC_G4]));
184	err |= __put_user(regs->u_regs[UREG_G5], &((*grp)[MC_G5]));
185	err |= __put_user(regs->u_regs[UREG_G6], &((*grp)[MC_G6]));
186	err |= __put_user(regs->u_regs[UREG_G7], &((*grp)[MC_G7]));
187	err |= __put_user(regs->u_regs[UREG_I0], &((*grp)[MC_O0]));
188	err |= __put_user(regs->u_regs[UREG_I1], &((*grp)[MC_O1]));
189	err |= __put_user(regs->u_regs[UREG_I2], &((*grp)[MC_O2]));
190	err |= __put_user(regs->u_regs[UREG_I3], &((*grp)[MC_O3]));
191	err |= __put_user(regs->u_regs[UREG_I4], &((*grp)[MC_O4]));
192	err |= __put_user(regs->u_regs[UREG_I5], &((*grp)[MC_O5]));
193	err |= __put_user(regs->u_regs[UREG_I6], &((*grp)[MC_O6]));
194	err |= __put_user(regs->u_regs[UREG_I7], &((*grp)[MC_O7]));
195
196	err |= __get_user(fp,
197		 (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[6])));
198	err |= __get_user(i7,
199		 (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
200	err |= __put_user(fp, &(mcp->mc_fp));
201	err |= __put_user(i7, &(mcp->mc_i7));
202
203	err |= __put_user(fenab, &(mcp->mc_fpregs.mcfpu_enab));
204	if (fenab) {
205		unsigned long *fpregs = current_thread_info()->fpregs;
206		unsigned long fprs;
207
208		fprs = current_thread_info()->fpsaved[0];
209		if (fprs & FPRS_DL)
210			err |= copy_to_user(&(mcp->mc_fpregs.mcfpu_fregs), fpregs,
211					    (sizeof(unsigned int) * 32));
212		if (fprs & FPRS_DU)
213			err |= copy_to_user(
214                          ((unsigned long __user *)&(mcp->mc_fpregs.mcfpu_fregs))+16, fpregs+16,
215			  (sizeof(unsigned int) * 32));
216		err |= __put_user(current_thread_info()->xfsr[0], &(mcp->mc_fpregs.mcfpu_fsr));
217		err |= __put_user(current_thread_info()->gsr[0], &(mcp->mc_fpregs.mcfpu_gsr));
218		err |= __put_user(fprs, &(mcp->mc_fpregs.mcfpu_fprs));
219	}
220	if (err)
221		goto do_sigsegv;
222
223	return;
224do_sigsegv:
225	force_sig(SIGSEGV, current);
226}
227
228struct rt_signal_frame {
229	struct sparc_stackf	ss;
230	siginfo_t		info;
231	struct pt_regs		regs;
232	__siginfo_fpu_t __user	*fpu_save;
233	stack_t			stack;
234	sigset_t		mask;
235	__siginfo_fpu_t		fpu_state;
236};
237
238static long _sigpause_common(old_sigset_t set)
239{
240	set &= _BLOCKABLE;
241	spin_lock_irq(&current->sighand->siglock);
242	current->saved_sigmask = current->blocked;
243	siginitset(&current->blocked, set);
244	recalc_sigpending();
245	spin_unlock_irq(&current->sighand->siglock);
246
247	current->state = TASK_INTERRUPTIBLE;
248	schedule();
249
250	set_restore_sigmask();
251
252	return -ERESTARTNOHAND;
253}
254
255asmlinkage long sys_sigpause(unsigned int set)
256{
257	return _sigpause_common(set);
258}
259
260asmlinkage long sys_sigsuspend(old_sigset_t set)
261{
262	return _sigpause_common(set);
263}
264
265static inline int
266restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
267{
268	unsigned long *fpregs = current_thread_info()->fpregs;
269	unsigned long fprs;
270	int err;
271
272	err = __get_user(fprs, &fpu->si_fprs);
273	fprs_write(0);
274	regs->tstate &= ~TSTATE_PEF;
275	if (fprs & FPRS_DL)
276		err |= copy_from_user(fpregs, &fpu->si_float_regs[0],
277		       	       (sizeof(unsigned int) * 32));
278	if (fprs & FPRS_DU)
279		err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32],
280		       	       (sizeof(unsigned int) * 32));
281	err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
282	err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
283	current_thread_info()->fpsaved[0] |= fprs;
284	return err;
285}
286
287void do_rt_sigreturn(struct pt_regs *regs)
288{
289	struct rt_signal_frame __user *sf;
290	unsigned long tpc, tnpc, tstate;
291	__siginfo_fpu_t __user *fpu_save;
292	sigset_t set;
293	int err;
294
295	/* Always make any pending restarted system calls return -EINTR */
296	current_thread_info()->restart_block.fn = do_no_restart_syscall;
297
298	synchronize_user_stack ();
299	sf = (struct rt_signal_frame __user *)
300		(regs->u_regs [UREG_FP] + STACK_BIAS);
301
302	/* 1. Make sure we are not getting garbage from the user */
303	if (((unsigned long) sf) & 3)
304		goto segv;
305
306	err = get_user(tpc, &sf->regs.tpc);
307	err |= __get_user(tnpc, &sf->regs.tnpc);
308	if (test_thread_flag(TIF_32BIT)) {
309		tpc &= 0xffffffff;
310		tnpc &= 0xffffffff;
311	}
312	err |= ((tpc | tnpc) & 3);
313
314	/* 2. Restore the state */
315	err |= __get_user(regs->y, &sf->regs.y);
316	err |= __get_user(tstate, &sf->regs.tstate);
317	err |= copy_from_user(regs->u_regs, sf->regs.u_regs, sizeof(regs->u_regs));
318
319	/* User can only change condition codes and %asi in %tstate. */
320	regs->tstate &= ~(TSTATE_ASI | TSTATE_ICC | TSTATE_XCC);
321	regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));
322
323	err |= __get_user(fpu_save, &sf->fpu_save);
324	if (fpu_save)
325		err |= restore_fpu_state(regs, &sf->fpu_state);
326
327	err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
328	err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf);
329
330	if (err)
331		goto segv;
332
333	regs->tpc = tpc;
334	regs->tnpc = tnpc;
335
336	/* Prevent syscall restart.  */
337	pt_regs_clear_syscall(regs);
338
339	sigdelsetmask(&set, ~_BLOCKABLE);
340	spin_lock_irq(&current->sighand->siglock);
341	current->blocked = set;
342	recalc_sigpending();
343	spin_unlock_irq(&current->sighand->siglock);
344	return;
345segv:
346	force_sig(SIGSEGV, current);
347}
348
349/* Checks if the fp is valid */
350static int invalid_frame_pointer(void __user *fp, int fplen)
351{
352	if (((unsigned long) fp) & 15)
353		return 1;
354	return 0;
355}
356
357static inline int
358save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
359{
360	unsigned long *fpregs = current_thread_info()->fpregs;
361	unsigned long fprs;
362	int err = 0;
363
364	fprs = current_thread_info()->fpsaved[0];
365	if (fprs & FPRS_DL)
366		err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
367				    (sizeof(unsigned int) * 32));
368	if (fprs & FPRS_DU)
369		err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
370				    (sizeof(unsigned int) * 32));
371	err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
372	err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
373	err |= __put_user(fprs, &fpu->si_fprs);
374
375	return err;
376}
377
378static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
379{
380	unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
381
382	/*
383	 * If we are on the alternate signal stack and would overflow it, don't.
384	 * Return an always-bogus address instead so we will die with SIGSEGV.
385	 */
386	if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
387		return (void __user *) -1L;
388
389	/* This is the X/Open sanctioned signal stack switching.  */
390	if (ka->sa.sa_flags & SA_ONSTACK) {
391		if (sas_ss_flags(sp) == 0)
392			sp = current->sas_ss_sp + current->sas_ss_size;
393	}
394
395	sp -= framesize;
396
397	/* Always align the stack frame.  This handles two cases.  First,
398	 * sigaltstack need not be mindful of platform specific stack
399	 * alignment.  Second, if we took this signal because the stack
400	 * is not aligned properly, we'd like to take the signal cleanly
401	 * and report that.
402	 */
403	sp &= ~15UL;
404
405	return (void __user *) sp;
406}
407
408static inline int
409setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
410	       int signo, sigset_t *oldset, siginfo_t *info)
411{
412	struct rt_signal_frame __user *sf;
413	int sigframe_size, err;
414
415	/* 1. Make sure everything is clean */
416	synchronize_user_stack();
417	save_and_clear_fpu();
418
419	sigframe_size = sizeof(struct rt_signal_frame);
420	if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
421		sigframe_size -= sizeof(__siginfo_fpu_t);
422
423	sf = (struct rt_signal_frame __user *)
424		get_sigframe(ka, regs, sigframe_size);
425
426	if (invalid_frame_pointer (sf, sigframe_size))
427		goto sigill;
428
429	if (get_thread_wsaved() != 0)
430		goto sigill;
431
432	/* 2. Save the current process state */
433	err = copy_to_user(&sf->regs, regs, sizeof (*regs));
434
435	if (current_thread_info()->fpsaved[0] & FPRS_FEF) {
436		err |= save_fpu_state(regs, &sf->fpu_state);
437		err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
438	} else {
439		err |= __put_user(0, &sf->fpu_save);
440	}
441
442	/* Setup sigaltstack */
443	err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
444	err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
445	err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
446
447	err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t));
448
449	err |= copy_in_user((u64 __user *)sf,
450			    (u64 __user *)(regs->u_regs[UREG_FP]+STACK_BIAS),
451			    sizeof(struct reg_window));
452
453	if (info)
454		err |= copy_siginfo_to_user(&sf->info, info);
455	else {
456		err |= __put_user(signo, &sf->info.si_signo);
457		err |= __put_user(SI_NOINFO, &sf->info.si_code);
458	}
459	if (err)
460		goto sigsegv;
461
462	/* 3. signal handler back-trampoline and parameters */
463	regs->u_regs[UREG_FP] = ((unsigned long) sf) - STACK_BIAS;
464	regs->u_regs[UREG_I0] = signo;
465	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
466
467	/* The sigcontext is passed in this way because of how it
468	 * is defined in GLIBC's /usr/include/bits/sigcontext.h
469	 * for sparc64.  It includes the 128 bytes of siginfo_t.
470	 */
471	regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
472
473	/* 5. signal handler */
474	regs->tpc = (unsigned long) ka->sa.sa_handler;
475	regs->tnpc = (regs->tpc + 4);
476	if (test_thread_flag(TIF_32BIT)) {
477		regs->tpc &= 0xffffffff;
478		regs->tnpc &= 0xffffffff;
479	}
480	/* 4. return to kernel instructions */
481	regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
482	return 0;
483
484sigill:
485	do_exit(SIGILL);
486	return -EINVAL;
487
488sigsegv:
489	force_sigsegv(signo, current);
490	return -EFAULT;
491}
492
493static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
494				siginfo_t *info,
495				sigset_t *oldset, struct pt_regs *regs)
496{
497	int err;
498
499	err = setup_rt_frame(ka, regs, signr, oldset,
500			     (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
501	if (err)
502		return err;
503	spin_lock_irq(&current->sighand->siglock);
504	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
505	if (!(ka->sa.sa_flags & SA_NOMASK))
506		sigaddset(&current->blocked,signr);
507	recalc_sigpending();
508	spin_unlock_irq(&current->sighand->siglock);
509
510	tracehook_signal_handler(signr, info, ka, regs, 0);
511
512	return 0;
513}
514
515static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
516				   struct sigaction *sa)
517{
518	switch (regs->u_regs[UREG_I0]) {
519	case ERESTART_RESTARTBLOCK:
520	case ERESTARTNOHAND:
521	no_system_call_restart:
522		regs->u_regs[UREG_I0] = EINTR;
523		regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
524		break;
525	case ERESTARTSYS:
526		if (!(sa->sa_flags & SA_RESTART))
527			goto no_system_call_restart;
528		/* fallthrough */
529	case ERESTARTNOINTR:
530		regs->u_regs[UREG_I0] = orig_i0;
531		regs->tpc -= 4;
532		regs->tnpc -= 4;
533	}
534}
535
536/* Note that 'init' is a special process: it doesn't get signals it doesn't
537 * want to handle. Thus you cannot kill init even with a SIGKILL even by
538 * mistake.
539 */
540static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
541{
542	struct k_sigaction ka;
543	int restart_syscall;
544	sigset_t *oldset;
545	siginfo_t info;
546	int signr;
547
548	if (pt_regs_is_syscall(regs) &&
549	    (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
550		restart_syscall = 1;
551	} else
552		restart_syscall = 0;
553
554	if (current_thread_info()->status & TS_RESTORE_SIGMASK)
555		oldset = &current->saved_sigmask;
556	else
557		oldset = &current->blocked;
558
559#ifdef CONFIG_COMPAT
560	if (test_thread_flag(TIF_32BIT)) {
561		extern void do_signal32(sigset_t *, struct pt_regs *,
562					int restart_syscall,
563					unsigned long orig_i0);
564		do_signal32(oldset, regs, restart_syscall, orig_i0);
565		return;
566	}
567#endif
568
569	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
570
571	/* If the debugger messes with the program counter, it clears
572	 * the software "in syscall" bit, directing us to not perform
573	 * a syscall restart.
574	 */
575	if (restart_syscall && !pt_regs_is_syscall(regs))
576		restart_syscall = 0;
577
578	if (signr > 0) {
579		if (restart_syscall)
580			syscall_restart(orig_i0, regs, &ka.sa);
581		if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
582			/* A signal was successfully delivered; the saved
583			 * sigmask will have been stored in the signal frame,
584			 * and will be restored by sigreturn, so we can simply
585			 * clear the TS_RESTORE_SIGMASK flag.
586			 */
587			current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
588		}
589		return;
590	}
591	if (restart_syscall &&
592	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
593	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
594	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
595		/* replay the system call when we are done */
596		regs->u_regs[UREG_I0] = orig_i0;
597		regs->tpc -= 4;
598		regs->tnpc -= 4;
599		pt_regs_clear_syscall(regs);
600	}
601	if (restart_syscall &&
602	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
603		regs->u_regs[UREG_G1] = __NR_restart_syscall;
604		regs->tpc -= 4;
605		regs->tnpc -= 4;
606		pt_regs_clear_syscall(regs);
607	}
608
609	/* If there's no signal to deliver, we just put the saved sigmask
610	 * back
611	 */
612	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
613		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
614		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
615	}
616}
617
618void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags)
619{
620	if (thread_info_flags & _TIF_SIGPENDING)
621		do_signal(regs, orig_i0);
622	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
623		clear_thread_flag(TIF_NOTIFY_RESUME);
624		tracehook_notify_resume(regs);
625		if (current->replacement_session_keyring)
626			key_replace_session_keyring();
627	}
628}
629