1 // SPDX-License-Identifier: GPL-2.0
2 /* arch/sparc64/kernel/signal32.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
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>
19 #include <linux/tty.h>
20 #include <linux/binfmts.h>
21 #include <linux/compat.h>
22 #include <linux/bitops.h>
23 #include <linux/tracehook.h>
25 #include <linux/uaccess.h>
26 #include <asm/ptrace.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 #include <asm/switch_to.h>
37 /* This magic should be in g_upper[0] for all upper parts
40 #define SIGINFO_EXTRA_V8PLUS_MAGIC 0x130e269
42 unsigned int g_upper[8];
43 unsigned int o_upper[8];
45 } siginfo_extra_v8plus_t;
47 struct signal_frame32 {
48 struct sparc_stackf32 ss;
50 /* __siginfo_fpu_t * */ u32 fpu_save;
51 unsigned int insns[2];
52 unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
53 unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
54 /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
55 siginfo_extra_v8plus_t v8plus;
56 /* __siginfo_rwin_t * */u32 rwin_save;
57 } __attribute__((aligned(8)));
59 struct rt_signal_frame32 {
60 struct sparc_stackf32 ss;
61 compat_siginfo_t info;
62 struct pt_regs32 regs;
64 /* __siginfo_fpu_t * */ u32 fpu_save;
65 unsigned int insns[2];
67 unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
68 /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
69 siginfo_extra_v8plus_t v8plus;
70 /* __siginfo_rwin_t * */u32 rwin_save;
71 } __attribute__((aligned(8)));
73 int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
77 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
80 /* If you change siginfo_t structure, please be sure
81 this code is fixed accordingly.
82 It should never copy any pad contained in the structure
83 to avoid security leaks, but must copy the generic
84 3 ints plus the relevant union member.
85 This routine must convert siginfo from 64bit to 32bit as well
87 err = __put_user(from->si_signo, &to->si_signo);
88 err |= __put_user(from->si_errno, &to->si_errno);
89 err |= __put_user(from->si_code, &to->si_code);
90 if (from->si_code < 0)
91 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
93 switch (siginfo_layout(from->si_signo, from->si_code)) {
95 err |= __put_user(from->si_tid, &to->si_tid);
96 err |= __put_user(from->si_overrun, &to->si_overrun);
97 err |= __put_user(from->si_int, &to->si_int);
100 err |= __put_user(from->si_utime, &to->si_utime);
101 err |= __put_user(from->si_stime, &to->si_stime);
102 err |= __put_user(from->si_status, &to->si_status);
105 err |= __put_user(from->si_pid, &to->si_pid);
106 err |= __put_user(from->si_uid, &to->si_uid);
109 err |= __put_user(from->si_trapno, &to->si_trapno);
110 err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
113 err |= __put_user(from->si_band, &to->si_band);
114 err |= __put_user(from->si_fd, &to->si_fd);
117 err |= __put_user(from->si_pid, &to->si_pid);
118 err |= __put_user(from->si_uid, &to->si_uid);
119 err |= __put_user(from->si_int, &to->si_int);
126 /* CAUTION: This is just a very minimalist implementation for the
127 * sake of compat_sys_rt_sigqueueinfo()
129 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
131 if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
134 if (copy_from_user(to, from, 3*sizeof(int)) ||
135 copy_from_user(to->_sifields._pad, from->_sifields._pad,
142 /* Checks if the fp is valid. We always build signal frames which are
143 * 16-byte aligned, therefore we can always enforce that the restore
144 * frame has that property as well.
146 static bool invalid_frame_pointer(void __user *fp, int fplen)
148 if ((((unsigned long) fp) & 15) ||
149 ((unsigned long)fp) > 0x100000000ULL - fplen)
154 void do_sigreturn32(struct pt_regs *regs)
156 struct signal_frame32 __user *sf;
157 compat_uptr_t fpu_save;
158 compat_uptr_t rwin_save;
159 unsigned int psr, ufp;
160 unsigned int pc, npc;
162 compat_sigset_t seta;
165 /* Always make any pending restarted system calls return -EINTR */
166 current->restart_block.fn = do_no_restart_syscall;
168 synchronize_user_stack();
170 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
171 sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
173 /* 1. Make sure we are not getting garbage from the user */
174 if (invalid_frame_pointer(sf, sizeof(*sf)))
177 if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
183 if (__get_user(pc, &sf->info.si_regs.pc) ||
184 __get_user(npc, &sf->info.si_regs.npc))
190 if (test_thread_flag(TIF_32BIT)) {
197 /* 2. Restore the state */
198 err = __get_user(regs->y, &sf->info.si_regs.y);
199 err |= __get_user(psr, &sf->info.si_regs.psr);
201 for (i = UREG_G1; i <= UREG_I7; i++)
202 err |= __get_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
203 if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
204 err |= __get_user(i, &sf->v8plus.g_upper[0]);
205 if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
208 for (i = UREG_G1; i <= UREG_I7; i++)
209 err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
210 err |= __get_user(asi, &sf->v8plus.asi);
211 regs->tstate &= ~TSTATE_ASI;
212 regs->tstate |= ((asi & 0xffUL) << 24UL);
216 /* User can only change condition codes in %tstate. */
217 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
218 regs->tstate |= psr_to_tstate_icc(psr);
220 /* Prevent syscall restart. */
221 pt_regs_clear_syscall(regs);
223 err |= __get_user(fpu_save, &sf->fpu_save);
224 if (!err && fpu_save)
225 err |= restore_fpu_state(regs, compat_ptr(fpu_save));
226 err |= __get_user(rwin_save, &sf->rwin_save);
227 if (!err && rwin_save) {
228 if (restore_rwin_state(compat_ptr(rwin_save)))
231 err |= __get_user(seta.sig[0], &sf->info.si_mask);
232 err |= copy_from_user(&seta.sig[1], &sf->extramask,
233 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
237 set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
238 set_current_blocked(&set);
242 force_sig(SIGSEGV, current);
245 asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
247 struct rt_signal_frame32 __user *sf;
248 unsigned int psr, pc, npc, ufp;
249 compat_uptr_t fpu_save;
250 compat_uptr_t rwin_save;
254 /* Always make any pending restarted system calls return -EINTR */
255 current->restart_block.fn = do_no_restart_syscall;
257 synchronize_user_stack();
258 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
259 sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
261 /* 1. Make sure we are not getting garbage from the user */
262 if (invalid_frame_pointer(sf, sizeof(*sf)))
265 if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
271 if (__get_user(pc, &sf->regs.pc) ||
272 __get_user(npc, &sf->regs.npc))
278 if (test_thread_flag(TIF_32BIT)) {
285 /* 2. Restore the state */
286 err = __get_user(regs->y, &sf->regs.y);
287 err |= __get_user(psr, &sf->regs.psr);
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) {
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);
304 /* User can only change condition codes in %tstate. */
305 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
306 regs->tstate |= psr_to_tstate_icc(psr);
308 /* Prevent syscall restart. */
309 pt_regs_clear_syscall(regs);
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 |= get_compat_sigset(&set, &sf->mask);
315 err |= compat_restore_altstack(&sf->stack);
319 err |= __get_user(rwin_save, &sf->rwin_save);
320 if (!err && rwin_save) {
321 if (restore_rwin_state(compat_ptr(rwin_save)))
325 set_current_blocked(&set);
328 force_sig(SIGSEGV, current);
331 static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
335 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
336 sp = regs->u_regs[UREG_FP];
339 * If we are on the alternate signal stack and would overflow it, don't.
340 * Return an always-bogus address instead so we will die with SIGSEGV.
342 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
343 return (void __user *) -1L;
345 /* This is the X/Open sanctioned signal stack switching. */
346 sp = sigsp(sp, ksig) - framesize;
348 /* Always align the stack frame. This handles two cases. First,
349 * sigaltstack need not be mindful of platform specific stack
350 * alignment. Second, if we took this signal because the stack
351 * is not aligned properly, we'd like to take the signal cleanly
356 return (void __user *) sp;
359 /* The I-cache flush instruction only works in the primary ASI, which
360 * right now is the nucleus, aka. kernel space.
362 * Therefore we have to kick the instructions out using the kernel
363 * side linear mapping of the physical address backing the user
366 static void flush_signal_insns(unsigned long address)
368 unsigned long pstate, paddr;
374 /* Commit all stores of the instructions we are about to flush. */
377 /* Disable cross-call reception. In this way even a very wide
378 * munmap() on another cpu can't tear down the page table
379 * hierarchy from underneath us, since that can't complete
380 * until the IPI tlb flush returns.
383 __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
384 __asm__ __volatile__("wrpr %0, %1, %%pstate"
385 : : "r" (pstate), "i" (PSTATE_IE));
387 pgdp = pgd_offset(current->mm, address);
390 pudp = pud_offset(pgdp, address);
393 pmdp = pmd_offset(pudp, address);
397 ptep = pte_offset_map(pmdp, address);
399 if (!pte_present(pte))
402 paddr = (unsigned long) page_address(pte_page(pte));
404 __asm__ __volatile__("flush %0 + %1"
407 "r" (address & (PAGE_SIZE - 1))
413 __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
417 static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs,
420 struct signal_frame32 __user *sf;
425 compat_sigset_t seta;
427 /* 1. Make sure everything is clean */
428 synchronize_user_stack();
429 save_and_clear_fpu();
431 wsaved = get_thread_wsaved();
433 sigframe_size = sizeof(*sf);
434 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
435 sigframe_size += sizeof(__siginfo_fpu_t);
437 sigframe_size += sizeof(__siginfo_rwin_t);
439 sf = (struct signal_frame32 __user *)
440 get_sigframe(ksig, regs, sigframe_size);
442 if (invalid_frame_pointer(sf, sigframe_size)) {
449 /* 2. Save the current process state */
450 if (test_thread_flag(TIF_32BIT)) {
451 regs->tpc &= 0xffffffff;
452 regs->tnpc &= 0xffffffff;
454 err = put_user(regs->tpc, &sf->info.si_regs.pc);
455 err |= __put_user(regs->tnpc, &sf->info.si_regs.npc);
456 err |= __put_user(regs->y, &sf->info.si_regs.y);
457 psr = tstate_to_psr(regs->tstate);
458 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
460 err |= __put_user(psr, &sf->info.si_regs.psr);
461 for (i = 0; i < 16; i++)
462 err |= __put_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
463 err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
464 err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
465 for (i = 1; i < 16; i++)
466 err |= __put_user(((u32 *)regs->u_regs)[2*i],
467 &sf->v8plus.g_upper[i]);
468 err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
472 __siginfo_fpu_t __user *fp = tail;
474 err |= save_fpu_state(regs, fp);
475 err |= __put_user((u64)fp, &sf->fpu_save);
477 err |= __put_user(0, &sf->fpu_save);
480 __siginfo_rwin_t __user *rwp = tail;
481 tail += sizeof(*rwp);
482 err |= save_rwin_state(wsaved, rwp);
483 err |= __put_user((u64)rwp, &sf->rwin_save);
484 set_thread_wsaved(0);
486 err |= __put_user(0, &sf->rwin_save);
489 /* If these change we need to know - assignments to seta relies on these sizes */
490 BUILD_BUG_ON(_NSIG_WORDS != 1);
491 BUILD_BUG_ON(_COMPAT_NSIG_WORDS != 2);
492 seta.sig[1] = (oldset->sig[0] >> 32);
493 seta.sig[0] = oldset->sig[0];
495 err |= __put_user(seta.sig[0], &sf->info.si_mask);
496 err |= __copy_to_user(sf->extramask, &seta.sig[1],
497 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
500 err |= copy_in_user((u32 __user *)sf,
501 (u32 __user *)(regs->u_regs[UREG_FP]),
502 sizeof(struct reg_window32));
504 struct reg_window *rp;
506 rp = ¤t_thread_info()->reg_window[wsaved - 1];
507 for (i = 0; i < 8; i++)
508 err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
509 for (i = 0; i < 6; i++)
510 err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
511 err |= __put_user(rp->ins[6], &sf->ss.fp);
512 err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
517 /* 3. signal handler back-trampoline and parameters */
518 regs->u_regs[UREG_FP] = (unsigned long) sf;
519 regs->u_regs[UREG_I0] = ksig->sig;
520 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
521 regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
523 /* 4. signal handler */
524 regs->tpc = (unsigned long) ksig->ka.sa.sa_handler;
525 regs->tnpc = (regs->tpc + 4);
526 if (test_thread_flag(TIF_32BIT)) {
527 regs->tpc &= 0xffffffff;
528 regs->tnpc &= 0xffffffff;
531 /* 5. return to kernel instructions */
532 if (ksig->ka.ka_restorer) {
533 regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
535 unsigned long address = ((unsigned long)&(sf->insns[0]));
537 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
539 err = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/
540 err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
543 flush_signal_insns(address);
548 static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs,
551 struct rt_signal_frame32 __user *sf;
557 /* 1. Make sure everything is clean */
558 synchronize_user_stack();
559 save_and_clear_fpu();
561 wsaved = get_thread_wsaved();
563 sigframe_size = sizeof(*sf);
564 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
565 sigframe_size += sizeof(__siginfo_fpu_t);
567 sigframe_size += sizeof(__siginfo_rwin_t);
569 sf = (struct rt_signal_frame32 __user *)
570 get_sigframe(ksig, regs, sigframe_size);
572 if (invalid_frame_pointer(sf, sigframe_size)) {
579 /* 2. Save the current process state */
580 if (test_thread_flag(TIF_32BIT)) {
581 regs->tpc &= 0xffffffff;
582 regs->tnpc &= 0xffffffff;
584 err = put_user(regs->tpc, &sf->regs.pc);
585 err |= __put_user(regs->tnpc, &sf->regs.npc);
586 err |= __put_user(regs->y, &sf->regs.y);
587 psr = tstate_to_psr(regs->tstate);
588 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
590 err |= __put_user(psr, &sf->regs.psr);
591 for (i = 0; i < 16; i++)
592 err |= __put_user(regs->u_regs[i], &sf->regs.u_regs[i]);
593 err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
594 err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
595 for (i = 1; i < 16; i++)
596 err |= __put_user(((u32 *)regs->u_regs)[2*i],
597 &sf->v8plus.g_upper[i]);
598 err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
602 __siginfo_fpu_t __user *fp = tail;
604 err |= save_fpu_state(regs, fp);
605 err |= __put_user((u64)fp, &sf->fpu_save);
607 err |= __put_user(0, &sf->fpu_save);
610 __siginfo_rwin_t __user *rwp = tail;
611 tail += sizeof(*rwp);
612 err |= save_rwin_state(wsaved, rwp);
613 err |= __put_user((u64)rwp, &sf->rwin_save);
614 set_thread_wsaved(0);
616 err |= __put_user(0, &sf->rwin_save);
619 /* Update the siginfo structure. */
620 err |= copy_siginfo_to_user32(&sf->info, &ksig->info);
622 /* Setup sigaltstack */
623 err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
625 err |= put_compat_sigset(&sf->mask, oldset, sizeof(compat_sigset_t));
628 err |= copy_in_user((u32 __user *)sf,
629 (u32 __user *)(regs->u_regs[UREG_FP]),
630 sizeof(struct reg_window32));
632 struct reg_window *rp;
634 rp = ¤t_thread_info()->reg_window[wsaved - 1];
635 for (i = 0; i < 8; i++)
636 err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
637 for (i = 0; i < 6; i++)
638 err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
639 err |= __put_user(rp->ins[6], &sf->ss.fp);
640 err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
645 /* 3. signal handler back-trampoline and parameters */
646 regs->u_regs[UREG_FP] = (unsigned long) sf;
647 regs->u_regs[UREG_I0] = ksig->sig;
648 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
649 regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
651 /* 4. signal handler */
652 regs->tpc = (unsigned long) ksig->ka.sa.sa_handler;
653 regs->tnpc = (regs->tpc + 4);
654 if (test_thread_flag(TIF_32BIT)) {
655 regs->tpc &= 0xffffffff;
656 regs->tnpc &= 0xffffffff;
659 /* 5. return to kernel instructions */
660 if (ksig->ka.ka_restorer)
661 regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
663 unsigned long address = ((unsigned long)&(sf->insns[0]));
665 regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
667 /* mov __NR_rt_sigreturn, %g1 */
668 err |= __put_user(0x82102065, &sf->insns[0]);
671 err |= __put_user(0x91d02010, &sf->insns[1]);
675 flush_signal_insns(address);
680 static inline void handle_signal32(struct ksignal *ksig,
681 struct pt_regs *regs)
683 sigset_t *oldset = sigmask_to_save();
686 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
687 err = setup_rt_frame32(ksig, regs, oldset);
689 err = setup_frame32(ksig, regs, oldset);
691 signal_setup_done(err, ksig, 0);
694 static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
695 struct sigaction *sa)
697 switch (regs->u_regs[UREG_I0]) {
698 case ERESTART_RESTARTBLOCK:
700 no_system_call_restart:
701 regs->u_regs[UREG_I0] = EINTR;
702 regs->tstate |= TSTATE_ICARRY;
705 if (!(sa->sa_flags & SA_RESTART))
706 goto no_system_call_restart;
709 regs->u_regs[UREG_I0] = orig_i0;
715 /* Note that 'init' is a special process: it doesn't get signals it doesn't
716 * want to handle. Thus you cannot kill init even with a SIGKILL even by
719 void do_signal32(struct pt_regs * regs)
722 unsigned long orig_i0 = 0;
723 int restart_syscall = 0;
724 bool has_handler = get_signal(&ksig);
726 if (pt_regs_is_syscall(regs) &&
727 (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
729 orig_i0 = regs->u_regs[UREG_G6];
734 syscall_restart32(orig_i0, regs, &ksig.ka.sa);
735 handle_signal32(&ksig, regs);
737 if (restart_syscall) {
738 switch (regs->u_regs[UREG_I0]) {
742 /* replay the system call when we are done */
743 regs->u_regs[UREG_I0] = orig_i0;
746 pt_regs_clear_syscall(regs);
747 case ERESTART_RESTARTBLOCK:
748 regs->u_regs[UREG_G1] = __NR_restart_syscall;
751 pt_regs_clear_syscall(regs);
754 restore_saved_sigmask();
763 asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
765 struct sigstack32 __user *ssptr =
766 (struct sigstack32 __user *)((unsigned long)(u_ssptr));
767 struct sigstack32 __user *ossptr =
768 (struct sigstack32 __user *)((unsigned long)(u_ossptr));
771 /* First see if old state is wanted. */
773 if (put_user(current->sas_ss_sp + current->sas_ss_size,
774 &ossptr->the_stack) ||
775 __put_user(on_sig_stack(sp), &ossptr->cur_status))
779 /* Now see if we want to update the new state. */
783 if (get_user(ss_sp, &ssptr->the_stack))
786 /* If the current stack was set with sigaltstack, don't
787 * swap stacks while we are on it.
790 if (current->sas_ss_sp && on_sig_stack(sp))
793 /* Since we don't know the extent of the stack, and we don't
794 * track onstack-ness, but rather calculate it, we must
795 * presume a size. Ho hum this interface is lossy.
797 current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
798 current->sas_ss_size = SIGSTKSZ;