]> bbs.cooldavid.org Git - net-next-2.6.git/blame - arch/sparc64/kernel/signal32.c
[SPARC]: sparc32 needs PROMDEV_{I,O}RSC defines too.
[net-next-2.6.git] / arch / sparc64 / kernel / signal32.c
CommitLineData
1da177e4
LT
1/* $Id: signal32.c,v 1.74 2002/02/09 19:49:30 davem Exp $
2 * arch/sparc64/kernel/signal32.c
3 *
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 */
10
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/smp_lock.h>
21#include <linux/binfmts.h>
22#include <linux/compat.h>
23#include <linux/bitops.h>
24
25#include <asm/uaccess.h>
26#include <asm/ptrace.h>
27#include <asm/svr4.h>
28#include <asm/pgtable.h>
29#include <asm/psrcompat.h>
30#include <asm/fpumacro.h>
31#include <asm/visasm.h>
32
33#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
34
35int do_signal32(sigset_t *oldset, struct pt_regs *regs,
36 unsigned long orig_o0, int ret_from_syscall);
37
38/* Signal frames: the original one (compatible with SunOS):
39 *
40 * Set up a signal frame... Make the stack look the way SunOS
41 * expects it to look which is basically:
42 *
43 * ---------------------------------- <-- %sp at signal time
44 * Struct sigcontext
45 * Signal address
46 * Ptr to sigcontext area above
47 * Signal code
48 * The signal number itself
49 * One register window
50 * ---------------------------------- <-- New %sp
51 */
52struct signal_sframe32 {
53 struct reg_window32 sig_window;
54 int sig_num;
55 int sig_code;
56 /* struct sigcontext32 * */ u32 sig_scptr;
57 int sig_address;
58 struct sigcontext32 sig_context;
59 unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
60};
61
62/* This magic should be in g_upper[0] for all upper parts
63 * to be valid.
64 */
65#define SIGINFO_EXTRA_V8PLUS_MAGIC 0x130e269
66typedef struct {
67 unsigned int g_upper[8];
68 unsigned int o_upper[8];
69 unsigned int asi;
70} siginfo_extra_v8plus_t;
71
72/*
73 * And the new one, intended to be used for Linux applications only
74 * (we have enough in there to work with clone).
75 * All the interesting bits are in the info field.
76 */
77struct new_signal_frame32 {
78 struct sparc_stackf32 ss;
79 __siginfo32_t info;
80 /* __siginfo_fpu32_t * */ u32 fpu_save;
81 unsigned int insns[2];
82 unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
83 unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
84 /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
85 siginfo_extra_v8plus_t v8plus;
86 __siginfo_fpu_t fpu_state;
87};
88
89typedef struct compat_siginfo{
90 int si_signo;
91 int si_errno;
92 int si_code;
93
94 union {
95 int _pad[SI_PAD_SIZE32];
96
97 /* kill() */
98 struct {
99 compat_pid_t _pid; /* sender's pid */
100 unsigned int _uid; /* sender's uid */
101 } _kill;
102
103 /* POSIX.1b timers */
104 struct {
0d77e5a2 105 compat_timer_t _tid; /* timer id */
1da177e4
LT
106 int _overrun; /* overrun count */
107 compat_sigval_t _sigval; /* same as below */
108 int _sys_private; /* not to be passed to user */
109 } _timer;
110
111 /* POSIX.1b signals */
112 struct {
113 compat_pid_t _pid; /* sender's pid */
114 unsigned int _uid; /* sender's uid */
115 compat_sigval_t _sigval;
116 } _rt;
117
118 /* SIGCHLD */
119 struct {
120 compat_pid_t _pid; /* which child */
121 unsigned int _uid; /* sender's uid */
122 int _status; /* exit code */
123 compat_clock_t _utime;
124 compat_clock_t _stime;
125 } _sigchld;
126
127 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
128 struct {
129 u32 _addr; /* faulting insn/memory ref. */
130 int _trapno;
131 } _sigfault;
132
133 /* SIGPOLL */
134 struct {
135 int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
136 int _fd;
137 } _sigpoll;
138 } _sifields;
139}compat_siginfo_t;
140
141struct rt_signal_frame32 {
142 struct sparc_stackf32 ss;
143 compat_siginfo_t info;
144 struct pt_regs32 regs;
145 compat_sigset_t mask;
146 /* __siginfo_fpu32_t * */ u32 fpu_save;
147 unsigned int insns[2];
148 stack_t32 stack;
149 unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
150 /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
151 siginfo_extra_v8plus_t v8plus;
152 __siginfo_fpu_t fpu_state;
153};
154
155/* Align macros */
156#define SF_ALIGNEDSZ (((sizeof(struct signal_sframe32) + 7) & (~7)))
157#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame32) + 7) & (~7)))
158#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
159
160int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
161{
162 int err;
163
164 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
165 return -EFAULT;
166
167 /* If you change siginfo_t structure, please be sure
168 this code is fixed accordingly.
169 It should never copy any pad contained in the structure
170 to avoid security leaks, but must copy the generic
171 3 ints plus the relevant union member.
172 This routine must convert siginfo from 64bit to 32bit as well
173 at the same time. */
174 err = __put_user(from->si_signo, &to->si_signo);
175 err |= __put_user(from->si_errno, &to->si_errno);
176 err |= __put_user((short)from->si_code, &to->si_code);
177 if (from->si_code < 0)
178 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
179 else {
180 switch (from->si_code >> 16) {
181 case __SI_TIMER >> 16:
182 err |= __put_user(from->si_tid, &to->si_tid);
183 err |= __put_user(from->si_overrun, &to->si_overrun);
184 err |= __put_user(from->si_int, &to->si_int);
185 break;
186 case __SI_CHLD >> 16:
187 err |= __put_user(from->si_utime, &to->si_utime);
188 err |= __put_user(from->si_stime, &to->si_stime);
189 err |= __put_user(from->si_status, &to->si_status);
190 default:
191 err |= __put_user(from->si_pid, &to->si_pid);
192 err |= __put_user(from->si_uid, &to->si_uid);
193 break;
194 case __SI_FAULT >> 16:
1da177e4
LT
195 err |= __put_user(from->si_trapno, &to->si_trapno);
196 err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
197 break;
9c7d3b3a
JS
198 case __SI_POLL >> 16:
199 err |= __put_user(from->si_band, &to->si_band);
200 err |= __put_user(from->si_fd, &to->si_fd);
201 break;
1da177e4
LT
202 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
203 case __SI_MESGQ >> 16:
204 err |= __put_user(from->si_pid, &to->si_pid);
205 err |= __put_user(from->si_uid, &to->si_uid);
206 err |= __put_user(from->si_int, &to->si_int);
207 break;
208 }
209 }
210 return err;
211}
212
213/* CAUTION: This is just a very minimalist implementation for the
214 * sake of compat_sys_rt_sigqueueinfo()
215 */
216int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
217{
218 if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
219 return -EFAULT;
220
221 if (copy_from_user(to, from, 3*sizeof(int)) ||
222 copy_from_user(to->_sifields._pad, from->_sifields._pad,
223 SI_PAD_SIZE))
224 return -EFAULT;
225
226 return 0;
227}
228
229/*
230 * atomically swap in the new signal mask, and wait for a signal.
231 * This is really tricky on the Sparc, watch out...
232 */
233asmlinkage void _sigpause32_common(compat_old_sigset_t set, struct pt_regs *regs)
234{
235 sigset_t saveset;
236
237 set &= _BLOCKABLE;
238 spin_lock_irq(&current->sighand->siglock);
239 saveset = current->blocked;
240 siginitset(&current->blocked, set);
241 recalc_sigpending();
242 spin_unlock_irq(&current->sighand->siglock);
243
244 regs->tpc = regs->tnpc;
245 regs->tnpc += 4;
246 if (test_thread_flag(TIF_32BIT)) {
247 regs->tpc &= 0xffffffff;
248 regs->tnpc &= 0xffffffff;
249 }
250
251 /* Condition codes and return value where set here for sigpause,
252 * and so got used by setup_frame, which again causes sigreturn()
253 * to return -EINTR.
254 */
255 while (1) {
256 current->state = TASK_INTERRUPTIBLE;
257 schedule();
258 /*
259 * Return -EINTR and set condition code here,
260 * so the interrupted system call actually returns
261 * these.
262 */
263 regs->tstate |= TSTATE_ICARRY;
264 regs->u_regs[UREG_I0] = EINTR;
265 if (do_signal32(&saveset, regs, 0, 0))
266 return;
267 }
268}
269
270asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *regs)
271{
272 sigset_t oldset, set;
273 compat_sigset_t set32;
274
275 /* XXX: Don't preclude handling different sized sigset_t's. */
276 if (((compat_size_t)sigsetsize) != sizeof(sigset_t)) {
277 regs->tstate |= TSTATE_ICARRY;
278 regs->u_regs[UREG_I0] = EINVAL;
279 return;
280 }
281 if (copy_from_user(&set32, compat_ptr(uset), sizeof(set32))) {
282 regs->tstate |= TSTATE_ICARRY;
283 regs->u_regs[UREG_I0] = EFAULT;
284 return;
285 }
286 switch (_NSIG_WORDS) {
287 case 4: set.sig[3] = set32.sig[6] + (((long)set32.sig[7]) << 32);
288 case 3: set.sig[2] = set32.sig[4] + (((long)set32.sig[5]) << 32);
289 case 2: set.sig[1] = set32.sig[2] + (((long)set32.sig[3]) << 32);
290 case 1: set.sig[0] = set32.sig[0] + (((long)set32.sig[1]) << 32);
291 }
292 sigdelsetmask(&set, ~_BLOCKABLE);
293 spin_lock_irq(&current->sighand->siglock);
294 oldset = current->blocked;
295 current->blocked = set;
296 recalc_sigpending();
297 spin_unlock_irq(&current->sighand->siglock);
298
299 regs->tpc = regs->tnpc;
300 regs->tnpc += 4;
301 if (test_thread_flag(TIF_32BIT)) {
302 regs->tpc &= 0xffffffff;
303 regs->tnpc &= 0xffffffff;
304 }
305
306 /* Condition codes and return value where set here for sigpause,
307 * and so got used by setup_frame, which again causes sigreturn()
308 * to return -EINTR.
309 */
310 while (1) {
311 current->state = TASK_INTERRUPTIBLE;
312 schedule();
313 /*
314 * Return -EINTR and set condition code here,
315 * so the interrupted system call actually returns
316 * these.
317 */
318 regs->tstate |= TSTATE_ICARRY;
319 regs->u_regs[UREG_I0] = EINTR;
320 if (do_signal32(&oldset, regs, 0, 0))
321 return;
322 }
323}
324
325static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
326{
327 unsigned long *fpregs = current_thread_info()->fpregs;
328 unsigned long fprs;
329 int err;
330
331 err = __get_user(fprs, &fpu->si_fprs);
332 fprs_write(0);
333 regs->tstate &= ~TSTATE_PEF;
334 if (fprs & FPRS_DL)
335 err |= copy_from_user(fpregs, &fpu->si_float_regs[0], (sizeof(unsigned int) * 32));
336 if (fprs & FPRS_DU)
337 err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], (sizeof(unsigned int) * 32));
338 err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
339 err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
340 current_thread_info()->fpsaved[0] |= fprs;
341 return err;
342}
343
344void do_new_sigreturn32(struct pt_regs *regs)
345{
346 struct new_signal_frame32 __user *sf;
347 unsigned int psr;
348 unsigned pc, npc, fpu_save;
349 sigset_t set;
350 unsigned seta[_COMPAT_NSIG_WORDS];
351 int err, i;
352
353 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
354 sf = (struct new_signal_frame32 __user *) regs->u_regs[UREG_FP];
355
356 /* 1. Make sure we are not getting garbage from the user */
357 if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
358 (((unsigned long) sf) & 3))
359 goto segv;
360
361 get_user(pc, &sf->info.si_regs.pc);
362 __get_user(npc, &sf->info.si_regs.npc);
363
364 if ((pc | npc) & 3)
365 goto segv;
366
367 if (test_thread_flag(TIF_32BIT)) {
368 pc &= 0xffffffff;
369 npc &= 0xffffffff;
370 }
371 regs->tpc = pc;
372 regs->tnpc = npc;
373
374 /* 2. Restore the state */
375 err = __get_user(regs->y, &sf->info.si_regs.y);
376 err |= __get_user(psr, &sf->info.si_regs.psr);
377
378 for (i = UREG_G1; i <= UREG_I7; i++)
379 err |= __get_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
380 if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
381 err |= __get_user(i, &sf->v8plus.g_upper[0]);
382 if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
383 unsigned long asi;
384
385 for (i = UREG_G1; i <= UREG_I7; i++)
386 err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
387 err |= __get_user(asi, &sf->v8plus.asi);
388 regs->tstate &= ~TSTATE_ASI;
389 regs->tstate |= ((asi & 0xffUL) << 24UL);
390 }
391 }
392
393 /* User can only change condition codes in %tstate. */
394 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
395 regs->tstate |= psr_to_tstate_icc(psr);
396
397 err |= __get_user(fpu_save, &sf->fpu_save);
398 if (fpu_save)
399 err |= restore_fpu_state32(regs, &sf->fpu_state);
400 err |= __get_user(seta[0], &sf->info.si_mask);
401 err |= copy_from_user(seta+1, &sf->extramask,
402 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
403 if (err)
404 goto segv;
405 switch (_NSIG_WORDS) {
406 case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32);
407 case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32);
408 case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
409 case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
410 }
411 sigdelsetmask(&set, ~_BLOCKABLE);
412 spin_lock_irq(&current->sighand->siglock);
413 current->blocked = set;
414 recalc_sigpending();
415 spin_unlock_irq(&current->sighand->siglock);
416 return;
417
418segv:
419 force_sig(SIGSEGV, current);
420}
421
422asmlinkage void do_sigreturn32(struct pt_regs *regs)
423{
424 struct sigcontext32 __user *scptr;
425 unsigned int pc, npc, psr;
426 sigset_t set;
427 unsigned int seta[_COMPAT_NSIG_WORDS];
428 int err;
429
430 /* Always make any pending restarted system calls return -EINTR */
431 current_thread_info()->restart_block.fn = do_no_restart_syscall;
432
433 synchronize_user_stack();
434 if (test_thread_flag(TIF_NEWSIGNALS)) {
435 do_new_sigreturn32(regs);
436 return;
437 }
438
439 scptr = (struct sigcontext32 __user *)
440 (regs->u_regs[UREG_I0] & 0x00000000ffffffffUL);
441 /* Check sanity of the user arg. */
442 if (!access_ok(VERIFY_READ, scptr, sizeof(struct sigcontext32)) ||
443 (((unsigned long) scptr) & 3))
444 goto segv;
445
446 err = __get_user(pc, &scptr->sigc_pc);
447 err |= __get_user(npc, &scptr->sigc_npc);
448
449 if ((pc | npc) & 3)
450 goto segv; /* Nice try. */
451
452 err |= __get_user(seta[0], &scptr->sigc_mask);
453 /* Note that scptr + 1 points to extramask */
454 err |= copy_from_user(seta+1, scptr + 1,
455 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
456 if (err)
457 goto segv;
458 switch (_NSIG_WORDS) {
459 case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32);
460 case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32);
461 case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
462 case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
463 }
464 sigdelsetmask(&set, ~_BLOCKABLE);
465 spin_lock_irq(&current->sighand->siglock);
466 current->blocked = set;
467 recalc_sigpending();
468 spin_unlock_irq(&current->sighand->siglock);
469
470 if (test_thread_flag(TIF_32BIT)) {
471 pc &= 0xffffffff;
472 npc &= 0xffffffff;
473 }
474 regs->tpc = pc;
475 regs->tnpc = npc;
476 err = __get_user(regs->u_regs[UREG_FP], &scptr->sigc_sp);
477 err |= __get_user(regs->u_regs[UREG_I0], &scptr->sigc_o0);
478 err |= __get_user(regs->u_regs[UREG_G1], &scptr->sigc_g1);
479
480 /* User can only change condition codes in %tstate. */
481 err |= __get_user(psr, &scptr->sigc_psr);
482 if (err)
483 goto segv;
484 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
485 regs->tstate |= psr_to_tstate_icc(psr);
486 return;
487
488segv:
489 force_sig(SIGSEGV, current);
490}
491
492asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
493{
494 struct rt_signal_frame32 __user *sf;
495 unsigned int psr, pc, npc, fpu_save, u_ss_sp;
496 mm_segment_t old_fs;
497 sigset_t set;
498 compat_sigset_t seta;
499 stack_t st;
500 int err, i;
501
502 /* Always make any pending restarted system calls return -EINTR */
503 current_thread_info()->restart_block.fn = do_no_restart_syscall;
504
505 synchronize_user_stack();
506 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
507 sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
508
509 /* 1. Make sure we are not getting garbage from the user */
510 if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
511 (((unsigned long) sf) & 3))
512 goto segv;
513
514 get_user(pc, &sf->regs.pc);
515 __get_user(npc, &sf->regs.npc);
516
517 if ((pc | npc) & 3)
518 goto segv;
519
520 if (test_thread_flag(TIF_32BIT)) {
521 pc &= 0xffffffff;
522 npc &= 0xffffffff;
523 }
524 regs->tpc = pc;
525 regs->tnpc = npc;
526
527 /* 2. Restore the state */
528 err = __get_user(regs->y, &sf->regs.y);
529 err |= __get_user(psr, &sf->regs.psr);
530
531 for (i = UREG_G1; i <= UREG_I7; i++)
532 err |= __get_user(regs->u_regs[i], &sf->regs.u_regs[i]);
533 if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
534 err |= __get_user(i, &sf->v8plus.g_upper[0]);
535 if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
536 unsigned long asi;
537
538 for (i = UREG_G1; i <= UREG_I7; i++)
539 err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
540 err |= __get_user(asi, &sf->v8plus.asi);
541 regs->tstate &= ~TSTATE_ASI;
542 regs->tstate |= ((asi & 0xffUL) << 24UL);
543 }
544 }
545
546 /* User can only change condition codes in %tstate. */
547 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
548 regs->tstate |= psr_to_tstate_icc(psr);
549
550 err |= __get_user(fpu_save, &sf->fpu_save);
551 if (fpu_save)
552 err |= restore_fpu_state32(regs, &sf->fpu_state);
553 err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
554 err |= __get_user(u_ss_sp, &sf->stack.ss_sp);
555 st.ss_sp = compat_ptr(u_ss_sp);
556 err |= __get_user(st.ss_flags, &sf->stack.ss_flags);
557 err |= __get_user(st.ss_size, &sf->stack.ss_size);
558 if (err)
559 goto segv;
560
561 /* It is more difficult to avoid calling this function than to
562 call it and ignore errors. */
563 old_fs = get_fs();
564 set_fs(KERNEL_DS);
565 do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf);
566 set_fs(old_fs);
567
568 switch (_NSIG_WORDS) {
569 case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32);
570 case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32);
571 case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32);
572 case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
573 }
574 sigdelsetmask(&set, ~_BLOCKABLE);
575 spin_lock_irq(&current->sighand->siglock);
576 current->blocked = set;
577 recalc_sigpending();
578 spin_unlock_irq(&current->sighand->siglock);
579 return;
580segv:
581 force_sig(SIGSEGV, current);
582}
583
584/* Checks if the fp is valid */
585static int invalid_frame_pointer(void __user *fp, int fplen)
586{
587 if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
588 return 1;
589 return 0;
590}
591
592static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
593{
594 unsigned long sp;
595
596 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
597 sp = regs->u_regs[UREG_FP];
598
599 /* This is the X/Open sanctioned signal stack switching. */
600 if (sa->sa_flags & SA_ONSTACK) {
601 if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
602 sp = current->sas_ss_sp + current->sas_ss_size;
603 }
604 return (void __user *)(sp - framesize);
605}
606
607static void
608setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info)
609{
610 struct signal_sframe32 __user *sframep;
611 struct sigcontext32 __user *sc;
612 unsigned int seta[_COMPAT_NSIG_WORDS];
613 int err = 0;
614 void __user *sig_address;
615 int sig_code;
616 unsigned long pc = regs->tpc;
617 unsigned long npc = regs->tnpc;
618 unsigned int psr;
619
620 if (test_thread_flag(TIF_32BIT)) {
621 pc &= 0xffffffff;
622 npc &= 0xffffffff;
623 }
624
625 synchronize_user_stack();
626 save_and_clear_fpu();
627
628 sframep = (struct signal_sframe32 __user *)
629 get_sigframe(sa, regs, SF_ALIGNEDSZ);
630 if (invalid_frame_pointer(sframep, sizeof(*sframep))){
631 /* Don't change signal code and address, so that
632 * post mortem debuggers can have a look.
633 */
634 do_exit(SIGILL);
635 }
636
637 sc = &sframep->sig_context;
638
639 /* We've already made sure frame pointer isn't in kernel space... */
640 err = __put_user((sas_ss_flags(regs->u_regs[UREG_FP]) == SS_ONSTACK),
641 &sc->sigc_onstack);
642
643 switch (_NSIG_WORDS) {
644 case 4: seta[7] = (oldset->sig[3] >> 32);
645 seta[6] = oldset->sig[3];
646 case 3: seta[5] = (oldset->sig[2] >> 32);
647 seta[4] = oldset->sig[2];
648 case 2: seta[3] = (oldset->sig[1] >> 32);
649 seta[2] = oldset->sig[1];
650 case 1: seta[1] = (oldset->sig[0] >> 32);
651 seta[0] = oldset->sig[0];
652 }
653 err |= __put_user(seta[0], &sc->sigc_mask);
654 err |= __copy_to_user(sframep->extramask, seta + 1,
655 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
656 err |= __put_user(regs->u_regs[UREG_FP], &sc->sigc_sp);
657 err |= __put_user(pc, &sc->sigc_pc);
658 err |= __put_user(npc, &sc->sigc_npc);
659 psr = tstate_to_psr(regs->tstate);
660 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
661 psr |= PSR_EF;
662 err |= __put_user(psr, &sc->sigc_psr);
663 err |= __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
664 err |= __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
665 err |= __put_user(get_thread_wsaved(), &sc->sigc_oswins);
666
667 err |= copy_in_user((u32 __user *)sframep,
668 (u32 __user *)(regs->u_regs[UREG_FP]),
669 sizeof(struct reg_window32));
670
671 set_thread_wsaved(0); /* So process is allowed to execute. */
672 err |= __put_user(signr, &sframep->sig_num);
673 sig_address = NULL;
674 sig_code = 0;
675 if (SI_FROMKERNEL (info) && (info->si_code & __SI_MASK) == __SI_FAULT) {
676 sig_address = info->si_addr;
677 switch (signr) {
678 case SIGSEGV:
679 switch (info->si_code) {
680 case SEGV_MAPERR: sig_code = SUBSIG_NOMAPPING; break;
681 default: sig_code = SUBSIG_PROTECTION; break;
682 }
683 break;
684 case SIGILL:
685 switch (info->si_code) {
686 case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break;
687 case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break;
688 case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP(info->si_trapno); break;
689 default: sig_code = SUBSIG_STACK; break;
690 }
691 break;
692 case SIGFPE:
693 switch (info->si_code) {
694 case FPE_INTDIV: sig_code = SUBSIG_IDIVZERO; break;
695 case FPE_INTOVF: sig_code = SUBSIG_FPINTOVFL; break;
696 case FPE_FLTDIV: sig_code = SUBSIG_FPDIVZERO; break;
697 case FPE_FLTOVF: sig_code = SUBSIG_FPOVFLOW; break;
698 case FPE_FLTUND: sig_code = SUBSIG_FPUNFLOW; break;
699 case FPE_FLTRES: sig_code = SUBSIG_FPINEXACT; break;
700 case FPE_FLTINV: sig_code = SUBSIG_FPOPERROR; break;
701 default: sig_code = SUBSIG_FPERROR; break;
702 }
703 break;
704 case SIGBUS:
705 switch (info->si_code) {
706 case BUS_ADRALN: sig_code = SUBSIG_ALIGNMENT; break;
707 case BUS_ADRERR: sig_code = SUBSIG_MISCERROR; break;
708 default: sig_code = SUBSIG_BUSTIMEOUT; break;
709 }
710 break;
711 case SIGEMT:
712 switch (info->si_code) {
713 case EMT_TAGOVF: sig_code = SUBSIG_TAG; break;
714 }
715 break;
716 case SIGSYS:
717 if (info->si_code == (__SI_FAULT|0x100)) {
718 /* See sys_sunos32.c */
719 sig_code = info->si_trapno;
720 break;
721 }
722 default:
723 sig_address = NULL;
724 }
725 }
726 err |= __put_user(ptr_to_compat(sig_address), &sframep->sig_address);
727 err |= __put_user(sig_code, &sframep->sig_code);
728 err |= __put_user(ptr_to_compat(sc), &sframep->sig_scptr);
729 if (err)
730 goto sigsegv;
731
732 regs->u_regs[UREG_FP] = (unsigned long) sframep;
733 regs->tpc = (unsigned long) sa->sa_handler;
734 regs->tnpc = (regs->tpc + 4);
735 if (test_thread_flag(TIF_32BIT)) {
736 regs->tpc &= 0xffffffff;
737 regs->tnpc &= 0xffffffff;
738 }
739 return;
740
741sigsegv:
742 force_sigsegv(signr, current);
743}
744
745
746static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
747{
748 unsigned long *fpregs = current_thread_info()->fpregs;
749 unsigned long fprs;
750 int err = 0;
751
752 fprs = current_thread_info()->fpsaved[0];
753 if (fprs & FPRS_DL)
754 err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
755 (sizeof(unsigned int) * 32));
756 if (fprs & FPRS_DU)
757 err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
758 (sizeof(unsigned int) * 32));
759 err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
760 err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
761 err |= __put_user(fprs, &fpu->si_fprs);
762
763 return err;
764}
765
766static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
767 int signo, sigset_t *oldset)
768{
769 struct new_signal_frame32 __user *sf;
770 int sigframe_size;
771 u32 psr;
772 int i, err;
773 unsigned int seta[_COMPAT_NSIG_WORDS];
774
775 /* 1. Make sure everything is clean */
776 synchronize_user_stack();
777 save_and_clear_fpu();
778
779 sigframe_size = NF_ALIGNEDSZ;
780 if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
781 sigframe_size -= sizeof(__siginfo_fpu_t);
782
783 sf = (struct new_signal_frame32 __user *)
784 get_sigframe(&ka->sa, regs, sigframe_size);
785
786 if (invalid_frame_pointer(sf, sigframe_size))
787 goto sigill;
788
789 if (get_thread_wsaved() != 0)
790 goto sigill;
791
792 /* 2. Save the current process state */
793 if (test_thread_flag(TIF_32BIT)) {
794 regs->tpc &= 0xffffffff;
795 regs->tnpc &= 0xffffffff;
796 }
797 err = put_user(regs->tpc, &sf->info.si_regs.pc);
798 err |= __put_user(regs->tnpc, &sf->info.si_regs.npc);
799 err |= __put_user(regs->y, &sf->info.si_regs.y);
800 psr = tstate_to_psr(regs->tstate);
801 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
802 psr |= PSR_EF;
803 err |= __put_user(psr, &sf->info.si_regs.psr);
804 for (i = 0; i < 16; i++)
805 err |= __put_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
806 err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
807 err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
808 for (i = 1; i < 16; i++)
809 err |= __put_user(((u32 *)regs->u_regs)[2*i],
810 &sf->v8plus.g_upper[i]);
811 err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
812 &sf->v8plus.asi);
813
814 if (psr & PSR_EF) {
815 err |= save_fpu_state32(regs, &sf->fpu_state);
816 err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
817 } else {
818 err |= __put_user(0, &sf->fpu_save);
819 }
820
821 switch (_NSIG_WORDS) {
822 case 4: seta[7] = (oldset->sig[3] >> 32);
823 seta[6] = oldset->sig[3];
824 case 3: seta[5] = (oldset->sig[2] >> 32);
825 seta[4] = oldset->sig[2];
826 case 2: seta[3] = (oldset->sig[1] >> 32);
827 seta[2] = oldset->sig[1];
828 case 1: seta[1] = (oldset->sig[0] >> 32);
829 seta[0] = oldset->sig[0];
830 }
831 err |= __put_user(seta[0], &sf->info.si_mask);
832 err |= __copy_to_user(sf->extramask, seta + 1,
833 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
834
835 err |= copy_in_user((u32 __user *)sf,
836 (u32 __user *)(regs->u_regs[UREG_FP]),
837 sizeof(struct reg_window32));
838
839 if (err)
840 goto sigsegv;
841
842 /* 3. signal handler back-trampoline and parameters */
843 regs->u_regs[UREG_FP] = (unsigned long) sf;
844 regs->u_regs[UREG_I0] = signo;
845 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
846 regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
847
848 /* 4. signal handler */
849 regs->tpc = (unsigned long) ka->sa.sa_handler;
850 regs->tnpc = (regs->tpc + 4);
851 if (test_thread_flag(TIF_32BIT)) {
852 regs->tpc &= 0xffffffff;
853 regs->tnpc &= 0xffffffff;
854 }
855
856 /* 5. return to kernel instructions */
857 if (ka->ka_restorer) {
858 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
859 } else {
860 /* Flush instruction space. */
861 unsigned long address = ((unsigned long)&(sf->insns[0]));
862 pgd_t *pgdp = pgd_offset(current->mm, address);
863 pud_t *pudp = pud_offset(pgdp, address);
864 pmd_t *pmdp = pmd_offset(pudp, address);
865 pte_t *ptep;
b8ae4865 866 pte_t pte;
1da177e4
LT
867
868 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
869
870 err = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/
871 err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
872 if (err)
873 goto sigsegv;
874
875 preempt_disable();
876 ptep = pte_offset_map(pmdp, address);
b8ae4865
HD
877 pte = *ptep;
878 if (pte_present(pte)) {
1da177e4 879 unsigned long page = (unsigned long)
b8ae4865 880 page_address(pte_page(pte));
1da177e4 881
4f07118f
DM
882 wmb();
883 __asm__ __volatile__("flush %0 + %1"
884 : /* no outputs */
885 : "r" (page),
886 "r" (address & (PAGE_SIZE - 1))
887 : "memory");
1da177e4
LT
888 }
889 pte_unmap(ptep);
890 preempt_enable();
891 }
892 return;
893
894sigill:
895 do_exit(SIGILL);
896sigsegv:
897 force_sigsegv(signo, current);
898}
899
900/* Setup a Solaris stack frame */
901static void
902setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
903 struct pt_regs *regs, int signr, sigset_t *oldset)
904{
905 svr4_signal_frame_t __user *sfp;
906 svr4_gregset_t __user *gr;
907 svr4_siginfo_t __user *si;
908 svr4_mcontext_t __user *mc;
909 svr4_gwindows_t __user *gw;
910 svr4_ucontext_t __user *uc;
911 svr4_sigset_t setv;
912 unsigned int psr;
913 int i, err;
914
915 synchronize_user_stack();
916 save_and_clear_fpu();
917
918 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
919 sfp = (svr4_signal_frame_t __user *)
920 get_sigframe(sa, regs,
921 sizeof(struct reg_window32) + SVR4_SF_ALIGNED);
922
923 if (invalid_frame_pointer(sfp, sizeof(*sfp)))
924 do_exit(SIGILL);
925
926 /* Start with a clean frame pointer and fill it */
927 err = clear_user(sfp, sizeof(*sfp));
928
929 /* Setup convenience variables */
930 si = &sfp->si;
931 uc = &sfp->uc;
932 gw = &sfp->gw;
933 mc = &uc->mcontext;
934 gr = &mc->greg;
935
936 /* FIXME: where am I supposed to put this?
937 * sc->sigc_onstack = old_status;
938 * anyways, it does not look like it is used for anything at all.
939 */
940 setv.sigbits[0] = oldset->sig[0];
941 setv.sigbits[1] = (oldset->sig[0] >> 32);
942 if (_NSIG_WORDS >= 2) {
943 setv.sigbits[2] = oldset->sig[1];
944 setv.sigbits[3] = (oldset->sig[1] >> 32);
945 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
946 } else
947 err |= __copy_to_user(&uc->sigmask, &setv,
948 2 * sizeof(unsigned int));
949
950 /* Store registers */
951 if (test_thread_flag(TIF_32BIT)) {
952 regs->tpc &= 0xffffffff;
953 regs->tnpc &= 0xffffffff;
954 }
955 err |= __put_user(regs->tpc, &((*gr)[SVR4_PC]));
956 err |= __put_user(regs->tnpc, &((*gr)[SVR4_NPC]));
957 psr = tstate_to_psr(regs->tstate);
958 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
959 psr |= PSR_EF;
960 err |= __put_user(psr, &((*gr)[SVR4_PSR]));
961 err |= __put_user(regs->y, &((*gr)[SVR4_Y]));
962
963 /* Copy g[1..7] and o[0..7] registers */
964 for (i = 0; i < 7; i++)
965 err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
966 for (i = 0; i < 8; i++)
967 err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
968
969 /* Setup sigaltstack */
970 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
971 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
972 err |= __put_user(current->sas_ss_size, &uc->stack.size);
973
974 /* Save the currently window file: */
975
976 /* 1. Link sfp->uc->gwins to our windows */
977 err |= __put_user(ptr_to_compat(gw), &mc->gwin);
978
979 /* 2. Number of windows to restore at setcontext (): */
980 err |= __put_user(get_thread_wsaved(), &gw->count);
981
982 /* 3. We just pay attention to the gw->count field on setcontext */
983 set_thread_wsaved(0); /* So process is allowed to execute. */
984
985 /* Setup the signal information. Solaris expects a bunch of
986 * information to be passed to the signal handler, we don't provide
987 * that much currently, should use siginfo.
988 */
989 err |= __put_user(signr, &si->siginfo.signo);
990 err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
991 if (err)
992 goto sigsegv;
993
994 regs->u_regs[UREG_FP] = (unsigned long) sfp;
995 regs->tpc = (unsigned long) sa->sa_handler;
996 regs->tnpc = (regs->tpc + 4);
997 if (test_thread_flag(TIF_32BIT)) {
998 regs->tpc &= 0xffffffff;
999 regs->tnpc &= 0xffffffff;
1000 }
1001
1002 /* Arguments passed to signal handler */
1003 if (regs->u_regs[14]){
1004 struct reg_window32 __user *rw = (struct reg_window32 __user *)
1005 (regs->u_regs[14] & 0x00000000ffffffffUL);
1006
1007 err |= __put_user(signr, &rw->ins[0]);
1008 err |= __put_user((u64)si, &rw->ins[1]);
1009 err |= __put_user((u64)uc, &rw->ins[2]);
1010 err |= __put_user((u64)sfp, &rw->ins[6]); /* frame pointer */
1011 if (err)
1012 goto sigsegv;
1013
1014 regs->u_regs[UREG_I0] = signr;
1015 regs->u_regs[UREG_I1] = (u32)(u64) si;
1016 regs->u_regs[UREG_I2] = (u32)(u64) uc;
1017 }
1018 return;
1019
1020sigsegv:
1021 force_sigsegv(signr, current);
1022}
1023
1024asmlinkage int
1025svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs)
1026{
1027 svr4_gregset_t __user *gr;
1028 svr4_mcontext_t __user *mc;
1029 svr4_sigset_t setv;
1030 int i, err;
1031 u32 psr;
1032
1033 synchronize_user_stack();
1034 save_and_clear_fpu();
1035
1036 if (get_thread_wsaved())
1037 do_exit(SIGSEGV);
1038
1039 err = clear_user(uc, sizeof(*uc));
1040
1041 /* Setup convenience variables */
1042 mc = &uc->mcontext;
1043 gr = &mc->greg;
1044
1045 setv.sigbits[0] = current->blocked.sig[0];
1046 setv.sigbits[1] = (current->blocked.sig[0] >> 32);
1047 if (_NSIG_WORDS >= 2) {
1048 setv.sigbits[2] = current->blocked.sig[1];
1049 setv.sigbits[3] = (current->blocked.sig[1] >> 32);
1050 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
1051 } else
1052 err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
1053
1054 /* Store registers */
1055 if (test_thread_flag(TIF_32BIT)) {
1056 regs->tpc &= 0xffffffff;
1057 regs->tnpc &= 0xffffffff;
1058 }
1059 err |= __put_user(regs->tpc, &uc->mcontext.greg[SVR4_PC]);
1060 err |= __put_user(regs->tnpc, &uc->mcontext.greg[SVR4_NPC]);
1061
1062 psr = tstate_to_psr(regs->tstate) & ~PSR_EF;
1063 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
1064 psr |= PSR_EF;
1065 err |= __put_user(psr, &uc->mcontext.greg[SVR4_PSR]);
1066
1067 err |= __put_user(regs->y, &uc->mcontext.greg[SVR4_Y]);
1068
1069 /* Copy g[1..7] and o[0..7] registers */
1070 for (i = 0; i < 7; i++)
1071 err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
1072 for (i = 0; i < 8; i++)
1073 err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
1074
1075 /* Setup sigaltstack */
1076 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
1077 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
1078 err |= __put_user(current->sas_ss_size, &uc->stack.size);
1079
1080 /* The register file is not saved
1081 * we have already stuffed all of it with sync_user_stack
1082 */
1083 return (err ? -EFAULT : 0);
1084}
1085
1086
1087/* Set the context for a svr4 application, this is Solaris way to sigreturn */
1088asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
1089{
1090 svr4_gregset_t __user *gr;
1091 mm_segment_t old_fs;
1092 u32 pc, npc, psr, u_ss_sp;
1093 sigset_t set;
1094 svr4_sigset_t setv;
1095 int i, err;
1096 stack_t st;
1097
1098 /* Fixme: restore windows, or is this already taken care of in
1099 * svr4_setup_frame when sync_user_windows is done?
1100 */
1101 flush_user_windows();
1102
1103 if (get_thread_wsaved())
1104 goto sigsegv;
1105
1106 if (((unsigned long) c) & 3){
1107 printk("Unaligned structure passed\n");
1108 goto sigsegv;
1109 }
1110
1111 if (!__access_ok(c, sizeof(*c))) {
1112 /* Miguel, add nice debugging msg _here_. ;-) */
1113 goto sigsegv;
1114 }
1115
1116 /* Check for valid PC and nPC */
1117 gr = &c->mcontext.greg;
1118 err = __get_user(pc, &((*gr)[SVR4_PC]));
1119 err |= __get_user(npc, &((*gr)[SVR4_NPC]));
1120 if ((pc | npc) & 3)
1121 goto sigsegv;
1122
1123 /* Retrieve information from passed ucontext */
1124 /* note that nPC is ored a 1, this is used to inform entry.S */
1125 /* that we don't want it to mess with our PC and nPC */
1126
1127 err |= copy_from_user(&setv, &c->sigmask, sizeof(svr4_sigset_t));
1128 set.sig[0] = setv.sigbits[0] | (((long)setv.sigbits[1]) << 32);
1129 if (_NSIG_WORDS >= 2)
1130 set.sig[1] = setv.sigbits[2] | (((long)setv.sigbits[3]) << 32);
1131
1132 err |= __get_user(u_ss_sp, &c->stack.sp);
1133 st.ss_sp = compat_ptr(u_ss_sp);
1134 err |= __get_user(st.ss_flags, &c->stack.flags);
1135 err |= __get_user(st.ss_size, &c->stack.size);
1136 if (err)
1137 goto sigsegv;
1138
1139 /* It is more difficult to avoid calling this function than to
1140 call it and ignore errors. */
1141 old_fs = get_fs();
1142 set_fs(KERNEL_DS);
1143 do_sigaltstack((stack_t __user *) &st, NULL, regs->u_regs[UREG_I6]);
1144 set_fs(old_fs);
1145
1146 sigdelsetmask(&set, ~_BLOCKABLE);
1147 spin_lock_irq(&current->sighand->siglock);
1148 current->blocked = set;
1149 recalc_sigpending();
1150 spin_unlock_irq(&current->sighand->siglock);
1151 regs->tpc = pc;
1152 regs->tnpc = npc | 1;
1153 if (test_thread_flag(TIF_32BIT)) {
1154 regs->tpc &= 0xffffffff;
1155 regs->tnpc &= 0xffffffff;
1156 }
1157 err |= __get_user(regs->y, &((*gr)[SVR4_Y]));
1158 err |= __get_user(psr, &((*gr)[SVR4_PSR]));
1159 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
1160 regs->tstate |= psr_to_tstate_icc(psr);
1161
1162 /* Restore g[1..7] and o[0..7] registers */
1163 for (i = 0; i < 7; i++)
1164 err |= __get_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
1165 for (i = 0; i < 8; i++)
1166 err |= __get_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
1167 if (err)
1168 goto sigsegv;
1169
1170 return -EINTR;
1171sigsegv:
1172 return -EFAULT;
1173}
1174
1175static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
1176 unsigned long signr, sigset_t *oldset,
1177 siginfo_t *info)
1178{
1179 struct rt_signal_frame32 __user *sf;
1180 int sigframe_size;
1181 u32 psr;
1182 int i, err;
1183 compat_sigset_t seta;
1184
1185 /* 1. Make sure everything is clean */
1186 synchronize_user_stack();
1187 save_and_clear_fpu();
1188
1189 sigframe_size = RT_ALIGNEDSZ;
1190 if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
1191 sigframe_size -= sizeof(__siginfo_fpu_t);
1192
1193 sf = (struct rt_signal_frame32 __user *)
1194 get_sigframe(&ka->sa, regs, sigframe_size);
1195
1196 if (invalid_frame_pointer(sf, sigframe_size))
1197 goto sigill;
1198
1199 if (get_thread_wsaved() != 0)
1200 goto sigill;
1201
1202 /* 2. Save the current process state */
1203 if (test_thread_flag(TIF_32BIT)) {
1204 regs->tpc &= 0xffffffff;
1205 regs->tnpc &= 0xffffffff;
1206 }
1207 err = put_user(regs->tpc, &sf->regs.pc);
1208 err |= __put_user(regs->tnpc, &sf->regs.npc);
1209 err |= __put_user(regs->y, &sf->regs.y);
1210 psr = tstate_to_psr(regs->tstate);
1211 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
1212 psr |= PSR_EF;
1213 err |= __put_user(psr, &sf->regs.psr);
1214 for (i = 0; i < 16; i++)
1215 err |= __put_user(regs->u_regs[i], &sf->regs.u_regs[i]);
1216 err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
1217 err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
1218 for (i = 1; i < 16; i++)
1219 err |= __put_user(((u32 *)regs->u_regs)[2*i],
1220 &sf->v8plus.g_upper[i]);
1221 err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
1222 &sf->v8plus.asi);
1223
1224 if (psr & PSR_EF) {
1225 err |= save_fpu_state32(regs, &sf->fpu_state);
1226 err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
1227 } else {
1228 err |= __put_user(0, &sf->fpu_save);
1229 }
1230
1231 /* Update the siginfo structure. */
1232 err |= copy_siginfo_to_user32(&sf->info, info);
1233
1234 /* Setup sigaltstack */
1235 err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
1236 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
1237 err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
1238
1239 switch (_NSIG_WORDS) {
1240 case 4: seta.sig[7] = (oldset->sig[3] >> 32);
1241 seta.sig[6] = oldset->sig[3];
1242 case 3: seta.sig[5] = (oldset->sig[2] >> 32);
1243 seta.sig[4] = oldset->sig[2];
1244 case 2: seta.sig[3] = (oldset->sig[1] >> 32);
1245 seta.sig[2] = oldset->sig[1];
1246 case 1: seta.sig[1] = (oldset->sig[0] >> 32);
1247 seta.sig[0] = oldset->sig[0];
1248 }
1249 err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
1250
1251 err |= copy_in_user((u32 __user *)sf,
1252 (u32 __user *)(regs->u_regs[UREG_FP]),
1253 sizeof(struct reg_window32));
1254 if (err)
1255 goto sigsegv;
1256
1257 /* 3. signal handler back-trampoline and parameters */
1258 regs->u_regs[UREG_FP] = (unsigned long) sf;
1259 regs->u_regs[UREG_I0] = signr;
1260 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
1261 regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
1262
1263 /* 4. signal handler */
1264 regs->tpc = (unsigned long) ka->sa.sa_handler;
1265 regs->tnpc = (regs->tpc + 4);
1266 if (test_thread_flag(TIF_32BIT)) {
1267 regs->tpc &= 0xffffffff;
1268 regs->tnpc &= 0xffffffff;
1269 }
1270
1271 /* 5. return to kernel instructions */
1272 if (ka->ka_restorer)
1273 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
1274 else {
1275 /* Flush instruction space. */
1276 unsigned long address = ((unsigned long)&(sf->insns[0]));
1277 pgd_t *pgdp = pgd_offset(current->mm, address);
1278 pud_t *pudp = pud_offset(pgdp, address);
1279 pmd_t *pmdp = pmd_offset(pudp, address);
1280 pte_t *ptep;
1281
1282 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
1283
1284 /* mov __NR_rt_sigreturn, %g1 */
1285 err |= __put_user(0x82102065, &sf->insns[0]);
1286
1287 /* t 0x10 */
1288 err |= __put_user(0x91d02010, &sf->insns[1]);
1289 if (err)
1290 goto sigsegv;
1291
1292 preempt_disable();
1293 ptep = pte_offset_map(pmdp, address);
1294 if (pte_present(*ptep)) {
1295 unsigned long page = (unsigned long)
1296 page_address(pte_page(*ptep));
1297
4f07118f
DM
1298 wmb();
1299 __asm__ __volatile__("flush %0 + %1"
1300 : /* no outputs */
1301 : "r" (page),
1302 "r" (address & (PAGE_SIZE - 1))
1303 : "memory");
1da177e4
LT
1304 }
1305 pte_unmap(ptep);
1306 preempt_enable();
1307 }
1308 return;
1309
1310sigill:
1311 do_exit(SIGILL);
1312sigsegv:
1313 force_sigsegv(signr, current);
1314}
1315
1316static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
1317 siginfo_t *info,
1318 sigset_t *oldset, struct pt_regs *regs,
1319 int svr4_signal)
1320{
1321 if (svr4_signal)
1322 setup_svr4_frame32(&ka->sa, regs->tpc, regs->tnpc,
1323 regs, signr, oldset);
1324 else {
1325 if (ka->sa.sa_flags & SA_SIGINFO)
1326 setup_rt_frame32(ka, regs, signr, oldset, info);
1327 else if (test_thread_flag(TIF_NEWSIGNALS))
1328 new_setup_frame32(ka, regs, signr, oldset);
1329 else
1330 setup_frame32(&ka->sa, regs, signr, oldset, info);
1331 }
69be8f18
SR
1332 spin_lock_irq(&current->sighand->siglock);
1333 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
1334 if (!(ka->sa.sa_flags & SA_NOMASK))
1da177e4 1335 sigaddset(&current->blocked,signr);
69be8f18
SR
1336 recalc_sigpending();
1337 spin_unlock_irq(&current->sighand->siglock);
1da177e4
LT
1338}
1339
1340static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
1341 struct sigaction *sa)
1342{
1343 switch (regs->u_regs[UREG_I0]) {
1344 case ERESTART_RESTARTBLOCK:
1345 case ERESTARTNOHAND:
1346 no_system_call_restart:
1347 regs->u_regs[UREG_I0] = EINTR;
1348 regs->tstate |= TSTATE_ICARRY;
1349 break;
1350 case ERESTARTSYS:
1351 if (!(sa->sa_flags & SA_RESTART))
1352 goto no_system_call_restart;
1353 /* fallthrough */
1354 case ERESTARTNOINTR:
1355 regs->u_regs[UREG_I0] = orig_i0;
1356 regs->tpc -= 4;
1357 regs->tnpc -= 4;
1358 }
1359}
1360
1361/* Note that 'init' is a special process: it doesn't get signals it doesn't
1362 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1363 * mistake.
1364 */
1365int do_signal32(sigset_t *oldset, struct pt_regs * regs,
1366 unsigned long orig_i0, int restart_syscall)
1367{
1368 siginfo_t info;
1369 struct signal_deliver_cookie cookie;
1370 struct k_sigaction ka;
1371 int signr;
1372 int svr4_signal = current->personality == PER_SVR4;
1373
1374 cookie.restart_syscall = restart_syscall;
1375 cookie.orig_i0 = orig_i0;
1376
1377 signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
1378 if (signr > 0) {
1379 if (cookie.restart_syscall)
1380 syscall_restart32(orig_i0, regs, &ka.sa);
1381 handle_signal32(signr, &ka, &info, oldset,
1382 regs, svr4_signal);
1383 return 1;
1384 }
1385 if (cookie.restart_syscall &&
1386 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
1387 regs->u_regs[UREG_I0] == ERESTARTSYS ||
1388 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
1389 /* replay the system call when we are done */
1390 regs->u_regs[UREG_I0] = cookie.orig_i0;
1391 regs->tpc -= 4;
1392 regs->tnpc -= 4;
1393 }
1394 if (cookie.restart_syscall &&
1395 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
1396 regs->u_regs[UREG_G1] = __NR_restart_syscall;
1397 regs->tpc -= 4;
1398 regs->tnpc -= 4;
1399 }
1400 return 0;
1401}
1402
1403struct sigstack32 {
1404 u32 the_stack;
1405 int cur_status;
1406};
1407
1408asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
1409{
1410 struct sigstack32 __user *ssptr =
1411 (struct sigstack32 __user *)((unsigned long)(u_ssptr));
1412 struct sigstack32 __user *ossptr =
1413 (struct sigstack32 __user *)((unsigned long)(u_ossptr));
1414 int ret = -EFAULT;
1415
1416 /* First see if old state is wanted. */
1417 if (ossptr) {
1418 if (put_user(current->sas_ss_sp + current->sas_ss_size,
1419 &ossptr->the_stack) ||
1420 __put_user(on_sig_stack(sp), &ossptr->cur_status))
1421 goto out;
1422 }
1423
1424 /* Now see if we want to update the new state. */
1425 if (ssptr) {
1426 u32 ss_sp;
1427
1428 if (get_user(ss_sp, &ssptr->the_stack))
1429 goto out;
1430
1431 /* If the current stack was set with sigaltstack, don't
1432 * swap stacks while we are on it.
1433 */
1434 ret = -EPERM;
1435 if (current->sas_ss_sp && on_sig_stack(sp))
1436 goto out;
1437
1438 /* Since we don't know the extent of the stack, and we don't
1439 * track onstack-ness, but rather calculate it, we must
1440 * presume a size. Ho hum this interface is lossy.
1441 */
1442 current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
1443 current->sas_ss_size = SIGSTKSZ;
1444 }
1445
1446 ret = 0;
1447out:
1448 return ret;
1449}
1450
1451asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp)
1452{
1453 stack_t uss, uoss;
1454 u32 u_ss_sp = 0;
1455 int ret;
1456 mm_segment_t old_fs;
1457 stack_t32 __user *uss32 = compat_ptr(ussa);
1458 stack_t32 __user *uoss32 = compat_ptr(uossa);
1459
1460 if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) ||
1461 __get_user(uss.ss_flags, &uss32->ss_flags) ||
1462 __get_user(uss.ss_size, &uss32->ss_size)))
1463 return -EFAULT;
1464 uss.ss_sp = compat_ptr(u_ss_sp);
1465 old_fs = get_fs();
1466 set_fs(KERNEL_DS);
1467 ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL,
1468 uossa ? (stack_t __user *) &uoss : NULL, sp);
1469 set_fs(old_fs);
1470 if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) ||
1471 __put_user(uoss.ss_flags, &uoss32->ss_flags) ||
1472 __put_user(uoss.ss_size, &uoss32->ss_size)))
1473 return -EFAULT;
1474 return ret;
1475}