aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-04-27 05:26:36 -0400
committerDavid S. Miller <davem@davemloft.net>2008-04-27 05:26:36 -0400
commit5526b7e4513c66bc1c91f661dcd518d5199f8934 (patch)
tree658de7d323dc5aa5c13d7c9545820b5911d758dc /arch/sparc64
parent7cf069955f2f0b95fed6a8b1a61ef598a3df0f4e (diff)
sparc: Remove old style signal frame support.
Back around the same time we were bootstrapping the first 32-bit sparc Linux kernel with a SunOS userland, we made the signal frame match that of SunOS. By the time we even started putting together a native Linux userland for 32-bit Sparc we realized this layout wasn't sufficient for Linux's needs. Therefore we changed the layout, yet kept support for the old style signal frame layout in there. The detection mechanism is that we had sys_sigaction() start passing in a negative signal number to indicate "new style signal frames please". Anyways, no binaries exist in the world that use the old stuff. In fact, I bet Jakub Jelinek and myself are the only two people who ever had such binaries to be honest. So let's get rid of this stuff. I added an assertion using WARN_ON_ONCE() that makes sure 32-bit applications are passing in that negative signal number still. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/kernel/process.c6
-rw-r--r--arch/sparc64/kernel/signal32.c272
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c11
3 files changed, 21 insertions, 268 deletions
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index acf8c5250aa9..500ac6d483a0 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -1,5 +1,4 @@
1/* $Id: process.c,v 1.131 2002/02/09 19:49:30 davem Exp $ 1/* arch/sparc64/kernel/process.c
2 * arch/sparc64/kernel/process.c
3 * 2 *
4 * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) 3 * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) 4 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
@@ -368,9 +367,6 @@ void flush_thread(void)
368 367
369 if (get_thread_current_ds() != ASI_AIUS) 368 if (get_thread_current_ds() != ASI_AIUS)
370 set_fs(USER_DS); 369 set_fs(USER_DS);
371
372 /* Init new signal delivery disposition. */
373 clear_thread_flag(TIF_NEWSIGNALS);
374} 370}
375 371
376/* It's a bit more tricky when 64-bit tasks are involved... */ 372/* It's a bit more tricky when 64-bit tasks are involved... */
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 43cdec64d9c9..91f8d0826db1 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -1,5 +1,4 @@
1/* $Id: signal32.c,v 1.74 2002/02/09 19:49:30 davem Exp $ 1/* arch/sparc64/kernel/signal32.c
2 * arch/sparc64/kernel/signal32.c
3 * 2 *
4 * Copyright (C) 1991, 1992 Linus Torvalds 3 * Copyright (C) 1991, 1992 Linus Torvalds
5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -31,30 +30,6 @@
31 30
32#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 31#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
33 32
34/* Signal frames: the original one (compatible with SunOS):
35 *
36 * Set up a signal frame... Make the stack look the way SunOS
37 * expects it to look which is basically:
38 *
39 * ---------------------------------- <-- %sp at signal time
40 * Struct sigcontext
41 * Signal address
42 * Ptr to sigcontext area above
43 * Signal code
44 * The signal number itself
45 * One register window
46 * ---------------------------------- <-- New %sp
47 */
48struct signal_sframe32 {
49 struct reg_window32 sig_window;
50 int sig_num;
51 int sig_code;
52 /* struct sigcontext32 * */ u32 sig_scptr;
53 int sig_address;
54 struct sigcontext32 sig_context;
55 unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
56};
57
58/* This magic should be in g_upper[0] for all upper parts 33/* This magic should be in g_upper[0] for all upper parts
59 * to be valid. 34 * to be valid.
60 */ 35 */
@@ -65,12 +40,7 @@ typedef struct {
65 unsigned int asi; 40 unsigned int asi;
66} siginfo_extra_v8plus_t; 41} siginfo_extra_v8plus_t;
67 42
68/* 43struct signal_frame32 {
69 * And the new one, intended to be used for Linux applications only
70 * (we have enough in there to work with clone).
71 * All the interesting bits are in the info field.
72 */
73struct new_signal_frame32 {
74 struct sparc_stackf32 ss; 44 struct sparc_stackf32 ss;
75 __siginfo32_t info; 45 __siginfo32_t info;
76 /* __siginfo_fpu32_t * */ u32 fpu_save; 46 /* __siginfo_fpu32_t * */ u32 fpu_save;
@@ -149,8 +119,7 @@ struct rt_signal_frame32 {
149}; 119};
150 120
151/* Align macros */ 121/* Align macros */
152#define SF_ALIGNEDSZ (((sizeof(struct signal_sframe32) + 7) & (~7))) 122#define SF_ALIGNEDSZ (((sizeof(struct signal_frame32) + 7) & (~7)))
153#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame32) + 7) & (~7)))
154#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7))) 123#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
155 124
156int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) 125int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
@@ -241,17 +210,22 @@ static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu
241 return err; 210 return err;
242} 211}
243 212
244void do_new_sigreturn32(struct pt_regs *regs) 213void do_sigreturn32(struct pt_regs *regs)
245{ 214{
246 struct new_signal_frame32 __user *sf; 215 struct signal_frame32 __user *sf;
247 unsigned int psr; 216 unsigned int psr;
248 unsigned pc, npc, fpu_save; 217 unsigned pc, npc, fpu_save;
249 sigset_t set; 218 sigset_t set;
250 unsigned seta[_COMPAT_NSIG_WORDS]; 219 unsigned seta[_COMPAT_NSIG_WORDS];
251 int err, i; 220 int err, i;
252 221
222 /* Always make any pending restarted system calls return -EINTR */
223 current_thread_info()->restart_block.fn = do_no_restart_syscall;
224
225 synchronize_user_stack();
226
253 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; 227 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
254 sf = (struct new_signal_frame32 __user *) regs->u_regs[UREG_FP]; 228 sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
255 229
256 /* 1. Make sure we are not getting garbage from the user */ 230 /* 1. Make sure we are not getting garbage from the user */
257 if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) || 231 if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
@@ -319,76 +293,6 @@ segv:
319 force_sig(SIGSEGV, current); 293 force_sig(SIGSEGV, current);
320} 294}
321 295
322asmlinkage void do_sigreturn32(struct pt_regs *regs)
323{
324 struct sigcontext32 __user *scptr;
325 unsigned int pc, npc, psr;
326 sigset_t set;
327 unsigned int seta[_COMPAT_NSIG_WORDS];
328 int err;
329
330 /* Always make any pending restarted system calls return -EINTR */
331 current_thread_info()->restart_block.fn = do_no_restart_syscall;
332
333 synchronize_user_stack();
334 if (test_thread_flag(TIF_NEWSIGNALS)) {
335 do_new_sigreturn32(regs);
336 return;
337 }
338
339 scptr = (struct sigcontext32 __user *)
340 (regs->u_regs[UREG_I0] & 0x00000000ffffffffUL);
341 /* Check sanity of the user arg. */
342 if (!access_ok(VERIFY_READ, scptr, sizeof(struct sigcontext32)) ||
343 (((unsigned long) scptr) & 3))
344 goto segv;
345
346 err = __get_user(pc, &scptr->sigc_pc);
347 err |= __get_user(npc, &scptr->sigc_npc);
348
349 if ((pc | npc) & 3)
350 goto segv; /* Nice try. */
351
352 err |= __get_user(seta[0], &scptr->sigc_mask);
353 /* Note that scptr + 1 points to extramask */
354 err |= copy_from_user(seta+1, scptr + 1,
355 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
356 if (err)
357 goto segv;
358 switch (_NSIG_WORDS) {
359 case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32);
360 case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32);
361 case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
362 case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
363 }
364 sigdelsetmask(&set, ~_BLOCKABLE);
365 spin_lock_irq(&current->sighand->siglock);
366 current->blocked = set;
367 recalc_sigpending();
368 spin_unlock_irq(&current->sighand->siglock);
369
370 if (test_thread_flag(TIF_32BIT)) {
371 pc &= 0xffffffff;
372 npc &= 0xffffffff;
373 }
374 regs->tpc = pc;
375 regs->tnpc = npc;
376 err = __get_user(regs->u_regs[UREG_FP], &scptr->sigc_sp);
377 err |= __get_user(regs->u_regs[UREG_I0], &scptr->sigc_o0);
378 err |= __get_user(regs->u_regs[UREG_G1], &scptr->sigc_g1);
379
380 /* User can only change condition codes in %tstate. */
381 err |= __get_user(psr, &scptr->sigc_psr);
382 if (err)
383 goto segv;
384 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
385 regs->tstate |= psr_to_tstate_icc(psr);
386 return;
387
388segv:
389 force_sig(SIGSEGV, current);
390}
391
392asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) 296asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
393{ 297{
394 struct rt_signal_frame32 __user *sf; 298 struct rt_signal_frame32 __user *sf;
@@ -504,145 +408,6 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
504 return (void __user *)(sp - framesize); 408 return (void __user *)(sp - framesize);
505} 409}
506 410
507static void
508setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info)
509{
510 struct signal_sframe32 __user *sframep;
511 struct sigcontext32 __user *sc;
512 unsigned int seta[_COMPAT_NSIG_WORDS];
513 int err = 0;
514 void __user *sig_address;
515 int sig_code;
516 unsigned long pc = regs->tpc;
517 unsigned long npc = regs->tnpc;
518 unsigned int psr;
519
520 if (test_thread_flag(TIF_32BIT)) {
521 pc &= 0xffffffff;
522 npc &= 0xffffffff;
523 }
524
525 synchronize_user_stack();
526 save_and_clear_fpu();
527
528 sframep = (struct signal_sframe32 __user *)
529 get_sigframe(sa, regs, SF_ALIGNEDSZ);
530 if (invalid_frame_pointer(sframep, sizeof(*sframep))){
531 /* Don't change signal code and address, so that
532 * post mortem debuggers can have a look.
533 */
534 do_exit(SIGILL);
535 }
536
537 sc = &sframep->sig_context;
538
539 /* We've already made sure frame pointer isn't in kernel space... */
540 err = __put_user((sas_ss_flags(regs->u_regs[UREG_FP]) == SS_ONSTACK),
541 &sc->sigc_onstack);
542
543 switch (_NSIG_WORDS) {
544 case 4: seta[7] = (oldset->sig[3] >> 32);
545 seta[6] = oldset->sig[3];
546 case 3: seta[5] = (oldset->sig[2] >> 32);
547 seta[4] = oldset->sig[2];
548 case 2: seta[3] = (oldset->sig[1] >> 32);
549 seta[2] = oldset->sig[1];
550 case 1: seta[1] = (oldset->sig[0] >> 32);
551 seta[0] = oldset->sig[0];
552 }
553 err |= __put_user(seta[0], &sc->sigc_mask);
554 err |= __copy_to_user(sframep->extramask, seta + 1,
555 (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
556 err |= __put_user(regs->u_regs[UREG_FP], &sc->sigc_sp);
557 err |= __put_user(pc, &sc->sigc_pc);
558 err |= __put_user(npc, &sc->sigc_npc);
559 psr = tstate_to_psr(regs->tstate);
560 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
561 psr |= PSR_EF;
562 err |= __put_user(psr, &sc->sigc_psr);
563 err |= __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
564 err |= __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
565 err |= __put_user(get_thread_wsaved(), &sc->sigc_oswins);
566
567 err |= copy_in_user((u32 __user *)sframep,
568 (u32 __user *)(regs->u_regs[UREG_FP]),
569 sizeof(struct reg_window32));
570
571 set_thread_wsaved(0); /* So process is allowed to execute. */
572 err |= __put_user(signr, &sframep->sig_num);
573 sig_address = NULL;
574 sig_code = 0;
575 if (SI_FROMKERNEL (info) && (info->si_code & __SI_MASK) == __SI_FAULT) {
576 sig_address = info->si_addr;
577 switch (signr) {
578 case SIGSEGV:
579 switch (info->si_code) {
580 case SEGV_MAPERR: sig_code = SUBSIG_NOMAPPING; break;
581 default: sig_code = SUBSIG_PROTECTION; break;
582 }
583 break;
584 case SIGILL:
585 switch (info->si_code) {
586 case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break;
587 case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break;
588 case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP(info->si_trapno); break;
589 default: sig_code = SUBSIG_STACK; break;
590 }
591 break;
592 case SIGFPE:
593 switch (info->si_code) {
594 case FPE_INTDIV: sig_code = SUBSIG_IDIVZERO; break;
595 case FPE_INTOVF: sig_code = SUBSIG_FPINTOVFL; break;
596 case FPE_FLTDIV: sig_code = SUBSIG_FPDIVZERO; break;
597 case FPE_FLTOVF: sig_code = SUBSIG_FPOVFLOW; break;
598 case FPE_FLTUND: sig_code = SUBSIG_FPUNFLOW; break;
599 case FPE_FLTRES: sig_code = SUBSIG_FPINEXACT; break;
600 case FPE_FLTINV: sig_code = SUBSIG_FPOPERROR; break;
601 default: sig_code = SUBSIG_FPERROR; break;
602 }
603 break;
604 case SIGBUS:
605 switch (info->si_code) {
606 case BUS_ADRALN: sig_code = SUBSIG_ALIGNMENT; break;
607 case BUS_ADRERR: sig_code = SUBSIG_MISCERROR; break;
608 default: sig_code = SUBSIG_BUSTIMEOUT; break;
609 }
610 break;
611 case SIGEMT:
612 switch (info->si_code) {
613 case EMT_TAGOVF: sig_code = SUBSIG_TAG; break;
614 }
615 break;
616 case SIGSYS:
617 if (info->si_code == (__SI_FAULT|0x100)) {
618 /* See sys_sunos32.c */
619 sig_code = info->si_trapno;
620 break;
621 }
622 default:
623 sig_address = NULL;
624 }
625 }
626 err |= __put_user(ptr_to_compat(sig_address), &sframep->sig_address);
627 err |= __put_user(sig_code, &sframep->sig_code);
628 err |= __put_user(ptr_to_compat(sc), &sframep->sig_scptr);
629 if (err)
630 goto sigsegv;
631
632 regs->u_regs[UREG_FP] = (unsigned long) sframep;
633 regs->tpc = (unsigned long) sa->sa_handler;
634 regs->tnpc = (regs->tpc + 4);
635 if (test_thread_flag(TIF_32BIT)) {
636 regs->tpc &= 0xffffffff;
637 regs->tnpc &= 0xffffffff;
638 }
639 return;
640
641sigsegv:
642 force_sigsegv(signr, current);
643}
644
645
646static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) 411static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
647{ 412{
648 unsigned long *fpregs = current_thread_info()->fpregs; 413 unsigned long *fpregs = current_thread_info()->fpregs;
@@ -663,10 +428,10 @@ static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
663 return err; 428 return err;
664} 429}
665 430
666static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, 431static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
667 int signo, sigset_t *oldset) 432 int signo, sigset_t *oldset)
668{ 433{
669 struct new_signal_frame32 __user *sf; 434 struct signal_frame32 __user *sf;
670 int sigframe_size; 435 int sigframe_size;
671 u32 psr; 436 u32 psr;
672 int i, err; 437 int i, err;
@@ -676,11 +441,11 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
676 synchronize_user_stack(); 441 synchronize_user_stack();
677 save_and_clear_fpu(); 442 save_and_clear_fpu();
678 443
679 sigframe_size = NF_ALIGNEDSZ; 444 sigframe_size = SF_ALIGNEDSZ;
680 if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) 445 if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
681 sigframe_size -= sizeof(__siginfo_fpu_t); 446 sigframe_size -= sizeof(__siginfo_fpu_t);
682 447
683 sf = (struct new_signal_frame32 __user *) 448 sf = (struct signal_frame32 __user *)
684 get_sigframe(&ka->sa, regs, sigframe_size); 449 get_sigframe(&ka->sa, regs, sigframe_size);
685 450
686 if (invalid_frame_pointer(sf, sigframe_size)) 451 if (invalid_frame_pointer(sf, sigframe_size))
@@ -944,10 +709,9 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
944{ 709{
945 if (ka->sa.sa_flags & SA_SIGINFO) 710 if (ka->sa.sa_flags & SA_SIGINFO)
946 setup_rt_frame32(ka, regs, signr, oldset, info); 711 setup_rt_frame32(ka, regs, signr, oldset, info);
947 else if (test_thread_flag(TIF_NEWSIGNALS))
948 new_setup_frame32(ka, regs, signr, oldset);
949 else 712 else
950 setup_frame32(&ka->sa, regs, signr, oldset, info); 713 setup_frame32(ka, regs, signr, oldset);
714
951 spin_lock_irq(&current->sighand->siglock); 715 spin_lock_irq(&current->sighand->siglock);
952 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 716 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
953 if (!(ka->sa.sa_flags & SA_NOMASK)) 717 if (!(ka->sa.sa_flags & SA_NOMASK))
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index c1a61e98899a..161ce4710fe7 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -554,10 +554,8 @@ asmlinkage long compat_sys_sigaction(int sig, struct old_sigaction32 __user *act
554 struct k_sigaction new_ka, old_ka; 554 struct k_sigaction new_ka, old_ka;
555 int ret; 555 int ret;
556 556
557 if (sig < 0) { 557 WARN_ON_ONCE(sig >= 0);
558 set_thread_flag(TIF_NEWSIGNALS); 558 sig = -sig;
559 sig = -sig;
560 }
561 559
562 if (act) { 560 if (act) {
563 compat_old_sigset_t mask; 561 compat_old_sigset_t mask;
@@ -601,11 +599,6 @@ asmlinkage long compat_sys_rt_sigaction(int sig,
601 if (sigsetsize != sizeof(compat_sigset_t)) 599 if (sigsetsize != sizeof(compat_sigset_t))
602 return -EINVAL; 600 return -EINVAL;
603 601
604 /* All tasks which use RT signals (effectively) use
605 * new style signals.
606 */
607 set_thread_flag(TIF_NEWSIGNALS);
608
609 if (act) { 602 if (act) {
610 u32 u_handler, u_restorer; 603 u32 u_handler, u_restorer;
611 604