1
2
3
4
5
6
7
8
9
10#include <linux/sched.h>
11#include <linux/kernel.h>
12#include <linux/signal.h>
13#include <linux/errno.h>
14#include <linux/wait.h>
15#include <linux/ptrace.h>
16#include <linux/unistd.h>
17#include <linux/mm.h>
18#include <linux/tty.h>
19#include <linux/binfmts.h>
20#include <linux/compat.h>
21#include <linux/bitops.h>
22#include <linux/tracehook.h>
23
24#include <linux/uaccess.h>
25#include <asm/ptrace.h>
26#include <asm/pgtable.h>
27#include <asm/psrcompat.h>
28#include <asm/fpumacro.h>
29#include <asm/visasm.h>
30#include <asm/compat_signal.h>
31#include <asm/switch_to.h>
32
33#include "sigutil.h"
34#include "kernel.h"
35
36
37
38
39#define SIGINFO_EXTRA_V8PLUS_MAGIC 0x130e269
40typedef struct {
41 unsigned int g_upper[8];
42 unsigned int o_upper[8];
43 unsigned int asi;
44} siginfo_extra_v8plus_t;
45
46struct signal_frame32 {
47 struct sparc_stackf32 ss;
48 __siginfo32_t info;
49 u32 fpu_save;
50 unsigned int insns[2];
51 unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
52 unsigned int extra_size;
53
54 siginfo_extra_v8plus_t v8plus;
55 u32 rwin_save;
56} __attribute__((aligned(8)));
57
58struct rt_signal_frame32 {
59 struct sparc_stackf32 ss;
60 compat_siginfo_t info;
61 struct pt_regs32 regs;
62 compat_sigset_t mask;
63 u32 fpu_save;
64 unsigned int insns[2];
65 compat_stack_t stack;
66 unsigned int extra_size;
67
68 siginfo_extra_v8plus_t v8plus;
69 u32 rwin_save;
70} __attribute__((aligned(8)));
71
72int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
73{
74 int err;
75
76 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
77 return -EFAULT;
78
79
80
81
82
83
84
85
86 err = __put_user(from->si_signo, &to->si_signo);
87 err |= __put_user(from->si_errno, &to->si_errno);
88 err |= __put_user((short)from->si_code, &to->si_code);
89 if (from->si_code < 0)
90 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
91 else {
92 switch (from->si_code >> 16) {
93 case __SI_TIMER >> 16:
94 err |= __put_user(from->si_tid, &to->si_tid);
95 err |= __put_user(from->si_overrun, &to->si_overrun);
96 err |= __put_user(from->si_int, &to->si_int);
97 break;
98 case __SI_CHLD >> 16:
99 err |= __put_user(from->si_utime, &to->si_utime);
100 err |= __put_user(from->si_stime, &to->si_stime);
101 err |= __put_user(from->si_status, &to->si_status);
102 default:
103 err |= __put_user(from->si_pid, &to->si_pid);
104 err |= __put_user(from->si_uid, &to->si_uid);
105 break;
106 case __SI_FAULT >> 16:
107 err |= __put_user(from->si_trapno, &to->si_trapno);
108 err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
109 break;
110 case __SI_POLL >> 16:
111 err |= __put_user(from->si_band, &to->si_band);
112 err |= __put_user(from->si_fd, &to->si_fd);
113 break;
114 case __SI_RT >> 16:
115 case __SI_MESGQ >> 16:
116 err |= __put_user(from->si_pid, &to->si_pid);
117 err |= __put_user(from->si_uid, &to->si_uid);
118 err |= __put_user(from->si_int, &to->si_int);
119 break;
120 }
121 }
122 return err;
123}
124
125
126
127
128int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
129{
130 if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
131 return -EFAULT;
132
133 if (copy_from_user(to, from, 3*sizeof(int)) ||
134 copy_from_user(to->_sifields._pad, from->_sifields._pad,
135 SI_PAD_SIZE))
136 return -EFAULT;
137
138 return 0;
139}
140
141
142
143
144
145static bool invalid_frame_pointer(void __user *fp, int fplen)
146{
147 if ((((unsigned long) fp) & 15) ||
148 ((unsigned long)fp) > 0x100000000ULL - fplen)
149 return true;
150 return false;
151}
152
153void do_sigreturn32(struct pt_regs *regs)
154{
155 struct signal_frame32 __user *sf;
156 compat_uptr_t fpu_save;
157 compat_uptr_t rwin_save;
158 unsigned int psr, ufp;
159 unsigned int pc, npc;
160 sigset_t set;
161 compat_sigset_t seta;
162 int err, i;
163
164
165 current->restart_block.fn = do_no_restart_syscall;
166
167 synchronize_user_stack();
168
169 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
170 sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
171
172
173 if (invalid_frame_pointer(sf, sizeof(*sf)))
174 goto segv;
175
176 if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
177 goto segv;
178
179 if (ufp & 0x7)
180 goto segv;
181
182 if (__get_user(pc, &sf->info.si_regs.pc) ||
183 __get_user(npc, &sf->info.si_regs.npc))
184 goto segv;
185
186 if ((pc | npc) & 3)
187 goto segv;
188
189 if (test_thread_flag(TIF_32BIT)) {
190 pc &= 0xffffffff;
191 npc &= 0xffffffff;
192 }
193 regs->tpc = pc;
194 regs->tnpc = npc;
195
196
197 err = __get_user(regs->y, &sf->info.si_regs.y);
198 err |= __get_user(psr, &sf->info.si_regs.psr);
199
200 for (i = UREG_G1; i <= UREG_I7; i++)
201 err |= __get_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
202 if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
203 err |= __get_user(i, &sf->v8plus.g_upper[0]);
204 if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
205 unsigned long asi;
206
207 for (i = UREG_G1; i <= UREG_I7; i++)
208 err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
209 err |= __get_user(asi, &sf->v8plus.asi);
210 regs->tstate &= ~TSTATE_ASI;
211 regs->tstate |= ((asi & 0xffUL) << 24UL);
212 }
213 }
214
215
216 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
217 regs->tstate |= psr_to_tstate_icc(psr);
218
219
220 pt_regs_clear_syscall(regs);
221
222 err |= __get_user(fpu_save, &sf->fpu_save);
223 if (!err && fpu_save)
224 err |= restore_fpu_state(regs, compat_ptr(fpu_save));
225 err |= __get_user(rwin_save, &sf->rwin_save);
226 if (!err && rwin_save) {
227 if (restore_rwin_state(compat_ptr(rwin_save)))
228 goto segv;
229 }
230 err |= __get_user(seta.sig[0], &sf->info.si_mask);
231 err |= copy_from_user(&seta.sig[1], &sf->extramask,
232 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
233 if (err)
234 goto segv;
235
236 set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
237 set_current_blocked(&set);
238 return;
239
240segv:
241 force_sig(SIGSEGV, current);
242}
243
244asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
245{
246 struct rt_signal_frame32 __user *sf;
247 unsigned int psr, pc, npc, ufp;
248 compat_uptr_t fpu_save;
249 compat_uptr_t rwin_save;
250 sigset_t set;
251 compat_sigset_t seta;
252 int err, i;
253
254
255 current->restart_block.fn = do_no_restart_syscall;
256
257 synchronize_user_stack();
258 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
259 sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
260
261
262 if (invalid_frame_pointer(sf, sizeof(*sf)))
263 goto segv;
264
265 if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
266 goto segv;
267
268 if (ufp & 0x7)
269 goto segv;
270
271 if (__get_user(pc, &sf->regs.pc) ||
272 __get_user(npc, &sf->regs.npc))
273 goto segv;
274
275 if ((pc | npc) & 3)
276 goto segv;
277
278 if (test_thread_flag(TIF_32BIT)) {
279 pc &= 0xffffffff;
280 npc &= 0xffffffff;
281 }
282 regs->tpc = pc;
283 regs->tnpc = npc;
284
285
286 err = __get_user(regs->y, &sf->regs.y);
287 err |= __get_user(psr, &sf->regs.psr);
288
289 for (i = UREG_G1; i <= UREG_I7; i++)
290 err |= __get_user(regs->u_regs[i], &sf->regs.u_regs[i]);
291 if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
292 err |= __get_user(i, &sf->v8plus.g_upper[0]);
293 if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
294 unsigned long asi;
295
296 for (i = UREG_G1; i <= UREG_I7; i++)
297 err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
298 err |= __get_user(asi, &sf->v8plus.asi);
299 regs->tstate &= ~TSTATE_ASI;
300 regs->tstate |= ((asi & 0xffUL) << 24UL);
301 }
302 }
303
304
305 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
306 regs->tstate |= psr_to_tstate_icc(psr);
307
308
309 pt_regs_clear_syscall(regs);
310
311 err |= __get_user(fpu_save, &sf->fpu_save);
312 if (!err && fpu_save)
313 err |= restore_fpu_state(regs, compat_ptr(fpu_save));
314 err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
315 err |= compat_restore_altstack(&sf->stack);
316 if (err)
317 goto segv;
318
319 err |= __get_user(rwin_save, &sf->rwin_save);
320 if (!err && rwin_save) {
321 if (restore_rwin_state(compat_ptr(rwin_save)))
322 goto segv;
323 }
324
325 set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
326 set_current_blocked(&set);
327 return;
328segv:
329 force_sig(SIGSEGV, current);
330}
331
332static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
333{
334 unsigned long sp;
335
336 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
337 sp = regs->u_regs[UREG_FP];
338
339
340
341
342
343 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
344 return (void __user *) -1L;
345
346
347 sp = sigsp(sp, ksig) - framesize;
348
349
350
351
352
353
354
355 sp &= ~15UL;
356
357 return (void __user *) sp;
358}
359
360
361
362
363
364
365
366
367static void flush_signal_insns(unsigned long address)
368{
369 unsigned long pstate, paddr;
370 pte_t *ptep, pte;
371 pgd_t *pgdp;
372 pud_t *pudp;
373 pmd_t *pmdp;
374
375
376 wmb();
377
378
379
380
381
382
383
384 __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
385 __asm__ __volatile__("wrpr %0, %1, %%pstate"
386 : : "r" (pstate), "i" (PSTATE_IE));
387
388 pgdp = pgd_offset(current->mm, address);
389 if (pgd_none(*pgdp))
390 goto out_irqs_on;
391 pudp = pud_offset(pgdp, address);
392 if (pud_none(*pudp))
393 goto out_irqs_on;
394 pmdp = pmd_offset(pudp, address);
395 if (pmd_none(*pmdp))
396 goto out_irqs_on;
397
398 ptep = pte_offset_map(pmdp, address);
399 pte = *ptep;
400 if (!pte_present(pte))
401 goto out_unmap;
402
403 paddr = (unsigned long) page_address(pte_page(pte));
404
405 __asm__ __volatile__("flush %0 + %1"
406 :
407 : "r" (paddr),
408 "r" (address & (PAGE_SIZE - 1))
409 : "memory");
410
411out_unmap:
412 pte_unmap(ptep);
413out_irqs_on:
414 __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
415
416}
417
418static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs,
419 sigset_t *oldset)
420{
421 struct signal_frame32 __user *sf;
422 int i, err, wsaved;
423 void __user *tail;
424 int sigframe_size;
425 u32 psr;
426 compat_sigset_t seta;
427
428
429 synchronize_user_stack();
430 save_and_clear_fpu();
431
432 wsaved = get_thread_wsaved();
433
434 sigframe_size = sizeof(*sf);
435 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
436 sigframe_size += sizeof(__siginfo_fpu_t);
437 if (wsaved)
438 sigframe_size += sizeof(__siginfo_rwin_t);
439
440 sf = (struct signal_frame32 __user *)
441 get_sigframe(ksig, regs, sigframe_size);
442
443 if (invalid_frame_pointer(sf, sigframe_size)) {
444 do_exit(SIGILL);
445 return -EINVAL;
446 }
447
448 tail = (sf + 1);
449
450
451 if (test_thread_flag(TIF_32BIT)) {
452 regs->tpc &= 0xffffffff;
453 regs->tnpc &= 0xffffffff;
454 }
455 err = put_user(regs->tpc, &sf->info.si_regs.pc);
456 err |= __put_user(regs->tnpc, &sf->info.si_regs.npc);
457 err |= __put_user(regs->y, &sf->info.si_regs.y);
458 psr = tstate_to_psr(regs->tstate);
459 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
460 psr |= PSR_EF;
461 err |= __put_user(psr, &sf->info.si_regs.psr);
462 for (i = 0; i < 16; i++)
463 err |= __put_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
464 err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
465 err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
466 for (i = 1; i < 16; i++)
467 err |= __put_user(((u32 *)regs->u_regs)[2*i],
468 &sf->v8plus.g_upper[i]);
469 err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
470 &sf->v8plus.asi);
471
472 if (psr & PSR_EF) {
473 __siginfo_fpu_t __user *fp = tail;
474 tail += sizeof(*fp);
475 err |= save_fpu_state(regs, fp);
476 err |= __put_user((u64)fp, &sf->fpu_save);
477 } else {
478 err |= __put_user(0, &sf->fpu_save);
479 }
480 if (wsaved) {
481 __siginfo_rwin_t __user *rwp = tail;
482 tail += sizeof(*rwp);
483 err |= save_rwin_state(wsaved, rwp);
484 err |= __put_user((u64)rwp, &sf->rwin_save);
485 set_thread_wsaved(0);
486 } else {
487 err |= __put_user(0, &sf->rwin_save);
488 }
489
490
491 BUILD_BUG_ON(_NSIG_WORDS != 1);
492 BUILD_BUG_ON(_COMPAT_NSIG_WORDS != 2);
493 seta.sig[1] = (oldset->sig[0] >> 32);
494 seta.sig[0] = oldset->sig[0];
495
496 err |= __put_user(seta.sig[0], &sf->info.si_mask);
497 err |= __copy_to_user(sf->extramask, &seta.sig[1],
498 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
499
500 if (!wsaved) {
501 err |= copy_in_user((u32 __user *)sf,
502 (u32 __user *)(regs->u_regs[UREG_FP]),
503 sizeof(struct reg_window32));
504 } else {
505 struct reg_window *rp;
506
507 rp = ¤t_thread_info()->reg_window[wsaved - 1];
508 for (i = 0; i < 8; i++)
509 err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
510 for (i = 0; i < 6; i++)
511 err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
512 err |= __put_user(rp->ins[6], &sf->ss.fp);
513 err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
514 }
515 if (err)
516 return err;
517
518
519 regs->u_regs[UREG_FP] = (unsigned long) sf;
520 regs->u_regs[UREG_I0] = ksig->sig;
521 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
522 regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
523
524
525 regs->tpc = (unsigned long) ksig->ka.sa.sa_handler;
526 regs->tnpc = (regs->tpc + 4);
527 if (test_thread_flag(TIF_32BIT)) {
528 regs->tpc &= 0xffffffff;
529 regs->tnpc &= 0xffffffff;
530 }
531
532
533 if (ksig->ka.ka_restorer) {
534 regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
535 } else {
536 unsigned long address = ((unsigned long)&(sf->insns[0]));
537
538 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
539
540 err = __put_user(0x821020d8, &sf->insns[0]);
541 err |= __put_user(0x91d02010, &sf->insns[1]);
542 if (err)
543 return err;
544 flush_signal_insns(address);
545 }
546 return 0;
547}
548
549static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs,
550 sigset_t *oldset)
551{
552 struct rt_signal_frame32 __user *sf;
553 int i, err, wsaved;
554 void __user *tail;
555 int sigframe_size;
556 u32 psr;
557 compat_sigset_t seta;
558
559
560 synchronize_user_stack();
561 save_and_clear_fpu();
562
563 wsaved = get_thread_wsaved();
564
565 sigframe_size = sizeof(*sf);
566 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
567 sigframe_size += sizeof(__siginfo_fpu_t);
568 if (wsaved)
569 sigframe_size += sizeof(__siginfo_rwin_t);
570
571 sf = (struct rt_signal_frame32 __user *)
572 get_sigframe(ksig, regs, sigframe_size);
573
574 if (invalid_frame_pointer(sf, sigframe_size)) {
575 do_exit(SIGILL);
576 return -EINVAL;
577 }
578
579 tail = (sf + 1);
580
581
582 if (test_thread_flag(TIF_32BIT)) {
583 regs->tpc &= 0xffffffff;
584 regs->tnpc &= 0xffffffff;
585 }
586 err = put_user(regs->tpc, &sf->regs.pc);
587 err |= __put_user(regs->tnpc, &sf->regs.npc);
588 err |= __put_user(regs->y, &sf->regs.y);
589 psr = tstate_to_psr(regs->tstate);
590 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
591 psr |= PSR_EF;
592 err |= __put_user(psr, &sf->regs.psr);
593 for (i = 0; i < 16; i++)
594 err |= __put_user(regs->u_regs[i], &sf->regs.u_regs[i]);
595 err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
596 err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
597 for (i = 1; i < 16; i++)
598 err |= __put_user(((u32 *)regs->u_regs)[2*i],
599 &sf->v8plus.g_upper[i]);
600 err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
601 &sf->v8plus.asi);
602
603 if (psr & PSR_EF) {
604 __siginfo_fpu_t __user *fp = tail;
605 tail += sizeof(*fp);
606 err |= save_fpu_state(regs, fp);
607 err |= __put_user((u64)fp, &sf->fpu_save);
608 } else {
609 err |= __put_user(0, &sf->fpu_save);
610 }
611 if (wsaved) {
612 __siginfo_rwin_t __user *rwp = tail;
613 tail += sizeof(*rwp);
614 err |= save_rwin_state(wsaved, rwp);
615 err |= __put_user((u64)rwp, &sf->rwin_save);
616 set_thread_wsaved(0);
617 } else {
618 err |= __put_user(0, &sf->rwin_save);
619 }
620
621
622 err |= copy_siginfo_to_user32(&sf->info, &ksig->info);
623
624
625 err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
626
627 seta.sig[1] = (oldset->sig[0] >> 32);
628 seta.sig[0] = oldset->sig[0];
629 err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
630
631 if (!wsaved) {
632 err |= copy_in_user((u32 __user *)sf,
633 (u32 __user *)(regs->u_regs[UREG_FP]),
634 sizeof(struct reg_window32));
635 } else {
636 struct reg_window *rp;
637
638 rp = ¤t_thread_info()->reg_window[wsaved - 1];
639 for (i = 0; i < 8; i++)
640 err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
641 for (i = 0; i < 6; i++)
642 err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
643 err |= __put_user(rp->ins[6], &sf->ss.fp);
644 err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
645 }
646 if (err)
647 return err;
648
649
650 regs->u_regs[UREG_FP] = (unsigned long) sf;
651 regs->u_regs[UREG_I0] = ksig->sig;
652 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
653 regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
654
655
656 regs->tpc = (unsigned long) ksig->ka.sa.sa_handler;
657 regs->tnpc = (regs->tpc + 4);
658 if (test_thread_flag(TIF_32BIT)) {
659 regs->tpc &= 0xffffffff;
660 regs->tnpc &= 0xffffffff;
661 }
662
663
664 if (ksig->ka.ka_restorer)
665 regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
666 else {
667 unsigned long address = ((unsigned long)&(sf->insns[0]));
668
669 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
670
671
672 err |= __put_user(0x82102065, &sf->insns[0]);
673
674
675 err |= __put_user(0x91d02010, &sf->insns[1]);
676 if (err)
677 return err;
678
679 flush_signal_insns(address);
680 }
681 return 0;
682}
683
684static inline void handle_signal32(struct ksignal *ksig,
685 struct pt_regs *regs)
686{
687 sigset_t *oldset = sigmask_to_save();
688 int err;
689
690 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
691 err = setup_rt_frame32(ksig, regs, oldset);
692 else
693 err = setup_frame32(ksig, regs, oldset);
694
695 signal_setup_done(err, ksig, 0);
696}
697
698static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
699 struct sigaction *sa)
700{
701 switch (regs->u_regs[UREG_I0]) {
702 case ERESTART_RESTARTBLOCK:
703 case ERESTARTNOHAND:
704 no_system_call_restart:
705 regs->u_regs[UREG_I0] = EINTR;
706 regs->tstate |= TSTATE_ICARRY;
707 break;
708 case ERESTARTSYS:
709 if (!(sa->sa_flags & SA_RESTART))
710 goto no_system_call_restart;
711
712 case ERESTARTNOINTR:
713 regs->u_regs[UREG_I0] = orig_i0;
714 regs->tpc -= 4;
715 regs->tnpc -= 4;
716 }
717}
718
719
720
721
722
723void do_signal32(struct pt_regs * regs)
724{
725 struct ksignal ksig;
726 unsigned long orig_i0 = 0;
727 int restart_syscall = 0;
728 bool has_handler = get_signal(&ksig);
729
730 if (pt_regs_is_syscall(regs) &&
731 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
732 restart_syscall = 1;
733 orig_i0 = regs->u_regs[UREG_G6];
734 }
735
736 if (has_handler) {
737 if (restart_syscall)
738 syscall_restart32(orig_i0, regs, &ksig.ka.sa);
739 handle_signal32(&ksig, regs);
740 } else {
741 if (restart_syscall) {
742 switch (regs->u_regs[UREG_I0]) {
743 case ERESTARTNOHAND:
744 case ERESTARTSYS:
745 case ERESTARTNOINTR:
746
747 regs->u_regs[UREG_I0] = orig_i0;
748 regs->tpc -= 4;
749 regs->tnpc -= 4;
750 pt_regs_clear_syscall(regs);
751 case ERESTART_RESTARTBLOCK:
752 regs->u_regs[UREG_G1] = __NR_restart_syscall;
753 regs->tpc -= 4;
754 regs->tnpc -= 4;
755 pt_regs_clear_syscall(regs);
756 }
757 }
758 restore_saved_sigmask();
759 }
760}
761
762struct sigstack32 {
763 u32 the_stack;
764 int cur_status;
765};
766
767asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
768{
769 struct sigstack32 __user *ssptr =
770 (struct sigstack32 __user *)((unsigned long)(u_ssptr));
771 struct sigstack32 __user *ossptr =
772 (struct sigstack32 __user *)((unsigned long)(u_ossptr));
773 int ret = -EFAULT;
774
775
776 if (ossptr) {
777 if (put_user(current->sas_ss_sp + current->sas_ss_size,
778 &ossptr->the_stack) ||
779 __put_user(on_sig_stack(sp), &ossptr->cur_status))
780 goto out;
781 }
782
783
784 if (ssptr) {
785 u32 ss_sp;
786
787 if (get_user(ss_sp, &ssptr->the_stack))
788 goto out;
789
790
791
792
793 ret = -EPERM;
794 if (current->sas_ss_sp && on_sig_stack(sp))
795 goto out;
796
797
798
799
800
801 current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
802 current->sas_ss_size = SIGSTKSZ;
803 }
804
805 ret = 0;
806out:
807 return ret;
808}
809