aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/signal_64.c
diff options
context:
space:
mode:
authorSam Ravnborg <sam@ravnborg.org>2008-12-03 06:11:52 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-04 12:17:21 -0500
commita88b5ba8bd8ac18aad65ee6c6a254e2e74876db3 (patch)
treeeb3d0ffaf53c3f7ec6083752c2097cecd1cb892a /arch/sparc/kernel/signal_64.c
parentd670bd4f803c8b646acd20f3ba21e65458293faf (diff)
sparc,sparc64: unify kernel/
o Move all files from sparc64/kernel/ to sparc/kernel - rename as appropriate o Update sparc/Makefile to the changes o Update sparc/kernel/Makefile to include the sparc64 files NOTE: This commit changes link order on sparc64! Link order had to change for either of sparc32 and sparc64. And assuming sparc64 see more testing than sparc32 change link order on sparc64 where issues will be caught faster. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/signal_64.c')
-rw-r--r--arch/sparc/kernel/signal_64.c617
1 files changed, 617 insertions, 0 deletions
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
new file mode 100644
index 000000000000..ec82d76dc6f2
--- /dev/null
+++ b/arch/sparc/kernel/signal_64.c
@@ -0,0 +1,617 @@
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#if 1
156 fenab = 0; /* IMO get_context is like any other system call, thus modifies FPU state -jj */
157#else
158 fenab = (current_thread_info()->fpsaved[0] & FPRS_FEF);
159#endif
160
161 mcp = &ucp->uc_mcontext;
162 grp = &mcp->mc_gregs;
163
164 /* Skip over the trap instruction, first. */
165 if (test_thread_flag(TIF_32BIT)) {
166 regs->tpc = (regs->tnpc & 0xffffffff);
167 regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
168 } else {
169 regs->tpc = regs->tnpc;
170 regs->tnpc += 4;
171 }
172 err = 0;
173 if (_NSIG_WORDS == 1)
174 err |= __put_user(current->blocked.sig[0],
175 (unsigned long __user *)&ucp->uc_sigmask);
176 else
177 err |= __copy_to_user(&ucp->uc_sigmask, &current->blocked,
178 sizeof(sigset_t));
179
180 err |= __put_user(regs->tstate, &((*grp)[MC_TSTATE]));
181 err |= __put_user(regs->tpc, &((*grp)[MC_PC]));
182 err |= __put_user(regs->tnpc, &((*grp)[MC_NPC]));
183 err |= __put_user(regs->y, &((*grp)[MC_Y]));
184 err |= __put_user(regs->u_regs[UREG_G1], &((*grp)[MC_G1]));
185 err |= __put_user(regs->u_regs[UREG_G2], &((*grp)[MC_G2]));
186 err |= __put_user(regs->u_regs[UREG_G3], &((*grp)[MC_G3]));
187 err |= __put_user(regs->u_regs[UREG_G4], &((*grp)[MC_G4]));
188 err |= __put_user(regs->u_regs[UREG_G5], &((*grp)[MC_G5]));
189 err |= __put_user(regs->u_regs[UREG_G6], &((*grp)[MC_G6]));
190 err |= __put_user(regs->u_regs[UREG_G7], &((*grp)[MC_G7]));
191 err |= __put_user(regs->u_regs[UREG_I0], &((*grp)[MC_O0]));
192 err |= __put_user(regs->u_regs[UREG_I1], &((*grp)[MC_O1]));
193 err |= __put_user(regs->u_regs[UREG_I2], &((*grp)[MC_O2]));
194 err |= __put_user(regs->u_regs[UREG_I3], &((*grp)[MC_O3]));
195 err |= __put_user(regs->u_regs[UREG_I4], &((*grp)[MC_O4]));
196 err |= __put_user(regs->u_regs[UREG_I5], &((*grp)[MC_O5]));
197 err |= __put_user(regs->u_regs[UREG_I6], &((*grp)[MC_O6]));
198 err |= __put_user(regs->u_regs[UREG_I7], &((*grp)[MC_O7]));
199
200 err |= __get_user(fp,
201 (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[6])));
202 err |= __get_user(i7,
203 (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
204 err |= __put_user(fp, &(mcp->mc_fp));
205 err |= __put_user(i7, &(mcp->mc_i7));
206
207 err |= __put_user(fenab, &(mcp->mc_fpregs.mcfpu_enab));
208 if (fenab) {
209 unsigned long *fpregs = current_thread_info()->fpregs;
210 unsigned long fprs;
211
212 fprs = current_thread_info()->fpsaved[0];
213 if (fprs & FPRS_DL)
214 err |= copy_to_user(&(mcp->mc_fpregs.mcfpu_fregs), fpregs,
215 (sizeof(unsigned int) * 32));
216 if (fprs & FPRS_DU)
217 err |= copy_to_user(
218 ((unsigned long __user *)&(mcp->mc_fpregs.mcfpu_fregs))+16, fpregs+16,
219 (sizeof(unsigned int) * 32));
220 err |= __put_user(current_thread_info()->xfsr[0], &(mcp->mc_fpregs.mcfpu_fsr));
221 err |= __put_user(current_thread_info()->gsr[0], &(mcp->mc_fpregs.mcfpu_gsr));
222 err |= __put_user(fprs, &(mcp->mc_fpregs.mcfpu_fprs));
223 }
224 if (err)
225 goto do_sigsegv;
226
227 return;
228do_sigsegv:
229 force_sig(SIGSEGV, current);
230}
231
232struct rt_signal_frame {
233 struct sparc_stackf ss;
234 siginfo_t info;
235 struct pt_regs regs;
236 __siginfo_fpu_t __user *fpu_save;
237 stack_t stack;
238 sigset_t mask;
239 __siginfo_fpu_t fpu_state;
240};
241
242static long _sigpause_common(old_sigset_t set)
243{
244 set &= _BLOCKABLE;
245 spin_lock_irq(&current->sighand->siglock);
246 current->saved_sigmask = current->blocked;
247 siginitset(&current->blocked, set);
248 recalc_sigpending();
249 spin_unlock_irq(&current->sighand->siglock);
250
251 current->state = TASK_INTERRUPTIBLE;
252 schedule();
253
254 set_restore_sigmask();
255
256 return -ERESTARTNOHAND;
257}
258
259asmlinkage long sys_sigpause(unsigned int set)
260{
261 return _sigpause_common(set);
262}
263
264asmlinkage long sys_sigsuspend(old_sigset_t set)
265{
266 return _sigpause_common(set);
267}
268
269static inline int
270restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
271{
272 unsigned long *fpregs = current_thread_info()->fpregs;
273 unsigned long fprs;
274 int err;
275
276 err = __get_user(fprs, &fpu->si_fprs);
277 fprs_write(0);
278 regs->tstate &= ~TSTATE_PEF;
279 if (fprs & FPRS_DL)
280 err |= copy_from_user(fpregs, &fpu->si_float_regs[0],
281 (sizeof(unsigned int) * 32));
282 if (fprs & FPRS_DU)
283 err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32],
284 (sizeof(unsigned int) * 32));
285 err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
286 err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
287 current_thread_info()->fpsaved[0] |= fprs;
288 return err;
289}
290
291void do_rt_sigreturn(struct pt_regs *regs)
292{
293 struct rt_signal_frame __user *sf;
294 unsigned long tpc, tnpc, tstate;
295 __siginfo_fpu_t __user *fpu_save;
296 sigset_t set;
297 int err;
298
299 /* Always make any pending restarted system calls return -EINTR */
300 current_thread_info()->restart_block.fn = do_no_restart_syscall;
301
302 synchronize_user_stack ();
303 sf = (struct rt_signal_frame __user *)
304 (regs->u_regs [UREG_FP] + STACK_BIAS);
305
306 /* 1. Make sure we are not getting garbage from the user */
307 if (((unsigned long) sf) & 3)
308 goto segv;
309
310 err = get_user(tpc, &sf->regs.tpc);
311 err |= __get_user(tnpc, &sf->regs.tnpc);
312 if (test_thread_flag(TIF_32BIT)) {
313 tpc &= 0xffffffff;
314 tnpc &= 0xffffffff;
315 }
316 err |= ((tpc | tnpc) & 3);
317
318 /* 2. Restore the state */
319 err |= __get_user(regs->y, &sf->regs.y);
320 err |= __get_user(tstate, &sf->regs.tstate);
321 err |= copy_from_user(regs->u_regs, sf->regs.u_regs, sizeof(regs->u_regs));
322
323 /* User can only change condition codes and %asi in %tstate. */
324 regs->tstate &= ~(TSTATE_ASI | TSTATE_ICC | TSTATE_XCC);
325 regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));
326
327 err |= __get_user(fpu_save, &sf->fpu_save);
328 if (fpu_save)
329 err |= restore_fpu_state(regs, &sf->fpu_state);
330
331 err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
332 err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf);
333
334 if (err)
335 goto segv;
336
337 regs->tpc = tpc;
338 regs->tnpc = tnpc;
339
340 /* Prevent syscall restart. */
341 pt_regs_clear_syscall(regs);
342
343 sigdelsetmask(&set, ~_BLOCKABLE);
344 spin_lock_irq(&current->sighand->siglock);
345 current->blocked = set;
346 recalc_sigpending();
347 spin_unlock_irq(&current->sighand->siglock);
348 return;
349segv:
350 force_sig(SIGSEGV, current);
351}
352
353/* Checks if the fp is valid */
354static int invalid_frame_pointer(void __user *fp, int fplen)
355{
356 if (((unsigned long) fp) & 7)
357 return 1;
358 return 0;
359}
360
361static inline int
362save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
363{
364 unsigned long *fpregs = current_thread_info()->fpregs;
365 unsigned long fprs;
366 int err = 0;
367
368 fprs = current_thread_info()->fpsaved[0];
369 if (fprs & FPRS_DL)
370 err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
371 (sizeof(unsigned int) * 32));
372 if (fprs & FPRS_DU)
373 err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
374 (sizeof(unsigned int) * 32));
375 err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
376 err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
377 err |= __put_user(fprs, &fpu->si_fprs);
378
379 return err;
380}
381
382static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
383{
384 unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
385
386 /*
387 * If we are on the alternate signal stack and would overflow it, don't.
388 * Return an always-bogus address instead so we will die with SIGSEGV.
389 */
390 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
391 return (void __user *) -1L;
392
393 /* This is the X/Open sanctioned signal stack switching. */
394 if (ka->sa.sa_flags & SA_ONSTACK) {
395 if (sas_ss_flags(sp) == 0)
396 sp = current->sas_ss_sp + current->sas_ss_size;
397 }
398
399 /* Always align the stack frame. This handles two cases. First,
400 * sigaltstack need not be mindful of platform specific stack
401 * alignment. Second, if we took this signal because the stack
402 * is not aligned properly, we'd like to take the signal cleanly
403 * and report that.
404 */
405 sp &= ~7UL;
406
407 return (void __user *)(sp - framesize);
408}
409
410static inline void
411setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
412 int signo, sigset_t *oldset, siginfo_t *info)
413{
414 struct rt_signal_frame __user *sf;
415 int sigframe_size, err;
416
417 /* 1. Make sure everything is clean */
418 synchronize_user_stack();
419 save_and_clear_fpu();
420
421 sigframe_size = sizeof(struct rt_signal_frame);
422 if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
423 sigframe_size -= sizeof(__siginfo_fpu_t);
424
425 sf = (struct rt_signal_frame __user *)
426 get_sigframe(ka, regs, sigframe_size);
427
428 if (invalid_frame_pointer (sf, sigframe_size))
429 goto sigill;
430
431 if (get_thread_wsaved() != 0)
432 goto sigill;
433
434 /* 2. Save the current process state */
435 err = copy_to_user(&sf->regs, regs, sizeof (*regs));
436
437 if (current_thread_info()->fpsaved[0] & FPRS_FEF) {
438 err |= save_fpu_state(regs, &sf->fpu_state);
439 err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
440 } else {
441 err |= __put_user(0, &sf->fpu_save);
442 }
443
444 /* Setup sigaltstack */
445 err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
446 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
447 err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
448
449 err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t));
450
451 err |= copy_in_user((u64 __user *)sf,
452 (u64 __user *)(regs->u_regs[UREG_FP]+STACK_BIAS),
453 sizeof(struct reg_window));
454
455 if (info)
456 err |= copy_siginfo_to_user(&sf->info, info);
457 else {
458 err |= __put_user(signo, &sf->info.si_signo);
459 err |= __put_user(SI_NOINFO, &sf->info.si_code);
460 }
461 if (err)
462 goto sigsegv;
463
464 /* 3. signal handler back-trampoline and parameters */
465 regs->u_regs[UREG_FP] = ((unsigned long) sf) - STACK_BIAS;
466 regs->u_regs[UREG_I0] = signo;
467 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
468
469 /* The sigcontext is passed in this way because of how it
470 * is defined in GLIBC's /usr/include/bits/sigcontext.h
471 * for sparc64. It includes the 128 bytes of siginfo_t.
472 */
473 regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
474
475 /* 5. signal handler */
476 regs->tpc = (unsigned long) ka->sa.sa_handler;
477 regs->tnpc = (regs->tpc + 4);
478 if (test_thread_flag(TIF_32BIT)) {
479 regs->tpc &= 0xffffffff;
480 regs->tnpc &= 0xffffffff;
481 }
482 /* 4. return to kernel instructions */
483 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
484 return;
485
486sigill:
487 do_exit(SIGILL);
488sigsegv:
489 force_sigsegv(signo, current);
490}
491
492static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
493 siginfo_t *info,
494 sigset_t *oldset, struct pt_regs *regs)
495{
496 setup_rt_frame(ka, regs, signr, oldset,
497 (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
498 spin_lock_irq(&current->sighand->siglock);
499 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
500 if (!(ka->sa.sa_flags & SA_NOMASK))
501 sigaddset(&current->blocked,signr);
502 recalc_sigpending();
503 spin_unlock_irq(&current->sighand->siglock);
504}
505
506static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
507 struct sigaction *sa)
508{
509 switch (regs->u_regs[UREG_I0]) {
510 case ERESTART_RESTARTBLOCK:
511 case ERESTARTNOHAND:
512 no_system_call_restart:
513 regs->u_regs[UREG_I0] = EINTR;
514 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
515 break;
516 case ERESTARTSYS:
517 if (!(sa->sa_flags & SA_RESTART))
518 goto no_system_call_restart;
519 /* fallthrough */
520 case ERESTARTNOINTR:
521 regs->u_regs[UREG_I0] = orig_i0;
522 regs->tpc -= 4;
523 regs->tnpc -= 4;
524 }
525}
526
527/* Note that 'init' is a special process: it doesn't get signals it doesn't
528 * want to handle. Thus you cannot kill init even with a SIGKILL even by
529 * mistake.
530 */
531static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
532{
533 struct k_sigaction ka;
534 int restart_syscall;
535 sigset_t *oldset;
536 siginfo_t info;
537 int signr;
538
539 if (pt_regs_is_syscall(regs) &&
540 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
541 restart_syscall = 1;
542 } else
543 restart_syscall = 0;
544
545 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
546 oldset = &current->saved_sigmask;
547 else
548 oldset = &current->blocked;
549
550#ifdef CONFIG_COMPAT
551 if (test_thread_flag(TIF_32BIT)) {
552 extern void do_signal32(sigset_t *, struct pt_regs *,
553 int restart_syscall,
554 unsigned long orig_i0);
555 do_signal32(oldset, regs, restart_syscall, orig_i0);
556 return;
557 }
558#endif
559
560 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
561
562 /* If the debugger messes with the program counter, it clears
563 * the software "in syscall" bit, directing us to not perform
564 * a syscall restart.
565 */
566 if (restart_syscall && !pt_regs_is_syscall(regs))
567 restart_syscall = 0;
568
569 if (signr > 0) {
570 if (restart_syscall)
571 syscall_restart(orig_i0, regs, &ka.sa);
572 handle_signal(signr, &ka, &info, oldset, regs);
573
574 /* A signal was successfully delivered; the saved
575 * sigmask will have been stored in the signal frame,
576 * and will be restored by sigreturn, so we can simply
577 * clear the TS_RESTORE_SIGMASK flag.
578 */
579 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
580
581 tracehook_signal_handler(signr, &info, &ka, regs, 0);
582 return;
583 }
584 if (restart_syscall &&
585 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
586 regs->u_regs[UREG_I0] == ERESTARTSYS ||
587 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
588 /* replay the system call when we are done */
589 regs->u_regs[UREG_I0] = orig_i0;
590 regs->tpc -= 4;
591 regs->tnpc -= 4;
592 }
593 if (restart_syscall &&
594 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
595 regs->u_regs[UREG_G1] = __NR_restart_syscall;
596 regs->tpc -= 4;
597 regs->tnpc -= 4;
598 }
599
600 /* If there's no signal to deliver, we just put the saved sigmask
601 * back
602 */
603 if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
604 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
605 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
606 }
607}
608
609void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags)
610{
611 if (thread_info_flags & _TIF_SIGPENDING)
612 do_signal(regs, orig_i0);
613 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
614 clear_thread_flag(TIF_NOTIFY_RESUME);
615 tracehook_notify_resume(regs);
616 }
617}