allow coexistance of N build and AC build.
[tomato.git] / release / src-rt-6.x / linux / linux-2.6 / arch / sparc64 / kernel / signal32.c
blob8c1c121330fba5b57687e5e3deca87c9d39ed1d7
1 /* $Id: signal32.c,v 1.74 2002/02/09 19:49:30 davem Exp $
2 * arch/sparc64/kernel/signal32.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 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
9 */
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/tty.h>
20 #include <linux/binfmts.h>
21 #include <linux/compat.h>
22 #include <linux/bitops.h>
24 #include <asm/uaccess.h>
25 #include <asm/ptrace.h>
26 #include <asm/svr4.h>
27 #include <asm/pgtable.h>
28 #include <asm/psrcompat.h>
29 #include <asm/fpumacro.h>
30 #include <asm/visasm.h>
31 #include <asm/compat_signal.h>
33 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35 /* Signal frames: the original one (compatible with SunOS):
37 * Set up a signal frame... Make the stack look the way SunOS
38 * expects it to look which is basically:
40 * ---------------------------------- <-- %sp at signal time
41 * Struct sigcontext
42 * Signal address
43 * Ptr to sigcontext area above
44 * Signal code
45 * The signal number itself
46 * One register window
47 * ---------------------------------- <-- New %sp
49 struct signal_sframe32 {
50 struct reg_window32 sig_window;
51 int sig_num;
52 int sig_code;
53 /* struct sigcontext32 * */ u32 sig_scptr;
54 int sig_address;
55 struct sigcontext32 sig_context;
56 unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
59 /* This magic should be in g_upper[0] for all upper parts
60 * to be valid.
62 #define SIGINFO_EXTRA_V8PLUS_MAGIC 0x130e269
63 typedef struct {
64 unsigned int g_upper[8];
65 unsigned int o_upper[8];
66 unsigned int asi;
67 } siginfo_extra_v8plus_t;
69 /*
70 * And the new one, intended to be used for Linux applications only
71 * (we have enough in there to work with clone).
72 * All the interesting bits are in the info field.
74 struct new_signal_frame32 {
75 struct sparc_stackf32 ss;
76 __siginfo32_t info;
77 /* __siginfo_fpu32_t * */ u32 fpu_save;
78 unsigned int insns[2];
79 unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
80 unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
81 /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
82 siginfo_extra_v8plus_t v8plus;
83 __siginfo_fpu_t fpu_state;
86 typedef struct compat_siginfo{
87 int si_signo;
88 int si_errno;
89 int si_code;
91 union {
92 int _pad[SI_PAD_SIZE32];
94 /* kill() */
95 struct {
96 compat_pid_t _pid; /* sender's pid */
97 unsigned int _uid; /* sender's uid */
98 } _kill;
100 /* POSIX.1b timers */
101 struct {
102 compat_timer_t _tid; /* timer id */
103 int _overrun; /* overrun count */
104 compat_sigval_t _sigval; /* same as below */
105 int _sys_private; /* not to be passed to user */
106 } _timer;
108 /* POSIX.1b signals */
109 struct {
110 compat_pid_t _pid; /* sender's pid */
111 unsigned int _uid; /* sender's uid */
112 compat_sigval_t _sigval;
113 } _rt;
115 /* SIGCHLD */
116 struct {
117 compat_pid_t _pid; /* which child */
118 unsigned int _uid; /* sender's uid */
119 int _status; /* exit code */
120 compat_clock_t _utime;
121 compat_clock_t _stime;
122 } _sigchld;
124 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
125 struct {
126 u32 _addr; /* faulting insn/memory ref. */
127 int _trapno;
128 } _sigfault;
130 /* SIGPOLL */
131 struct {
132 int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
133 int _fd;
134 } _sigpoll;
135 } _sifields;
136 }compat_siginfo_t;
138 struct rt_signal_frame32 {
139 struct sparc_stackf32 ss;
140 compat_siginfo_t info;
141 struct pt_regs32 regs;
142 compat_sigset_t mask;
143 /* __siginfo_fpu32_t * */ u32 fpu_save;
144 unsigned int insns[2];
145 stack_t32 stack;
146 unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
147 /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
148 siginfo_extra_v8plus_t v8plus;
149 __siginfo_fpu_t fpu_state;
152 /* Align macros */
153 #define SF_ALIGNEDSZ (((sizeof(struct signal_sframe32) + 7) & (~7)))
154 #define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame32) + 7) & (~7)))
155 #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
157 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
159 int err;
161 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
162 return -EFAULT;
164 /* If you change siginfo_t structure, please be sure
165 this code is fixed accordingly.
166 It should never copy any pad contained in the structure
167 to avoid security leaks, but must copy the generic
168 3 ints plus the relevant union member.
169 This routine must convert siginfo from 64bit to 32bit as well
170 at the same time. */
171 err = __put_user(from->si_signo, &to->si_signo);
172 err |= __put_user(from->si_errno, &to->si_errno);
173 err |= __put_user((short)from->si_code, &to->si_code);
174 if (from->si_code < 0)
175 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
176 else {
177 switch (from->si_code >> 16) {
178 case __SI_TIMER >> 16:
179 err |= __put_user(from->si_tid, &to->si_tid);
180 err |= __put_user(from->si_overrun, &to->si_overrun);
181 err |= __put_user(from->si_int, &to->si_int);
182 break;
183 case __SI_CHLD >> 16:
184 err |= __put_user(from->si_utime, &to->si_utime);
185 err |= __put_user(from->si_stime, &to->si_stime);
186 err |= __put_user(from->si_status, &to->si_status);
187 default:
188 err |= __put_user(from->si_pid, &to->si_pid);
189 err |= __put_user(from->si_uid, &to->si_uid);
190 break;
191 case __SI_FAULT >> 16:
192 err |= __put_user(from->si_trapno, &to->si_trapno);
193 err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
194 break;
195 case __SI_POLL >> 16:
196 err |= __put_user(from->si_band, &to->si_band);
197 err |= __put_user(from->si_fd, &to->si_fd);
198 break;
199 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
200 case __SI_MESGQ >> 16:
201 err |= __put_user(from->si_pid, &to->si_pid);
202 err |= __put_user(from->si_uid, &to->si_uid);
203 err |= __put_user(from->si_int, &to->si_int);
204 break;
207 return err;
210 /* CAUTION: This is just a very minimalist implementation for the
211 * sake of compat_sys_rt_sigqueueinfo()
213 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
215 if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
216 return -EFAULT;
218 if (copy_from_user(to, from, 3*sizeof(int)) ||
219 copy_from_user(to->_sifields._pad, from->_sifields._pad,
220 SI_PAD_SIZE))
221 return -EFAULT;
223 return 0;
226 static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
228 unsigned long *fpregs = current_thread_info()->fpregs;
229 unsigned long fprs;
230 int err;
232 err = __get_user(fprs, &fpu->si_fprs);
233 fprs_write(0);
234 regs->tstate &= ~TSTATE_PEF;
235 if (fprs & FPRS_DL)
236 err |= copy_from_user(fpregs, &fpu->si_float_regs[0], (sizeof(unsigned int) * 32));
237 if (fprs & FPRS_DU)
238 err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], (sizeof(unsigned int) * 32));
239 err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
240 err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
241 current_thread_info()->fpsaved[0] |= fprs;
242 return err;
245 void do_new_sigreturn32(struct pt_regs *regs)
247 struct new_signal_frame32 __user *sf;
248 unsigned int psr;
249 unsigned pc, npc, fpu_save;
250 sigset_t set;
251 unsigned seta[_COMPAT_NSIG_WORDS];
252 int err, i;
254 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
255 sf = (struct new_signal_frame32 __user *) regs->u_regs[UREG_FP];
257 /* 1. Make sure we are not getting garbage from the user */
258 if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
259 (((unsigned long) sf) & 3))
260 goto segv;
262 get_user(pc, &sf->info.si_regs.pc);
263 __get_user(npc, &sf->info.si_regs.npc);
265 if ((pc | npc) & 3)
266 goto segv;
268 if (test_thread_flag(TIF_32BIT)) {
269 pc &= 0xffffffff;
270 npc &= 0xffffffff;
272 regs->tpc = pc;
273 regs->tnpc = npc;
275 /* 2. Restore the state */
276 err = __get_user(regs->y, &sf->info.si_regs.y);
277 err |= __get_user(psr, &sf->info.si_regs.psr);
279 for (i = UREG_G1; i <= UREG_I7; i++)
280 err |= __get_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
281 if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
282 err |= __get_user(i, &sf->v8plus.g_upper[0]);
283 if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
284 unsigned long asi;
286 for (i = UREG_G1; i <= UREG_I7; i++)
287 err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
288 err |= __get_user(asi, &sf->v8plus.asi);
289 regs->tstate &= ~TSTATE_ASI;
290 regs->tstate |= ((asi & 0xffUL) << 24UL);
294 /* User can only change condition codes in %tstate. */
295 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
296 regs->tstate |= psr_to_tstate_icc(psr);
298 err |= __get_user(fpu_save, &sf->fpu_save);
299 if (fpu_save)
300 err |= restore_fpu_state32(regs, &sf->fpu_state);
301 err |= __get_user(seta[0], &sf->info.si_mask);
302 err |= copy_from_user(seta+1, &sf->extramask,
303 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
304 if (err)
305 goto segv;
306 switch (_NSIG_WORDS) {
307 case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32);
308 case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32);
309 case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
310 case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
312 sigdelsetmask(&set, ~_BLOCKABLE);
313 spin_lock_irq(&current->sighand->siglock);
314 current->blocked = set;
315 recalc_sigpending();
316 spin_unlock_irq(&current->sighand->siglock);
317 return;
319 segv:
320 force_sig(SIGSEGV, current);
323 asmlinkage void do_sigreturn32(struct pt_regs *regs)
325 struct sigcontext32 __user *scptr;
326 unsigned int pc, npc, psr;
327 sigset_t set;
328 unsigned int seta[_COMPAT_NSIG_WORDS];
329 int err;
331 /* Always make any pending restarted system calls return -EINTR */
332 current_thread_info()->restart_block.fn = do_no_restart_syscall;
334 synchronize_user_stack();
335 if (test_thread_flag(TIF_NEWSIGNALS)) {
336 do_new_sigreturn32(regs);
337 return;
340 scptr = (struct sigcontext32 __user *)
341 (regs->u_regs[UREG_I0] & 0x00000000ffffffffUL);
342 /* Check sanity of the user arg. */
343 if (!access_ok(VERIFY_READ, scptr, sizeof(struct sigcontext32)) ||
344 (((unsigned long) scptr) & 3))
345 goto segv;
347 err = __get_user(pc, &scptr->sigc_pc);
348 err |= __get_user(npc, &scptr->sigc_npc);
350 if ((pc | npc) & 3)
351 goto segv; /* Nice try. */
353 err |= __get_user(seta[0], &scptr->sigc_mask);
354 /* Note that scptr + 1 points to extramask */
355 err |= copy_from_user(seta+1, scptr + 1,
356 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
357 if (err)
358 goto segv;
359 switch (_NSIG_WORDS) {
360 case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32);
361 case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32);
362 case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
363 case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
365 sigdelsetmask(&set, ~_BLOCKABLE);
366 spin_lock_irq(&current->sighand->siglock);
367 current->blocked = set;
368 recalc_sigpending();
369 spin_unlock_irq(&current->sighand->siglock);
371 if (test_thread_flag(TIF_32BIT)) {
372 pc &= 0xffffffff;
373 npc &= 0xffffffff;
375 regs->tpc = pc;
376 regs->tnpc = npc;
377 err = __get_user(regs->u_regs[UREG_FP], &scptr->sigc_sp);
378 err |= __get_user(regs->u_regs[UREG_I0], &scptr->sigc_o0);
379 err |= __get_user(regs->u_regs[UREG_G1], &scptr->sigc_g1);
381 /* User can only change condition codes in %tstate. */
382 err |= __get_user(psr, &scptr->sigc_psr);
383 if (err)
384 goto segv;
385 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
386 regs->tstate |= psr_to_tstate_icc(psr);
387 return;
389 segv:
390 force_sig(SIGSEGV, current);
393 asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
395 struct rt_signal_frame32 __user *sf;
396 unsigned int psr, pc, npc, fpu_save, u_ss_sp;
397 mm_segment_t old_fs;
398 sigset_t set;
399 compat_sigset_t seta;
400 stack_t st;
401 int err, i;
403 /* Always make any pending restarted system calls return -EINTR */
404 current_thread_info()->restart_block.fn = do_no_restart_syscall;
406 synchronize_user_stack();
407 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
408 sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
410 /* 1. Make sure we are not getting garbage from the user */
411 if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
412 (((unsigned long) sf) & 3))
413 goto segv;
415 get_user(pc, &sf->regs.pc);
416 __get_user(npc, &sf->regs.npc);
418 if ((pc | npc) & 3)
419 goto segv;
421 if (test_thread_flag(TIF_32BIT)) {
422 pc &= 0xffffffff;
423 npc &= 0xffffffff;
425 regs->tpc = pc;
426 regs->tnpc = npc;
428 /* 2. Restore the state */
429 err = __get_user(regs->y, &sf->regs.y);
430 err |= __get_user(psr, &sf->regs.psr);
432 for (i = UREG_G1; i <= UREG_I7; i++)
433 err |= __get_user(regs->u_regs[i], &sf->regs.u_regs[i]);
434 if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
435 err |= __get_user(i, &sf->v8plus.g_upper[0]);
436 if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
437 unsigned long asi;
439 for (i = UREG_G1; i <= UREG_I7; i++)
440 err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
441 err |= __get_user(asi, &sf->v8plus.asi);
442 regs->tstate &= ~TSTATE_ASI;
443 regs->tstate |= ((asi & 0xffUL) << 24UL);
447 /* User can only change condition codes in %tstate. */
448 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
449 regs->tstate |= psr_to_tstate_icc(psr);
451 err |= __get_user(fpu_save, &sf->fpu_save);
452 if (fpu_save)
453 err |= restore_fpu_state32(regs, &sf->fpu_state);
454 err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
455 err |= __get_user(u_ss_sp, &sf->stack.ss_sp);
456 st.ss_sp = compat_ptr(u_ss_sp);
457 err |= __get_user(st.ss_flags, &sf->stack.ss_flags);
458 err |= __get_user(st.ss_size, &sf->stack.ss_size);
459 if (err)
460 goto segv;
462 /* It is more difficult to avoid calling this function than to
463 call it and ignore errors. */
464 old_fs = get_fs();
465 set_fs(KERNEL_DS);
466 do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf);
467 set_fs(old_fs);
469 switch (_NSIG_WORDS) {
470 case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32);
471 case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32);
472 case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32);
473 case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
475 sigdelsetmask(&set, ~_BLOCKABLE);
476 spin_lock_irq(&current->sighand->siglock);
477 current->blocked = set;
478 recalc_sigpending();
479 spin_unlock_irq(&current->sighand->siglock);
480 return;
481 segv:
482 force_sig(SIGSEGV, current);
485 /* Checks if the fp is valid */
486 static int invalid_frame_pointer(void __user *fp, int fplen)
488 if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
489 return 1;
490 return 0;
493 static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
495 unsigned long sp;
497 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
498 sp = regs->u_regs[UREG_FP];
500 /* This is the X/Open sanctioned signal stack switching. */
501 if (sa->sa_flags & SA_ONSTACK) {
502 if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
503 sp = current->sas_ss_sp + current->sas_ss_size;
505 return (void __user *)(sp - framesize);
508 static void
509 setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info)
511 struct signal_sframe32 __user *sframep;
512 struct sigcontext32 __user *sc;
513 unsigned int seta[_COMPAT_NSIG_WORDS];
514 int err = 0;
515 void __user *sig_address;
516 int sig_code;
517 unsigned long pc = regs->tpc;
518 unsigned long npc = regs->tnpc;
519 unsigned int psr;
521 if (test_thread_flag(TIF_32BIT)) {
522 pc &= 0xffffffff;
523 npc &= 0xffffffff;
526 synchronize_user_stack();
527 save_and_clear_fpu();
529 sframep = (struct signal_sframe32 __user *)
530 get_sigframe(sa, regs, SF_ALIGNEDSZ);
531 if (invalid_frame_pointer(sframep, sizeof(*sframep))){
532 /* Don't change signal code and address, so that
533 * post mortem debuggers can have a look.
535 do_exit(SIGILL);
538 sc = &sframep->sig_context;
540 /* We've already made sure frame pointer isn't in kernel space... */
541 err = __put_user((sas_ss_flags(regs->u_regs[UREG_FP]) == SS_ONSTACK),
542 &sc->sigc_onstack);
544 switch (_NSIG_WORDS) {
545 case 4: seta[7] = (oldset->sig[3] >> 32);
546 seta[6] = oldset->sig[3];
547 case 3: seta[5] = (oldset->sig[2] >> 32);
548 seta[4] = oldset->sig[2];
549 case 2: seta[3] = (oldset->sig[1] >> 32);
550 seta[2] = oldset->sig[1];
551 case 1: seta[1] = (oldset->sig[0] >> 32);
552 seta[0] = oldset->sig[0];
554 err |= __put_user(seta[0], &sc->sigc_mask);
555 err |= __copy_to_user(sframep->extramask, seta + 1,
556 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
557 err |= __put_user(regs->u_regs[UREG_FP], &sc->sigc_sp);
558 err |= __put_user(pc, &sc->sigc_pc);
559 err |= __put_user(npc, &sc->sigc_npc);
560 psr = tstate_to_psr(regs->tstate);
561 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
562 psr |= PSR_EF;
563 err |= __put_user(psr, &sc->sigc_psr);
564 err |= __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
565 err |= __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
566 err |= __put_user(get_thread_wsaved(), &sc->sigc_oswins);
568 err |= copy_in_user((u32 __user *)sframep,
569 (u32 __user *)(regs->u_regs[UREG_FP]),
570 sizeof(struct reg_window32));
572 set_thread_wsaved(0); /* So process is allowed to execute. */
573 err |= __put_user(signr, &sframep->sig_num);
574 sig_address = NULL;
575 sig_code = 0;
576 if (SI_FROMKERNEL (info) && (info->si_code & __SI_MASK) == __SI_FAULT) {
577 sig_address = info->si_addr;
578 switch (signr) {
579 case SIGSEGV:
580 switch (info->si_code) {
581 case SEGV_MAPERR: sig_code = SUBSIG_NOMAPPING; break;
582 default: sig_code = SUBSIG_PROTECTION; break;
584 break;
585 case SIGILL:
586 switch (info->si_code) {
587 case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break;
588 case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break;
589 case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP(info->si_trapno); break;
590 default: sig_code = SUBSIG_STACK; break;
592 break;
593 case SIGFPE:
594 switch (info->si_code) {
595 case FPE_INTDIV: sig_code = SUBSIG_IDIVZERO; break;
596 case FPE_INTOVF: sig_code = SUBSIG_FPINTOVFL; break;
597 case FPE_FLTDIV: sig_code = SUBSIG_FPDIVZERO; break;
598 case FPE_FLTOVF: sig_code = SUBSIG_FPOVFLOW; break;
599 case FPE_FLTUND: sig_code = SUBSIG_FPUNFLOW; break;
600 case FPE_FLTRES: sig_code = SUBSIG_FPINEXACT; break;
601 case FPE_FLTINV: sig_code = SUBSIG_FPOPERROR; break;
602 default: sig_code = SUBSIG_FPERROR; break;
604 break;
605 case SIGBUS:
606 switch (info->si_code) {
607 case BUS_ADRALN: sig_code = SUBSIG_ALIGNMENT; break;
608 case BUS_ADRERR: sig_code = SUBSIG_MISCERROR; break;
609 default: sig_code = SUBSIG_BUSTIMEOUT; break;
611 break;
612 case SIGEMT:
613 switch (info->si_code) {
614 case EMT_TAGOVF: sig_code = SUBSIG_TAG; break;
616 break;
617 case SIGSYS:
618 if (info->si_code == (__SI_FAULT|0x100)) {
619 /* See sys_sunos32.c */
620 sig_code = info->si_trapno;
621 break;
623 default:
624 sig_address = NULL;
627 err |= __put_user(ptr_to_compat(sig_address), &sframep->sig_address);
628 err |= __put_user(sig_code, &sframep->sig_code);
629 err |= __put_user(ptr_to_compat(sc), &sframep->sig_scptr);
630 if (err)
631 goto sigsegv;
633 regs->u_regs[UREG_FP] = (unsigned long) sframep;
634 regs->tpc = (unsigned long) sa->sa_handler;
635 regs->tnpc = (regs->tpc + 4);
636 if (test_thread_flag(TIF_32BIT)) {
637 regs->tpc &= 0xffffffff;
638 regs->tnpc &= 0xffffffff;
640 return;
642 sigsegv:
643 force_sigsegv(signr, current);
647 static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
649 unsigned long *fpregs = current_thread_info()->fpregs;
650 unsigned long fprs;
651 int err = 0;
653 fprs = current_thread_info()->fpsaved[0];
654 if (fprs & FPRS_DL)
655 err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
656 (sizeof(unsigned int) * 32));
657 if (fprs & FPRS_DU)
658 err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
659 (sizeof(unsigned int) * 32));
660 err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
661 err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
662 err |= __put_user(fprs, &fpu->si_fprs);
664 return err;
667 static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
668 int signo, sigset_t *oldset)
670 struct new_signal_frame32 __user *sf;
671 int sigframe_size;
672 u32 psr;
673 int i, err;
674 unsigned int seta[_COMPAT_NSIG_WORDS];
676 /* 1. Make sure everything is clean */
677 synchronize_user_stack();
678 save_and_clear_fpu();
680 sigframe_size = NF_ALIGNEDSZ;
681 if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
682 sigframe_size -= sizeof(__siginfo_fpu_t);
684 sf = (struct new_signal_frame32 __user *)
685 get_sigframe(&ka->sa, regs, sigframe_size);
687 if (invalid_frame_pointer(sf, sigframe_size))
688 goto sigill;
690 if (get_thread_wsaved() != 0)
691 goto sigill;
693 /* 2. Save the current process state */
694 if (test_thread_flag(TIF_32BIT)) {
695 regs->tpc &= 0xffffffff;
696 regs->tnpc &= 0xffffffff;
698 err = put_user(regs->tpc, &sf->info.si_regs.pc);
699 err |= __put_user(regs->tnpc, &sf->info.si_regs.npc);
700 err |= __put_user(regs->y, &sf->info.si_regs.y);
701 psr = tstate_to_psr(regs->tstate);
702 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
703 psr |= PSR_EF;
704 err |= __put_user(psr, &sf->info.si_regs.psr);
705 for (i = 0; i < 16; i++)
706 err |= __put_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
707 err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
708 err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
709 for (i = 1; i < 16; i++)
710 err |= __put_user(((u32 *)regs->u_regs)[2*i],
711 &sf->v8plus.g_upper[i]);
712 err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
713 &sf->v8plus.asi);
715 if (psr & PSR_EF) {
716 err |= save_fpu_state32(regs, &sf->fpu_state);
717 err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
718 } else {
719 err |= __put_user(0, &sf->fpu_save);
722 switch (_NSIG_WORDS) {
723 case 4: seta[7] = (oldset->sig[3] >> 32);
724 seta[6] = oldset->sig[3];
725 case 3: seta[5] = (oldset->sig[2] >> 32);
726 seta[4] = oldset->sig[2];
727 case 2: seta[3] = (oldset->sig[1] >> 32);
728 seta[2] = oldset->sig[1];
729 case 1: seta[1] = (oldset->sig[0] >> 32);
730 seta[0] = oldset->sig[0];
732 err |= __put_user(seta[0], &sf->info.si_mask);
733 err |= __copy_to_user(sf->extramask, seta + 1,
734 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
736 err |= copy_in_user((u32 __user *)sf,
737 (u32 __user *)(regs->u_regs[UREG_FP]),
738 sizeof(struct reg_window32));
740 if (err)
741 goto sigsegv;
743 /* 3. signal handler back-trampoline and parameters */
744 regs->u_regs[UREG_FP] = (unsigned long) sf;
745 regs->u_regs[UREG_I0] = signo;
746 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
747 regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
749 /* 4. signal handler */
750 regs->tpc = (unsigned long) ka->sa.sa_handler;
751 regs->tnpc = (regs->tpc + 4);
752 if (test_thread_flag(TIF_32BIT)) {
753 regs->tpc &= 0xffffffff;
754 regs->tnpc &= 0xffffffff;
757 /* 5. return to kernel instructions */
758 if (ka->ka_restorer) {
759 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
760 } else {
761 /* Flush instruction space. */
762 unsigned long address = ((unsigned long)&(sf->insns[0]));
763 pgd_t *pgdp = pgd_offset(current->mm, address);
764 pud_t *pudp = pud_offset(pgdp, address);
765 pmd_t *pmdp = pmd_offset(pudp, address);
766 pte_t *ptep;
767 pte_t pte;
769 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
771 err = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/
772 err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
773 if (err)
774 goto sigsegv;
776 preempt_disable();
777 ptep = pte_offset_map(pmdp, address);
778 pte = *ptep;
779 if (pte_present(pte)) {
780 unsigned long page = (unsigned long)
781 page_address(pte_page(pte));
783 wmb();
784 __asm__ __volatile__("flush %0 + %1"
785 : /* no outputs */
786 : "r" (page),
787 "r" (address & (PAGE_SIZE - 1))
788 : "memory");
790 pte_unmap(ptep);
791 preempt_enable();
793 return;
795 sigill:
796 do_exit(SIGILL);
797 sigsegv:
798 force_sigsegv(signo, current);
801 /* Setup a Solaris stack frame */
802 static void
803 setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
804 struct pt_regs *regs, int signr, sigset_t *oldset)
806 svr4_signal_frame_t __user *sfp;
807 svr4_gregset_t __user *gr;
808 svr4_siginfo_t __user *si;
809 svr4_mcontext_t __user *mc;
810 svr4_gwindows_t __user *gw;
811 svr4_ucontext_t __user *uc;
812 svr4_sigset_t setv;
813 unsigned int psr;
814 int i, err;
816 synchronize_user_stack();
817 save_and_clear_fpu();
819 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
820 sfp = (svr4_signal_frame_t __user *)
821 get_sigframe(sa, regs,
822 sizeof(struct reg_window32) + SVR4_SF_ALIGNED);
824 if (invalid_frame_pointer(sfp, sizeof(*sfp)))
825 do_exit(SIGILL);
827 /* Start with a clean frame pointer and fill it */
828 err = clear_user(sfp, sizeof(*sfp));
830 /* Setup convenience variables */
831 si = &sfp->si;
832 uc = &sfp->uc;
833 gw = &sfp->gw;
834 mc = &uc->mcontext;
835 gr = &mc->greg;
837 /* FIXME: where am I supposed to put this?
838 * sc->sigc_onstack = old_status;
839 * anyways, it does not look like it is used for anything at all.
841 setv.sigbits[0] = oldset->sig[0];
842 setv.sigbits[1] = (oldset->sig[0] >> 32);
843 if (_NSIG_WORDS >= 2) {
844 setv.sigbits[2] = oldset->sig[1];
845 setv.sigbits[3] = (oldset->sig[1] >> 32);
846 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
847 } else
848 err |= __copy_to_user(&uc->sigmask, &setv,
849 2 * sizeof(unsigned int));
851 /* Store registers */
852 if (test_thread_flag(TIF_32BIT)) {
853 regs->tpc &= 0xffffffff;
854 regs->tnpc &= 0xffffffff;
856 err |= __put_user(regs->tpc, &((*gr)[SVR4_PC]));
857 err |= __put_user(regs->tnpc, &((*gr)[SVR4_NPC]));
858 psr = tstate_to_psr(regs->tstate);
859 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
860 psr |= PSR_EF;
861 err |= __put_user(psr, &((*gr)[SVR4_PSR]));
862 err |= __put_user(regs->y, &((*gr)[SVR4_Y]));
864 /* Copy g[1..7] and o[0..7] registers */
865 for (i = 0; i < 7; i++)
866 err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
867 for (i = 0; i < 8; i++)
868 err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
870 /* Setup sigaltstack */
871 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
872 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
873 err |= __put_user(current->sas_ss_size, &uc->stack.size);
875 /* Save the currently window file: */
877 /* 1. Link sfp->uc->gwins to our windows */
878 err |= __put_user(ptr_to_compat(gw), &mc->gwin);
880 /* 2. Number of windows to restore at setcontext (): */
881 err |= __put_user(get_thread_wsaved(), &gw->count);
883 /* 3. We just pay attention to the gw->count field on setcontext */
884 set_thread_wsaved(0); /* So process is allowed to execute. */
886 /* Setup the signal information. Solaris expects a bunch of
887 * information to be passed to the signal handler, we don't provide
888 * that much currently, should use siginfo.
890 err |= __put_user(signr, &si->siginfo.signo);
891 err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
892 if (err)
893 goto sigsegv;
895 regs->u_regs[UREG_FP] = (unsigned long) sfp;
896 regs->tpc = (unsigned long) sa->sa_handler;
897 regs->tnpc = (regs->tpc + 4);
898 if (test_thread_flag(TIF_32BIT)) {
899 regs->tpc &= 0xffffffff;
900 regs->tnpc &= 0xffffffff;
903 /* Arguments passed to signal handler */
904 if (regs->u_regs[14]){
905 struct reg_window32 __user *rw = (struct reg_window32 __user *)
906 (regs->u_regs[14] & 0x00000000ffffffffUL);
908 err |= __put_user(signr, &rw->ins[0]);
909 err |= __put_user((u64)si, &rw->ins[1]);
910 err |= __put_user((u64)uc, &rw->ins[2]);
911 err |= __put_user((u64)sfp, &rw->ins[6]); /* frame pointer */
912 if (err)
913 goto sigsegv;
915 regs->u_regs[UREG_I0] = signr;
916 regs->u_regs[UREG_I1] = (u32)(u64) si;
917 regs->u_regs[UREG_I2] = (u32)(u64) uc;
919 return;
921 sigsegv:
922 force_sigsegv(signr, current);
925 asmlinkage int
926 svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs)
928 svr4_gregset_t __user *gr;
929 svr4_mcontext_t __user *mc;
930 svr4_sigset_t setv;
931 int i, err;
932 u32 psr;
934 synchronize_user_stack();
935 save_and_clear_fpu();
937 if (get_thread_wsaved())
938 do_exit(SIGSEGV);
940 err = clear_user(uc, sizeof(*uc));
942 /* Setup convenience variables */
943 mc = &uc->mcontext;
944 gr = &mc->greg;
946 setv.sigbits[0] = current->blocked.sig[0];
947 setv.sigbits[1] = (current->blocked.sig[0] >> 32);
948 if (_NSIG_WORDS >= 2) {
949 setv.sigbits[2] = current->blocked.sig[1];
950 setv.sigbits[3] = (current->blocked.sig[1] >> 32);
951 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
952 } else
953 err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
955 /* Store registers */
956 if (test_thread_flag(TIF_32BIT)) {
957 regs->tpc &= 0xffffffff;
958 regs->tnpc &= 0xffffffff;
960 err |= __put_user(regs->tpc, &uc->mcontext.greg[SVR4_PC]);
961 err |= __put_user(regs->tnpc, &uc->mcontext.greg[SVR4_NPC]);
963 psr = tstate_to_psr(regs->tstate) & ~PSR_EF;
964 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
965 psr |= PSR_EF;
966 err |= __put_user(psr, &uc->mcontext.greg[SVR4_PSR]);
968 err |= __put_user(regs->y, &uc->mcontext.greg[SVR4_Y]);
970 /* Copy g[1..7] and o[0..7] registers */
971 for (i = 0; i < 7; i++)
972 err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
973 for (i = 0; i < 8; i++)
974 err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
976 /* Setup sigaltstack */
977 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
978 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
979 err |= __put_user(current->sas_ss_size, &uc->stack.size);
981 /* The register file is not saved
982 * we have already stuffed all of it with sync_user_stack
984 return (err ? -EFAULT : 0);
988 /* Set the context for a svr4 application, this is Solaris way to sigreturn */
989 asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
991 svr4_gregset_t __user *gr;
992 mm_segment_t old_fs;
993 u32 pc, npc, psr, u_ss_sp;
994 sigset_t set;
995 svr4_sigset_t setv;
996 int i, err;
997 stack_t st;
999 /* Fixme: restore windows, or is this already taken care of in
1000 * svr4_setup_frame when sync_user_windows is done?
1002 flush_user_windows();
1004 if (get_thread_wsaved())
1005 goto sigsegv;
1007 if (((unsigned long) c) & 3){
1008 printk("Unaligned structure passed\n");
1009 goto sigsegv;
1012 if (!__access_ok(c, sizeof(*c))) {
1013 /* Miguel, add nice debugging msg _here_. ;-) */
1014 goto sigsegv;
1017 /* Check for valid PC and nPC */
1018 gr = &c->mcontext.greg;
1019 err = __get_user(pc, &((*gr)[SVR4_PC]));
1020 err |= __get_user(npc, &((*gr)[SVR4_NPC]));
1021 if ((pc | npc) & 3)
1022 goto sigsegv;
1024 /* Retrieve information from passed ucontext */
1025 /* note that nPC is ored a 1, this is used to inform entry.S */
1026 /* that we don't want it to mess with our PC and nPC */
1028 err |= copy_from_user(&setv, &c->sigmask, sizeof(svr4_sigset_t));
1029 set.sig[0] = setv.sigbits[0] | (((long)setv.sigbits[1]) << 32);
1030 if (_NSIG_WORDS >= 2)
1031 set.sig[1] = setv.sigbits[2] | (((long)setv.sigbits[3]) << 32);
1033 err |= __get_user(u_ss_sp, &c->stack.sp);
1034 st.ss_sp = compat_ptr(u_ss_sp);
1035 err |= __get_user(st.ss_flags, &c->stack.flags);
1036 err |= __get_user(st.ss_size, &c->stack.size);
1037 if (err)
1038 goto sigsegv;
1040 /* It is more difficult to avoid calling this function than to
1041 call it and ignore errors. */
1042 old_fs = get_fs();
1043 set_fs(KERNEL_DS);
1044 do_sigaltstack((stack_t __user *) &st, NULL, regs->u_regs[UREG_I6]);
1045 set_fs(old_fs);
1047 sigdelsetmask(&set, ~_BLOCKABLE);
1048 spin_lock_irq(&current->sighand->siglock);
1049 current->blocked = set;
1050 recalc_sigpending();
1051 spin_unlock_irq(&current->sighand->siglock);
1052 regs->tpc = pc;
1053 regs->tnpc = npc | 1;
1054 if (test_thread_flag(TIF_32BIT)) {
1055 regs->tpc &= 0xffffffff;
1056 regs->tnpc &= 0xffffffff;
1058 err |= __get_user(regs->y, &((*gr)[SVR4_Y]));
1059 err |= __get_user(psr, &((*gr)[SVR4_PSR]));
1060 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
1061 regs->tstate |= psr_to_tstate_icc(psr);
1063 /* Restore g[1..7] and o[0..7] registers */
1064 for (i = 0; i < 7; i++)
1065 err |= __get_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
1066 for (i = 0; i < 8; i++)
1067 err |= __get_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
1068 if (err)
1069 goto sigsegv;
1071 return -EINTR;
1072 sigsegv:
1073 return -EFAULT;
1076 static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
1077 unsigned long signr, sigset_t *oldset,
1078 siginfo_t *info)
1080 struct rt_signal_frame32 __user *sf;
1081 int sigframe_size;
1082 u32 psr;
1083 int i, err;
1084 compat_sigset_t seta;
1086 /* 1. Make sure everything is clean */
1087 synchronize_user_stack();
1088 save_and_clear_fpu();
1090 sigframe_size = RT_ALIGNEDSZ;
1091 if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
1092 sigframe_size -= sizeof(__siginfo_fpu_t);
1094 sf = (struct rt_signal_frame32 __user *)
1095 get_sigframe(&ka->sa, regs, sigframe_size);
1097 if (invalid_frame_pointer(sf, sigframe_size))
1098 goto sigill;
1100 if (get_thread_wsaved() != 0)
1101 goto sigill;
1103 /* 2. Save the current process state */
1104 if (test_thread_flag(TIF_32BIT)) {
1105 regs->tpc &= 0xffffffff;
1106 regs->tnpc &= 0xffffffff;
1108 err = put_user(regs->tpc, &sf->regs.pc);
1109 err |= __put_user(regs->tnpc, &sf->regs.npc);
1110 err |= __put_user(regs->y, &sf->regs.y);
1111 psr = tstate_to_psr(regs->tstate);
1112 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
1113 psr |= PSR_EF;
1114 err |= __put_user(psr, &sf->regs.psr);
1115 for (i = 0; i < 16; i++)
1116 err |= __put_user(regs->u_regs[i], &sf->regs.u_regs[i]);
1117 err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
1118 err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
1119 for (i = 1; i < 16; i++)
1120 err |= __put_user(((u32 *)regs->u_regs)[2*i],
1121 &sf->v8plus.g_upper[i]);
1122 err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
1123 &sf->v8plus.asi);
1125 if (psr & PSR_EF) {
1126 err |= save_fpu_state32(regs, &sf->fpu_state);
1127 err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
1128 } else {
1129 err |= __put_user(0, &sf->fpu_save);
1132 /* Update the siginfo structure. */
1133 err |= copy_siginfo_to_user32(&sf->info, info);
1135 /* Setup sigaltstack */
1136 err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
1137 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
1138 err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
1140 switch (_NSIG_WORDS) {
1141 case 4: seta.sig[7] = (oldset->sig[3] >> 32);
1142 seta.sig[6] = oldset->sig[3];
1143 case 3: seta.sig[5] = (oldset->sig[2] >> 32);
1144 seta.sig[4] = oldset->sig[2];
1145 case 2: seta.sig[3] = (oldset->sig[1] >> 32);
1146 seta.sig[2] = oldset->sig[1];
1147 case 1: seta.sig[1] = (oldset->sig[0] >> 32);
1148 seta.sig[0] = oldset->sig[0];
1150 err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
1152 err |= copy_in_user((u32 __user *)sf,
1153 (u32 __user *)(regs->u_regs[UREG_FP]),
1154 sizeof(struct reg_window32));
1155 if (err)
1156 goto sigsegv;
1158 /* 3. signal handler back-trampoline and parameters */
1159 regs->u_regs[UREG_FP] = (unsigned long) sf;
1160 regs->u_regs[UREG_I0] = signr;
1161 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
1162 regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
1164 /* 4. signal handler */
1165 regs->tpc = (unsigned long) ka->sa.sa_handler;
1166 regs->tnpc = (regs->tpc + 4);
1167 if (test_thread_flag(TIF_32BIT)) {
1168 regs->tpc &= 0xffffffff;
1169 regs->tnpc &= 0xffffffff;
1172 /* 5. return to kernel instructions */
1173 if (ka->ka_restorer)
1174 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
1175 else {
1176 /* Flush instruction space. */
1177 unsigned long address = ((unsigned long)&(sf->insns[0]));
1178 pgd_t *pgdp = pgd_offset(current->mm, address);
1179 pud_t *pudp = pud_offset(pgdp, address);
1180 pmd_t *pmdp = pmd_offset(pudp, address);
1181 pte_t *ptep;
1183 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
1185 /* mov __NR_rt_sigreturn, %g1 */
1186 err |= __put_user(0x82102065, &sf->insns[0]);
1188 /* t 0x10 */
1189 err |= __put_user(0x91d02010, &sf->insns[1]);
1190 if (err)
1191 goto sigsegv;
1193 preempt_disable();
1194 ptep = pte_offset_map(pmdp, address);
1195 if (pte_present(*ptep)) {
1196 unsigned long page = (unsigned long)
1197 page_address(pte_page(*ptep));
1199 wmb();
1200 __asm__ __volatile__("flush %0 + %1"
1201 : /* no outputs */
1202 : "r" (page),
1203 "r" (address & (PAGE_SIZE - 1))
1204 : "memory");
1206 pte_unmap(ptep);
1207 preempt_enable();
1209 return;
1211 sigill:
1212 do_exit(SIGILL);
1213 sigsegv:
1214 force_sigsegv(signr, current);
1217 static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
1218 siginfo_t *info,
1219 sigset_t *oldset, struct pt_regs *regs,
1220 int svr4_signal)
1222 if (svr4_signal)
1223 setup_svr4_frame32(&ka->sa, regs->tpc, regs->tnpc,
1224 regs, signr, oldset);
1225 else {
1226 if (ka->sa.sa_flags & SA_SIGINFO)
1227 setup_rt_frame32(ka, regs, signr, oldset, info);
1228 else if (test_thread_flag(TIF_NEWSIGNALS))
1229 new_setup_frame32(ka, regs, signr, oldset);
1230 else
1231 setup_frame32(&ka->sa, regs, signr, oldset, info);
1233 spin_lock_irq(&current->sighand->siglock);
1234 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
1235 if (!(ka->sa.sa_flags & SA_NOMASK))
1236 sigaddset(&current->blocked,signr);
1237 recalc_sigpending();
1238 spin_unlock_irq(&current->sighand->siglock);
1241 static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
1242 struct sigaction *sa)
1244 switch (regs->u_regs[UREG_I0]) {
1245 case ERESTART_RESTARTBLOCK:
1246 case ERESTARTNOHAND:
1247 no_system_call_restart:
1248 regs->u_regs[UREG_I0] = EINTR;
1249 regs->tstate |= TSTATE_ICARRY;
1250 break;
1251 case ERESTARTSYS:
1252 if (!(sa->sa_flags & SA_RESTART))
1253 goto no_system_call_restart;
1254 /* fallthrough */
1255 case ERESTARTNOINTR:
1256 regs->u_regs[UREG_I0] = orig_i0;
1257 regs->tpc -= 4;
1258 regs->tnpc -= 4;
1262 /* Note that 'init' is a special process: it doesn't get signals it doesn't
1263 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1264 * mistake.
1266 void do_signal32(sigset_t *oldset, struct pt_regs * regs,
1267 unsigned long orig_i0, int restart_syscall)
1269 siginfo_t info;
1270 struct signal_deliver_cookie cookie;
1271 struct k_sigaction ka;
1272 int signr;
1273 int svr4_signal = current->personality == PER_SVR4;
1275 cookie.restart_syscall = restart_syscall;
1276 cookie.orig_i0 = orig_i0;
1278 signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
1279 if (signr > 0) {
1280 if (cookie.restart_syscall)
1281 syscall_restart32(orig_i0, regs, &ka.sa);
1282 handle_signal32(signr, &ka, &info, oldset,
1283 regs, svr4_signal);
1285 /* a signal was successfully delivered; the saved
1286 * sigmask will have been stored in the signal frame,
1287 * and will be restored by sigreturn, so we can simply
1288 * clear the TIF_RESTORE_SIGMASK flag.
1290 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1291 clear_thread_flag(TIF_RESTORE_SIGMASK);
1292 return;
1294 if (cookie.restart_syscall &&
1295 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
1296 regs->u_regs[UREG_I0] == ERESTARTSYS ||
1297 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
1298 /* replay the system call when we are done */
1299 regs->u_regs[UREG_I0] = cookie.orig_i0;
1300 regs->tpc -= 4;
1301 regs->tnpc -= 4;
1303 if (cookie.restart_syscall &&
1304 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
1305 regs->u_regs[UREG_G1] = __NR_restart_syscall;
1306 regs->tpc -= 4;
1307 regs->tnpc -= 4;
1310 /* if there's no signal to deliver, we just put the saved sigmask
1311 * back
1313 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
1314 clear_thread_flag(TIF_RESTORE_SIGMASK);
1315 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
1319 struct sigstack32 {
1320 u32 the_stack;
1321 int cur_status;
1324 asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
1326 struct sigstack32 __user *ssptr =
1327 (struct sigstack32 __user *)((unsigned long)(u_ssptr));
1328 struct sigstack32 __user *ossptr =
1329 (struct sigstack32 __user *)((unsigned long)(u_ossptr));
1330 int ret = -EFAULT;
1332 /* First see if old state is wanted. */
1333 if (ossptr) {
1334 if (put_user(current->sas_ss_sp + current->sas_ss_size,
1335 &ossptr->the_stack) ||
1336 __put_user(on_sig_stack(sp), &ossptr->cur_status))
1337 goto out;
1340 /* Now see if we want to update the new state. */
1341 if (ssptr) {
1342 u32 ss_sp;
1344 if (get_user(ss_sp, &ssptr->the_stack))
1345 goto out;
1347 /* If the current stack was set with sigaltstack, don't
1348 * swap stacks while we are on it.
1350 ret = -EPERM;
1351 if (current->sas_ss_sp && on_sig_stack(sp))
1352 goto out;
1354 /* Since we don't know the extent of the stack, and we don't
1355 * track onstack-ness, but rather calculate it, we must
1356 * presume a size. Ho hum this interface is lossy.
1358 current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
1359 current->sas_ss_size = SIGSTKSZ;
1362 ret = 0;
1363 out:
1364 return ret;
1367 asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp)
1369 stack_t uss, uoss;
1370 u32 u_ss_sp = 0;
1371 int ret;
1372 mm_segment_t old_fs;
1373 stack_t32 __user *uss32 = compat_ptr(ussa);
1374 stack_t32 __user *uoss32 = compat_ptr(uossa);
1376 if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) ||
1377 __get_user(uss.ss_flags, &uss32->ss_flags) ||
1378 __get_user(uss.ss_size, &uss32->ss_size)))
1379 return -EFAULT;
1380 uss.ss_sp = compat_ptr(u_ss_sp);
1381 old_fs = get_fs();
1382 set_fs(KERNEL_DS);
1383 ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL,
1384 uossa ? (stack_t __user *) &uoss : NULL, sp);
1385 set_fs(old_fs);
1386 if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) ||
1387 __put_user(uoss.ss_flags, &uoss32->ss_flags) ||
1388 __put_user(uoss.ss_size, &uoss32->ss_size)))
1389 return -EFAULT;
1390 return ret;