1
2
3
4
5
6
7
8
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/binfmts.h>
21#include <linux/compat.h>
22#include <linux/bitops.h>
23
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>
32
33#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49struct signal_sframe32 {
50 struct reg_window32 sig_window;
51 int sig_num;
52 int sig_code;
53 u32 sig_scptr;
54 int sig_address;
55 struct sigcontext32 sig_context;
56 unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
57};
58
59
60
61
62#define SIGINFO_EXTRA_V8PLUS_MAGIC 0x130e269
63typedef struct {
64 unsigned int g_upper[8];
65 unsigned int o_upper[8];
66 unsigned int asi;
67} siginfo_extra_v8plus_t;
68
69
70
71
72
73
74struct new_signal_frame32 {
75 struct sparc_stackf32 ss;
76 __siginfo32_t info;
77 u32 fpu_save;
78 unsigned int insns[2];
79 unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
80 unsigned int extra_size;
81
82 siginfo_extra_v8plus_t v8plus;
83 __siginfo_fpu_t fpu_state;
84};
85
86typedef struct compat_siginfo{
87 int si_signo;
88 int si_errno;
89 int si_code;
90
91 union {
92 int _pad[SI_PAD_SIZE32];
93
94
95 struct {
96 compat_pid_t _pid;
97 unsigned int _uid;
98 } _kill;
99
100
101 struct {
102 compat_timer_t _tid;
103 int _overrun;
104 compat_sigval_t _sigval;
105 int _sys_private;
106 } _timer;
107
108
109 struct {
110 compat_pid_t _pid;
111 unsigned int _uid;
112 compat_sigval_t _sigval;
113 } _rt;
114
115
116 struct {
117 compat_pid_t _pid;
118 unsigned int _uid;
119 int _status;
120 compat_clock_t _utime;
121 compat_clock_t _stime;
122 } _sigchld;
123
124
125 struct {
126 u32 _addr;
127 int _trapno;
128 } _sigfault;
129
130
131 struct {
132 int _band;
133 int _fd;
134 } _sigpoll;
135 } _sifields;
136}compat_siginfo_t;
137
138struct rt_signal_frame32 {
139 struct sparc_stackf32 ss;
140 compat_siginfo_t info;
141 struct pt_regs32 regs;
142 compat_sigset_t mask;
143 u32 fpu_save;
144 unsigned int insns[2];
145 stack_t32 stack;
146 unsigned int extra_size;
147
148 siginfo_extra_v8plus_t v8plus;
149 __siginfo_fpu_t fpu_state;
150};
151
152
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)))
156
157int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
158{
159 int err;
160
161 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
162 return -EFAULT;
163
164
165
166
167
168
169
170
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:
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;
205 }
206 }
207 return err;
208}
209
210
211
212
213int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
214{
215 if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
216 return -EFAULT;
217
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;
222
223 return 0;
224}
225
226static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
227{
228 unsigned long *fpregs = current_thread_info()->fpregs;
229 unsigned long fprs;
230 int err;
231
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;
243}
244
245void do_new_sigreturn32(struct pt_regs *regs)
246{
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;
253
254 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
255 sf = (struct new_signal_frame32 __user *) regs->u_regs[UREG_FP];
256
257
258 if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
259 (((unsigned long) sf) & 3))
260 goto segv;
261
262 get_user(pc, &sf->info.si_regs.pc);
263 __get_user(npc, &sf->info.si_regs.npc);
264
265 if ((pc | npc) & 3)
266 goto segv;
267
268 if (test_thread_flag(TIF_32BIT)) {
269 pc &= 0xffffffff;
270 npc &= 0xffffffff;
271 }
272 regs->tpc = pc;
273 regs->tnpc = npc;
274
275
276 err = __get_user(regs->y, &sf->info.si_regs.y);
277 err |= __get_user(psr, &sf->info.si_regs.psr);
278
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;
285
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);
291 }
292 }
293
294
295 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
296 regs->tstate |= psr_to_tstate_icc(psr);
297
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);
311 }
312 sigdelsetmask(&set, ~_BLOCKABLE);
313 spin_lock_irq(¤t->sighand->siglock);
314 current->blocked = set;
315 recalc_sigpending();
316 spin_unlock_irq(¤t->sighand->siglock);
317 return;
318
319segv:
320 force_sig(SIGSEGV, current);
321}
322
323asmlinkage void do_sigreturn32(struct pt_regs *regs)
324{
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;
330
331
332 current_thread_info()->restart_block.fn = do_no_restart_syscall;
333
334 synchronize_user_stack();
335 if (test_thread_flag(TIF_NEWSIGNALS)) {
336 do_new_sigreturn32(regs);
337 return;
338 }
339
340 scptr = (struct sigcontext32 __user *)
341 (regs->u_regs[UREG_I0] & 0x00000000ffffffffUL);
342
343 if (!access_ok(VERIFY_READ, scptr, sizeof(struct sigcontext32)) ||
344 (((unsigned long) scptr) & 3))
345 goto segv;
346
347 err = __get_user(pc, &scptr->sigc_pc);
348 err |= __get_user(npc, &scptr->sigc_npc);
349
350 if ((pc | npc) & 3)
351 goto segv;
352
353 err |= __get_user(seta[0], &scptr->sigc_mask);
354
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);
364 }
365 sigdelsetmask(&set, ~_BLOCKABLE);
366 spin_lock_irq(¤t->sighand->siglock);
367 current->blocked = set;
368 recalc_sigpending();
369 spin_unlock_irq(¤t->sighand->siglock);
370
371 if (test_thread_flag(TIF_32BIT)) {
372 pc &= 0xffffffff;
373 npc &= 0xffffffff;
374 }
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);
380
381
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;
388
389segv:
390 force_sig(SIGSEGV, current);
391}
392
393asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
394{
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;
402
403
404 current_thread_info()->restart_block.fn = do_no_restart_syscall;
405
406 synchronize_user_stack();
407 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
408 sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
409
410
411 if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
412 (((unsigned long) sf) & 3))
413 goto segv;
414
415 get_user(pc, &sf->regs.pc);
416 __get_user(npc, &sf->regs.npc);
417
418 if ((pc | npc) & 3)
419 goto segv;
420
421 if (test_thread_flag(TIF_32BIT)) {
422 pc &= 0xffffffff;
423 npc &= 0xffffffff;
424 }
425 regs->tpc = pc;
426 regs->tnpc = npc;
427
428
429 err = __get_user(regs->y, &sf->regs.y);
430 err |= __get_user(psr, &sf->regs.psr);
431
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;
438
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);
444 }
445 }
446
447
448 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
449 regs->tstate |= psr_to_tstate_icc(psr);
450
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;
461
462
463
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);
468
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);
474 }
475 sigdelsetmask(&set, ~_BLOCKABLE);
476 spin_lock_irq(¤t->sighand->siglock);
477 current->blocked = set;
478 recalc_sigpending();
479 spin_unlock_irq(¤t->sighand->siglock);
480 return;
481segv:
482 force_sig(SIGSEGV, current);
483}
484
485
486static int invalid_frame_pointer(void __user *fp, int fplen)
487{
488 if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
489 return 1;
490 return 0;
491}
492
493static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
494{
495 unsigned long sp;
496
497 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
498 sp = regs->u_regs[UREG_FP];
499
500
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;
504 }
505 return (void __user *)(sp - framesize);
506}
507
508static void
509setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info)
510{
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;
520
521 if (test_thread_flag(TIF_32BIT)) {
522 pc &= 0xffffffff;
523 npc &= 0xffffffff;
524 }
525
526 synchronize_user_stack();
527 save_and_clear_fpu();
528
529 sframep = (struct signal_sframe32 __user *)
530 get_sigframe(sa, regs, SF_ALIGNEDSZ);
531 if (invalid_frame_pointer(sframep, sizeof(*sframep))){
532
533
534
535 do_exit(SIGILL);
536 }
537
538 sc = &sframep->sig_context;
539
540
541 err = __put_user((sas_ss_flags(regs->u_regs[UREG_FP]) == SS_ONSTACK),
542 &sc->sigc_onstack);
543
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];
553 }
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);
567
568 err |= copy_in_user((u32 __user *)sframep,
569 (u32 __user *)(regs->u_regs[UREG_FP]),
570 sizeof(struct reg_window32));
571
572 set_thread_wsaved(0);
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;
583 }
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;
591 }
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;
603 }
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;
610 }
611 break;
612 case SIGEMT:
613 switch (info->si_code) {
614 case EMT_TAGOVF: sig_code = SUBSIG_TAG; break;
615 }
616 break;
617 case SIGSYS:
618 if (info->si_code == (__SI_FAULT|0x100)) {
619
620 sig_code = info->si_trapno;
621 break;
622 }
623 default:
624 sig_address = NULL;
625 }
626 }
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;
632
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;
639 }
640 return;
641
642sigsegv:
643 force_sigsegv(signr, current);
644}
645
646
647static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
648{
649 unsigned long *fpregs = current_thread_info()->fpregs;
650 unsigned long fprs;
651 int err = 0;
652
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);
663
664 return err;
665}
666
667static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
668 int signo, sigset_t *oldset)
669{
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];
675
676
677 synchronize_user_stack();
678 save_and_clear_fpu();
679
680 sigframe_size = NF_ALIGNEDSZ;
681 if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
682 sigframe_size -= sizeof(__siginfo_fpu_t);
683
684 sf = (struct new_signal_frame32 __user *)
685 get_sigframe(&ka->sa, regs, sigframe_size);
686
687 if (invalid_frame_pointer(sf, sigframe_size))
688 goto sigill;
689
690 if (get_thread_wsaved() != 0)
691 goto sigill;
692
693
694 if (test_thread_flag(TIF_32BIT)) {
695 regs->tpc &= 0xffffffff;
696 regs->tnpc &= 0xffffffff;
697 }
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);
714
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);
720 }
721
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];
731 }
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));
735
736 err |= copy_in_user((u32 __user *)sf,
737 (u32 __user *)(regs->u_regs[UREG_FP]),
738 sizeof(struct reg_window32));
739
740 if (err)
741 goto sigsegv;
742
743
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;
748
749
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;
755 }
756
757
758 if (ka->ka_restorer) {
759 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
760 } else {
761
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;
768
769 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
770
771 err = __put_user(0x821020d8, &sf->insns[0]);
772 err |= __put_user(0x91d02010, &sf->insns[1]);
773 if (err)
774 goto sigsegv;
775
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));
782
783 wmb();
784 __asm__ __volatile__("flush %0 + %1"
785 :
786 : "r" (page),
787 "r" (address & (PAGE_SIZE - 1))
788 : "memory");
789 }
790 pte_unmap(ptep);
791 preempt_enable();
792 }
793 return;
794
795sigill:
796 do_exit(SIGILL);
797sigsegv:
798 force_sigsegv(signo, current);
799}
800
801
802static void
803setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
804 struct pt_regs *regs, int signr, sigset_t *oldset)
805{
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;
815
816 synchronize_user_stack();
817 save_and_clear_fpu();
818
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);
823
824 if (invalid_frame_pointer(sfp, sizeof(*sfp)))
825 do_exit(SIGILL);
826
827
828 err = clear_user(sfp, sizeof(*sfp));
829
830
831 si = &sfp->si;
832 uc = &sfp->uc;
833 gw = &sfp->gw;
834 mc = &uc->mcontext;
835 gr = &mc->greg;
836
837
838
839
840
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));
850
851
852 if (test_thread_flag(TIF_32BIT)) {
853 regs->tpc &= 0xffffffff;
854 regs->tnpc &= 0xffffffff;
855 }
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]));
863
864
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);
869
870
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);
874
875
876
877
878 err |= __put_user(ptr_to_compat(gw), &mc->gwin);
879
880
881 err |= __put_user(get_thread_wsaved(), &gw->count);
882
883
884 set_thread_wsaved(0);
885
886
887
888
889
890 err |= __put_user(signr, &si->siginfo.signo);
891 err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
892 if (err)
893 goto sigsegv;
894
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;
901 }
902
903
904 if (regs->u_regs[14]){
905 struct reg_window32 __user *rw = (struct reg_window32 __user *)
906 (regs->u_regs[14] & 0x00000000ffffffffUL);
907
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]);
912 if (err)
913 goto sigsegv;
914
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;
918 }
919 return;
920
921sigsegv:
922 force_sigsegv(signr, current);
923}
924
925asmlinkage int
926svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs)
927{
928 svr4_gregset_t __user *gr;
929 svr4_mcontext_t __user *mc;
930 svr4_sigset_t setv;
931 int i, err;
932 u32 psr;
933
934 synchronize_user_stack();
935 save_and_clear_fpu();
936
937 if (get_thread_wsaved())
938 do_exit(SIGSEGV);
939
940 err = clear_user(uc, sizeof(*uc));
941
942
943 mc = &uc->mcontext;
944 gr = &mc->greg;
945
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));
954
955
956 if (test_thread_flag(TIF_32BIT)) {
957 regs->tpc &= 0xffffffff;
958 regs->tnpc &= 0xffffffff;
959 }
960 err |= __put_user(regs->tpc, &uc->mcontext.greg[SVR4_PC]);
961 err |= __put_user(regs->tnpc, &uc->mcontext.greg[SVR4_NPC]);
962
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]);
967
968 err |= __put_user(regs->y, &uc->mcontext.greg[SVR4_Y]);
969
970
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);
975
976
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);
980
981
982
983
984 return (err ? -EFAULT : 0);
985}
986
987
988
989asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
990{
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;
998
999
1000
1001
1002 flush_user_windows();
1003
1004 if (get_thread_wsaved())
1005 goto sigsegv;
1006
1007 if (((unsigned long) c) & 3){
1008 printk("Unaligned structure passed\n");
1009 goto sigsegv;
1010 }
1011
1012 if (!__access_ok(c, sizeof(*c))) {
1013
1014 goto sigsegv;
1015 }
1016
1017
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;
1023
1024
1025
1026
1027
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);
1032
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;
1039
1040
1041
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);
1046
1047 sigdelsetmask(&set, ~_BLOCKABLE);
1048 spin_lock_irq(¤t->sighand->siglock);
1049 current->blocked = set;
1050 recalc_sigpending();
1051 spin_unlock_irq(¤t->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;
1057 }
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);
1062
1063
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;
1070
1071 return -EINTR;
1072sigsegv:
1073 return -EFAULT;
1074}
1075
1076static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
1077 unsigned long signr, sigset_t *oldset,
1078 siginfo_t *info)
1079{
1080 struct rt_signal_frame32 __user *sf;
1081 int sigframe_size;
1082 u32 psr;
1083 int i, err;
1084 compat_sigset_t seta;
1085
1086
1087 synchronize_user_stack();
1088 save_and_clear_fpu();
1089
1090 sigframe_size = RT_ALIGNEDSZ;
1091 if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
1092 sigframe_size -= sizeof(__siginfo_fpu_t);
1093
1094 sf = (struct rt_signal_frame32 __user *)
1095 get_sigframe(&ka->sa, regs, sigframe_size);
1096
1097 if (invalid_frame_pointer(sf, sigframe_size))
1098 goto sigill;
1099
1100 if (get_thread_wsaved() != 0)
1101 goto sigill;
1102
1103
1104 if (test_thread_flag(TIF_32BIT)) {
1105 regs->tpc &= 0xffffffff;
1106 regs->tnpc &= 0xffffffff;
1107 }
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);
1124
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);
1130 }
1131
1132
1133 err |= copy_siginfo_to_user32(&sf->info, info);
1134
1135
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);
1139
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];
1149 }
1150 err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
1151
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;
1157
1158
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;
1163
1164
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;
1170 }
1171
1172
1173 if (ka->ka_restorer)
1174 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
1175 else {
1176
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;
1182
1183 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
1184
1185
1186 err |= __put_user(0x82102065, &sf->insns[0]);
1187
1188
1189 err |= __put_user(0x91d02010, &sf->insns[1]);
1190 if (err)
1191 goto sigsegv;
1192
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));
1198
1199 wmb();
1200 __asm__ __volatile__("flush %0 + %1"
1201 :
1202 : "r" (page),
1203 "r" (address & (PAGE_SIZE - 1))
1204 : "memory");
1205 }
1206 pte_unmap(ptep);
1207 preempt_enable();
1208 }
1209 return;
1210
1211sigill:
1212 do_exit(SIGILL);
1213sigsegv:
1214 force_sigsegv(signr, current);
1215}
1216
1217static 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)
1221{
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);
1232 }
1233 spin_lock_irq(¤t->sighand->siglock);
1234 sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
1235 if (!(ka->sa.sa_flags & SA_NOMASK))
1236 sigaddset(¤t->blocked,signr);
1237 recalc_sigpending();
1238 spin_unlock_irq(¤t->sighand->siglock);
1239}
1240
1241static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
1242 struct sigaction *sa)
1243{
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
1255 case ERESTARTNOINTR:
1256 regs->u_regs[UREG_I0] = orig_i0;
1257 regs->tpc -= 4;
1258 regs->tnpc -= 4;
1259 }
1260}
1261
1262
1263
1264
1265
1266void do_signal32(sigset_t *oldset, struct pt_regs * regs,
1267 unsigned long orig_i0, int restart_syscall)
1268{
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;
1274
1275 cookie.restart_syscall = restart_syscall;
1276 cookie.orig_i0 = orig_i0;
1277
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);
1284
1285
1286
1287
1288
1289
1290 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1291 clear_thread_flag(TIF_RESTORE_SIGMASK);
1292 return;
1293 }
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
1299 regs->u_regs[UREG_I0] = cookie.orig_i0;
1300 regs->tpc -= 4;
1301 regs->tnpc -= 4;
1302 }
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;
1308 }
1309
1310
1311
1312
1313 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
1314 clear_thread_flag(TIF_RESTORE_SIGMASK);
1315 sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
1316 }
1317}
1318
1319struct sigstack32 {
1320 u32 the_stack;
1321 int cur_status;
1322};
1323
1324asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
1325{
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;
1331
1332
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;
1338 }
1339
1340
1341 if (ssptr) {
1342 u32 ss_sp;
1343
1344 if (get_user(ss_sp, &ssptr->the_stack))
1345 goto out;
1346
1347
1348
1349
1350 ret = -EPERM;
1351 if (current->sas_ss_sp && on_sig_stack(sp))
1352 goto out;
1353
1354
1355
1356
1357
1358 current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
1359 current->sas_ss_size = SIGSTKSZ;
1360 }
1361
1362 ret = 0;
1363out:
1364 return ret;
1365}
1366
1367asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp)
1368{
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);
1375
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;
1391}
1392