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