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
32#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
33
34
35
36
37#define SIGINFO_EXTRA_V8PLUS_MAGIC 0x130e269
38typedef struct {
39 unsigned int g_upper[8];
40 unsigned int o_upper[8];
41 unsigned int asi;
42} siginfo_extra_v8plus_t;
43
44struct signal_frame32 {
45 struct sparc_stackf32 ss;
46 __siginfo32_t info;
47 u32 fpu_save;
48 unsigned int insns[2];
49 unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
50 unsigned int extra_size;
51
52 siginfo_extra_v8plus_t v8plus;
53 __siginfo_fpu_t fpu_state;
54};
55
56typedef struct compat_siginfo{
57 int si_signo;
58 int si_errno;
59 int si_code;
60
61 union {
62 int _pad[SI_PAD_SIZE32];
63
64
65 struct {
66 compat_pid_t _pid;
67 unsigned int _uid;
68 } _kill;
69
70
71 struct {
72 compat_timer_t _tid;
73 int _overrun;
74 compat_sigval_t _sigval;
75 int _sys_private;
76 } _timer;
77
78
79 struct {
80 compat_pid_t _pid;
81 unsigned int _uid;
82 compat_sigval_t _sigval;
83 } _rt;
84
85
86 struct {
87 compat_pid_t _pid;
88 unsigned int _uid;
89 int _status;
90 compat_clock_t _utime;
91 compat_clock_t _stime;
92 } _sigchld;
93
94
95 struct {
96 u32 _addr;
97 int _trapno;
98 } _sigfault;
99
100
101 struct {
102 int _band;
103 int _fd;
104 } _sigpoll;
105 } _sifields;
106}compat_siginfo_t;
107
108struct rt_signal_frame32 {
109 struct sparc_stackf32 ss;
110 compat_siginfo_t info;
111 struct pt_regs32 regs;
112 compat_sigset_t mask;
113 u32 fpu_save;
114 unsigned int insns[2];
115 stack_t32 stack;
116 unsigned int extra_size;
117
118 siginfo_extra_v8plus_t v8plus;
119 __siginfo_fpu_t fpu_state;
120};
121
122
123#define SF_ALIGNEDSZ (((sizeof(struct signal_frame32) + 7) & (~7)))
124#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
125
126int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
127{
128 int err;
129
130 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
131 return -EFAULT;
132
133
134
135
136
137
138
139
140 err = __put_user(from->si_signo, &to->si_signo);
141 err |= __put_user(from->si_errno, &to->si_errno);
142 err |= __put_user((short)from->si_code, &to->si_code);
143 if (from->si_code < 0)
144 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
145 else {
146 switch (from->si_code >> 16) {
147 case __SI_TIMER >> 16:
148 err |= __put_user(from->si_tid, &to->si_tid);
149 err |= __put_user(from->si_overrun, &to->si_overrun);
150 err |= __put_user(from->si_int, &to->si_int);
151 break;
152 case __SI_CHLD >> 16:
153 err |= __put_user(from->si_utime, &to->si_utime);
154 err |= __put_user(from->si_stime, &to->si_stime);
155 err |= __put_user(from->si_status, &to->si_status);
156 default:
157 err |= __put_user(from->si_pid, &to->si_pid);
158 err |= __put_user(from->si_uid, &to->si_uid);
159 break;
160 case __SI_FAULT >> 16:
161 err |= __put_user(from->si_trapno, &to->si_trapno);
162 err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
163 break;
164 case __SI_POLL >> 16:
165 err |= __put_user(from->si_band, &to->si_band);
166 err |= __put_user(from->si_fd, &to->si_fd);
167 break;
168 case __SI_RT >> 16:
169 case __SI_MESGQ >> 16:
170 err |= __put_user(from->si_pid, &to->si_pid);
171 err |= __put_user(from->si_uid, &to->si_uid);
172 err |= __put_user(from->si_int, &to->si_int);
173 break;
174 }
175 }
176 return err;
177}
178
179
180
181
182int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
183{
184 if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
185 return -EFAULT;
186
187 if (copy_from_user(to, from, 3*sizeof(int)) ||
188 copy_from_user(to->_sifields._pad, from->_sifields._pad,
189 SI_PAD_SIZE))
190 return -EFAULT;
191
192 return 0;
193}
194
195static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
196{
197 unsigned long *fpregs = current_thread_info()->fpregs;
198 unsigned long fprs;
199 int err;
200
201 err = __get_user(fprs, &fpu->si_fprs);
202 fprs_write(0);
203 regs->tstate &= ~TSTATE_PEF;
204 if (fprs & FPRS_DL)
205 err |= copy_from_user(fpregs, &fpu->si_float_regs[0], (sizeof(unsigned int) * 32));
206 if (fprs & FPRS_DU)
207 err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], (sizeof(unsigned int) * 32));
208 err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
209 err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
210 current_thread_info()->fpsaved[0] |= fprs;
211 return err;
212}
213
214void do_sigreturn32(struct pt_regs *regs)
215{
216 struct signal_frame32 __user *sf;
217 unsigned int psr;
218 unsigned pc, npc, fpu_save;
219 sigset_t set;
220 unsigned seta[_COMPAT_NSIG_WORDS];
221 int err, i;
222
223
224 current_thread_info()->restart_block.fn = do_no_restart_syscall;
225
226 synchronize_user_stack();
227
228 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
229 sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
230
231
232 if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
233 (((unsigned long) sf) & 3))
234 goto segv;
235
236 get_user(pc, &sf->info.si_regs.pc);
237 __get_user(npc, &sf->info.si_regs.npc);
238
239 if ((pc | npc) & 3)
240 goto segv;
241
242 if (test_thread_flag(TIF_32BIT)) {
243 pc &= 0xffffffff;
244 npc &= 0xffffffff;
245 }
246 regs->tpc = pc;
247 regs->tnpc = npc;
248
249
250 err = __get_user(regs->y, &sf->info.si_regs.y);
251 err |= __get_user(psr, &sf->info.si_regs.psr);
252
253 for (i = UREG_G1; i <= UREG_I7; i++)
254 err |= __get_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
255 if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
256 err |= __get_user(i, &sf->v8plus.g_upper[0]);
257 if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
258 unsigned long asi;
259
260 for (i = UREG_G1; i <= UREG_I7; i++)
261 err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
262 err |= __get_user(asi, &sf->v8plus.asi);
263 regs->tstate &= ~TSTATE_ASI;
264 regs->tstate |= ((asi & 0xffUL) << 24UL);
265 }
266 }
267
268
269 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
270 regs->tstate |= psr_to_tstate_icc(psr);
271
272
273 pt_regs_clear_syscall(regs);
274
275 err |= __get_user(fpu_save, &sf->fpu_save);
276 if (fpu_save)
277 err |= restore_fpu_state32(regs, &sf->fpu_state);
278 err |= __get_user(seta[0], &sf->info.si_mask);
279 err |= copy_from_user(seta+1, &sf->extramask,
280 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
281 if (err)
282 goto segv;
283 switch (_NSIG_WORDS) {
284 case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32);
285 case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32);
286 case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
287 case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
288 }
289 sigdelsetmask(&set, ~_BLOCKABLE);
290 spin_lock_irq(¤t->sighand->siglock);
291 current->blocked = set;
292 recalc_sigpending();
293 spin_unlock_irq(¤t->sighand->siglock);
294 return;
295
296segv:
297 force_sig(SIGSEGV, current);
298}
299
300asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
301{
302 struct rt_signal_frame32 __user *sf;
303 unsigned int psr, pc, npc, fpu_save, u_ss_sp;
304 mm_segment_t old_fs;
305 sigset_t set;
306 compat_sigset_t seta;
307 stack_t st;
308 int err, i;
309
310
311 current_thread_info()->restart_block.fn = do_no_restart_syscall;
312
313 synchronize_user_stack();
314 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
315 sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
316
317
318 if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
319 (((unsigned long) sf) & 3))
320 goto segv;
321
322 get_user(pc, &sf->regs.pc);
323 __get_user(npc, &sf->regs.npc);
324
325 if ((pc | npc) & 3)
326 goto segv;
327
328 if (test_thread_flag(TIF_32BIT)) {
329 pc &= 0xffffffff;
330 npc &= 0xffffffff;
331 }
332 regs->tpc = pc;
333 regs->tnpc = npc;
334
335
336 err = __get_user(regs->y, &sf->regs.y);
337 err |= __get_user(psr, &sf->regs.psr);
338
339 for (i = UREG_G1; i <= UREG_I7; i++)
340 err |= __get_user(regs->u_regs[i], &sf->regs.u_regs[i]);
341 if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
342 err |= __get_user(i, &sf->v8plus.g_upper[0]);
343 if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
344 unsigned long asi;
345
346 for (i = UREG_G1; i <= UREG_I7; i++)
347 err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
348 err |= __get_user(asi, &sf->v8plus.asi);
349 regs->tstate &= ~TSTATE_ASI;
350 regs->tstate |= ((asi & 0xffUL) << 24UL);
351 }
352 }
353
354
355 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
356 regs->tstate |= psr_to_tstate_icc(psr);
357
358
359 pt_regs_clear_syscall(regs);
360
361 err |= __get_user(fpu_save, &sf->fpu_save);
362 if (fpu_save)
363 err |= restore_fpu_state32(regs, &sf->fpu_state);
364 err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
365 err |= __get_user(u_ss_sp, &sf->stack.ss_sp);
366 st.ss_sp = compat_ptr(u_ss_sp);
367 err |= __get_user(st.ss_flags, &sf->stack.ss_flags);
368 err |= __get_user(st.ss_size, &sf->stack.ss_size);
369 if (err)
370 goto segv;
371
372
373
374 old_fs = get_fs();
375 set_fs(KERNEL_DS);
376 do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf);
377 set_fs(old_fs);
378
379 switch (_NSIG_WORDS) {
380 case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32);
381 case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32);
382 case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32);
383 case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
384 }
385 sigdelsetmask(&set, ~_BLOCKABLE);
386 spin_lock_irq(¤t->sighand->siglock);
387 current->blocked = set;
388 recalc_sigpending();
389 spin_unlock_irq(¤t->sighand->siglock);
390 return;
391segv:
392 force_sig(SIGSEGV, current);
393}
394
395
396static int invalid_frame_pointer(void __user *fp, int fplen)
397{
398 if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
399 return 1;
400 return 0;
401}
402
403static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
404{
405 unsigned long sp;
406
407 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
408 sp = regs->u_regs[UREG_FP];
409
410
411
412
413
414 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
415 return (void __user *) -1L;
416
417
418 if (sa->sa_flags & SA_ONSTACK) {
419 if (sas_ss_flags(sp) == 0)
420 sp = current->sas_ss_sp + current->sas_ss_size;
421 }
422
423
424
425
426
427
428
429 sp &= ~7UL;
430
431 return (void __user *)(sp - framesize);
432}
433
434static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
435{
436 unsigned long *fpregs = current_thread_info()->fpregs;
437 unsigned long fprs;
438 int err = 0;
439
440 fprs = current_thread_info()->fpsaved[0];
441 if (fprs & FPRS_DL)
442 err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
443 (sizeof(unsigned int) * 32));
444 if (fprs & FPRS_DU)
445 err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
446 (sizeof(unsigned int) * 32));
447 err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
448 err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
449 err |= __put_user(fprs, &fpu->si_fprs);
450
451 return err;
452}
453
454static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
455 int signo, sigset_t *oldset)
456{
457 struct signal_frame32 __user *sf;
458 int sigframe_size;
459 u32 psr;
460 int i, err;
461 unsigned int seta[_COMPAT_NSIG_WORDS];
462
463
464 synchronize_user_stack();
465 save_and_clear_fpu();
466
467 sigframe_size = SF_ALIGNEDSZ;
468 if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
469 sigframe_size -= sizeof(__siginfo_fpu_t);
470
471 sf = (struct signal_frame32 __user *)
472 get_sigframe(&ka->sa, regs, sigframe_size);
473
474 if (invalid_frame_pointer(sf, sigframe_size))
475 goto sigill;
476
477 if (get_thread_wsaved() != 0)
478 goto sigill;
479
480
481 if (test_thread_flag(TIF_32BIT)) {
482 regs->tpc &= 0xffffffff;
483 regs->tnpc &= 0xffffffff;
484 }
485 err = put_user(regs->tpc, &sf->info.si_regs.pc);
486 err |= __put_user(regs->tnpc, &sf->info.si_regs.npc);
487 err |= __put_user(regs->y, &sf->info.si_regs.y);
488 psr = tstate_to_psr(regs->tstate);
489 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
490 psr |= PSR_EF;
491 err |= __put_user(psr, &sf->info.si_regs.psr);
492 for (i = 0; i < 16; i++)
493 err |= __put_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
494 err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
495 err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
496 for (i = 1; i < 16; i++)
497 err |= __put_user(((u32 *)regs->u_regs)[2*i],
498 &sf->v8plus.g_upper[i]);
499 err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
500 &sf->v8plus.asi);
501
502 if (psr & PSR_EF) {
503 err |= save_fpu_state32(regs, &sf->fpu_state);
504 err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
505 } else {
506 err |= __put_user(0, &sf->fpu_save);
507 }
508
509 switch (_NSIG_WORDS) {
510 case 4: seta[7] = (oldset->sig[3] >> 32);
511 seta[6] = oldset->sig[3];
512 case 3: seta[5] = (oldset->sig[2] >> 32);
513 seta[4] = oldset->sig[2];
514 case 2: seta[3] = (oldset->sig[1] >> 32);
515 seta[2] = oldset->sig[1];
516 case 1: seta[1] = (oldset->sig[0] >> 32);
517 seta[0] = oldset->sig[0];
518 }
519 err |= __put_user(seta[0], &sf->info.si_mask);
520 err |= __copy_to_user(sf->extramask, seta + 1,
521 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
522
523 err |= copy_in_user((u32 __user *)sf,
524 (u32 __user *)(regs->u_regs[UREG_FP]),
525 sizeof(struct reg_window32));
526
527 if (err)
528 goto sigsegv;
529
530
531 regs->u_regs[UREG_FP] = (unsigned long) sf;
532 regs->u_regs[UREG_I0] = signo;
533 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
534 regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
535
536
537 regs->tpc = (unsigned long) ka->sa.sa_handler;
538 regs->tnpc = (regs->tpc + 4);
539 if (test_thread_flag(TIF_32BIT)) {
540 regs->tpc &= 0xffffffff;
541 regs->tnpc &= 0xffffffff;
542 }
543
544
545 if (ka->ka_restorer) {
546 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
547 } else {
548
549 unsigned long address = ((unsigned long)&(sf->insns[0]));
550 pgd_t *pgdp = pgd_offset(current->mm, address);
551 pud_t *pudp = pud_offset(pgdp, address);
552 pmd_t *pmdp = pmd_offset(pudp, address);
553 pte_t *ptep;
554 pte_t pte;
555
556 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
557
558 err = __put_user(0x821020d8, &sf->insns[0]);
559 err |= __put_user(0x91d02010, &sf->insns[1]);
560 if (err)
561 goto sigsegv;
562
563 preempt_disable();
564 ptep = pte_offset_map(pmdp, address);
565 pte = *ptep;
566 if (pte_present(pte)) {
567 unsigned long page = (unsigned long)
568 page_address(pte_page(pte));
569
570 wmb();
571 __asm__ __volatile__("flush %0 + %1"
572 :
573 : "r" (page),
574 "r" (address & (PAGE_SIZE - 1))
575 : "memory");
576 }
577 pte_unmap(ptep);
578 preempt_enable();
579 }
580 return;
581
582sigill:
583 do_exit(SIGILL);
584sigsegv:
585 force_sigsegv(signo, current);
586}
587
588static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
589 unsigned long signr, sigset_t *oldset,
590 siginfo_t *info)
591{
592 struct rt_signal_frame32 __user *sf;
593 int sigframe_size;
594 u32 psr;
595 int i, err;
596 compat_sigset_t seta;
597
598
599 synchronize_user_stack();
600 save_and_clear_fpu();
601
602 sigframe_size = RT_ALIGNEDSZ;
603 if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
604 sigframe_size -= sizeof(__siginfo_fpu_t);
605
606 sf = (struct rt_signal_frame32 __user *)
607 get_sigframe(&ka->sa, regs, sigframe_size);
608
609 if (invalid_frame_pointer(sf, sigframe_size))
610 goto sigill;
611
612 if (get_thread_wsaved() != 0)
613 goto sigill;
614
615
616 if (test_thread_flag(TIF_32BIT)) {
617 regs->tpc &= 0xffffffff;
618 regs->tnpc &= 0xffffffff;
619 }
620 err = put_user(regs->tpc, &sf->regs.pc);
621 err |= __put_user(regs->tnpc, &sf->regs.npc);
622 err |= __put_user(regs->y, &sf->regs.y);
623 psr = tstate_to_psr(regs->tstate);
624 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
625 psr |= PSR_EF;
626 err |= __put_user(psr, &sf->regs.psr);
627 for (i = 0; i < 16; i++)
628 err |= __put_user(regs->u_regs[i], &sf->regs.u_regs[i]);
629 err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
630 err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
631 for (i = 1; i < 16; i++)
632 err |= __put_user(((u32 *)regs->u_regs)[2*i],
633 &sf->v8plus.g_upper[i]);
634 err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
635 &sf->v8plus.asi);
636
637 if (psr & PSR_EF) {
638 err |= save_fpu_state32(regs, &sf->fpu_state);
639 err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
640 } else {
641 err |= __put_user(0, &sf->fpu_save);
642 }
643
644
645 err |= copy_siginfo_to_user32(&sf->info, info);
646
647
648 err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
649 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
650 err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
651
652 switch (_NSIG_WORDS) {
653 case 4: seta.sig[7] = (oldset->sig[3] >> 32);
654 seta.sig[6] = oldset->sig[3];
655 case 3: seta.sig[5] = (oldset->sig[2] >> 32);
656 seta.sig[4] = oldset->sig[2];
657 case 2: seta.sig[3] = (oldset->sig[1] >> 32);
658 seta.sig[2] = oldset->sig[1];
659 case 1: seta.sig[1] = (oldset->sig[0] >> 32);
660 seta.sig[0] = oldset->sig[0];
661 }
662 err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
663
664 err |= copy_in_user((u32 __user *)sf,
665 (u32 __user *)(regs->u_regs[UREG_FP]),
666 sizeof(struct reg_window32));
667 if (err)
668 goto sigsegv;
669
670
671 regs->u_regs[UREG_FP] = (unsigned long) sf;
672 regs->u_regs[UREG_I0] = signr;
673 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
674 regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
675
676
677 regs->tpc = (unsigned long) ka->sa.sa_handler;
678 regs->tnpc = (regs->tpc + 4);
679 if (test_thread_flag(TIF_32BIT)) {
680 regs->tpc &= 0xffffffff;
681 regs->tnpc &= 0xffffffff;
682 }
683
684
685 if (ka->ka_restorer)
686 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
687 else {
688
689 unsigned long address = ((unsigned long)&(sf->insns[0]));
690 pgd_t *pgdp = pgd_offset(current->mm, address);
691 pud_t *pudp = pud_offset(pgdp, address);
692 pmd_t *pmdp = pmd_offset(pudp, address);
693 pte_t *ptep;
694
695 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
696
697
698 err |= __put_user(0x82102065, &sf->insns[0]);
699
700
701 err |= __put_user(0x91d02010, &sf->insns[1]);
702 if (err)
703 goto sigsegv;
704
705 preempt_disable();
706 ptep = pte_offset_map(pmdp, address);
707 if (pte_present(*ptep)) {
708 unsigned long page = (unsigned long)
709 page_address(pte_page(*ptep));
710
711 wmb();
712 __asm__ __volatile__("flush %0 + %1"
713 :
714 : "r" (page),
715 "r" (address & (PAGE_SIZE - 1))
716 : "memory");
717 }
718 pte_unmap(ptep);
719 preempt_enable();
720 }
721 return;
722
723sigill:
724 do_exit(SIGILL);
725sigsegv:
726 force_sigsegv(signr, current);
727}
728
729static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
730 siginfo_t *info,
731 sigset_t *oldset, struct pt_regs *regs)
732{
733 if (ka->sa.sa_flags & SA_SIGINFO)
734 setup_rt_frame32(ka, regs, signr, oldset, info);
735 else
736 setup_frame32(ka, regs, signr, oldset);
737
738 spin_lock_irq(¤t->sighand->siglock);
739 sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
740 if (!(ka->sa.sa_flags & SA_NOMASK))
741 sigaddset(¤t->blocked,signr);
742 recalc_sigpending();
743 spin_unlock_irq(¤t->sighand->siglock);
744}
745
746static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
747 struct sigaction *sa)
748{
749 switch (regs->u_regs[UREG_I0]) {
750 case ERESTART_RESTARTBLOCK:
751 case ERESTARTNOHAND:
752 no_system_call_restart:
753 regs->u_regs[UREG_I0] = EINTR;
754 regs->tstate |= TSTATE_ICARRY;
755 break;
756 case ERESTARTSYS:
757 if (!(sa->sa_flags & SA_RESTART))
758 goto no_system_call_restart;
759
760 case ERESTARTNOINTR:
761 regs->u_regs[UREG_I0] = orig_i0;
762 regs->tpc -= 4;
763 regs->tnpc -= 4;
764 }
765}
766
767
768
769
770
771void do_signal32(sigset_t *oldset, struct pt_regs * regs,
772 int restart_syscall, unsigned long orig_i0)
773{
774 struct k_sigaction ka;
775 siginfo_t info;
776 int signr;
777
778 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
779
780
781
782
783
784 if (restart_syscall && !pt_regs_is_syscall(regs))
785 restart_syscall = 0;
786
787 if (signr > 0) {
788 if (restart_syscall)
789 syscall_restart32(orig_i0, regs, &ka.sa);
790 handle_signal32(signr, &ka, &info, oldset, regs);
791
792
793
794
795
796
797 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
798
799 tracehook_signal_handler(signr, &info, &ka, regs, 0);
800 return;
801 }
802 if (restart_syscall &&
803 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
804 regs->u_regs[UREG_I0] == ERESTARTSYS ||
805 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
806
807 regs->u_regs[UREG_I0] = orig_i0;
808 regs->tpc -= 4;
809 regs->tnpc -= 4;
810 }
811 if (restart_syscall &&
812 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
813 regs->u_regs[UREG_G1] = __NR_restart_syscall;
814 regs->tpc -= 4;
815 regs->tnpc -= 4;
816 }
817
818
819
820
821 if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
822 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
823 sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
824 }
825}
826
827struct sigstack32 {
828 u32 the_stack;
829 int cur_status;
830};
831
832asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
833{
834 struct sigstack32 __user *ssptr =
835 (struct sigstack32 __user *)((unsigned long)(u_ssptr));
836 struct sigstack32 __user *ossptr =
837 (struct sigstack32 __user *)((unsigned long)(u_ossptr));
838 int ret = -EFAULT;
839
840
841 if (ossptr) {
842 if (put_user(current->sas_ss_sp + current->sas_ss_size,
843 &ossptr->the_stack) ||
844 __put_user(on_sig_stack(sp), &ossptr->cur_status))
845 goto out;
846 }
847
848
849 if (ssptr) {
850 u32 ss_sp;
851
852 if (get_user(ss_sp, &ssptr->the_stack))
853 goto out;
854
855
856
857
858 ret = -EPERM;
859 if (current->sas_ss_sp && on_sig_stack(sp))
860 goto out;
861
862
863
864
865
866 current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
867 current->sas_ss_size = SIGSTKSZ;
868 }
869
870 ret = 0;
871out:
872 return ret;
873}
874
875asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp)
876{
877 stack_t uss, uoss;
878 u32 u_ss_sp = 0;
879 int ret;
880 mm_segment_t old_fs;
881 stack_t32 __user *uss32 = compat_ptr(ussa);
882 stack_t32 __user *uoss32 = compat_ptr(uossa);
883
884 if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) ||
885 __get_user(uss.ss_flags, &uss32->ss_flags) ||
886 __get_user(uss.ss_size, &uss32->ss_size)))
887 return -EFAULT;
888 uss.ss_sp = compat_ptr(u_ss_sp);
889 old_fs = get_fs();
890 set_fs(KERNEL_DS);
891 ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL,
892 uossa ? (stack_t __user *) &uoss : NULL, sp);
893 set_fs(old_fs);
894 if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) ||
895 __put_user(uoss.ss_flags, &uoss32->ss_flags) ||
896 __put_user(uoss.ss_size, &uoss32->ss_size)))
897 return -EFAULT;
898 return ret;
899}
900