aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc/kernel/process.c2
-rw-r--r--arch/sparc/kernel/signal.c260
-rw-r--r--arch/sparc/kernel/sys_sparc.c14
-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
-rw-r--r--include/asm-sparc/processor.h4
-rw-r--r--include/asm-sparc64/thread_info.h6
8 files changed, 47 insertions, 528 deletions
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 70c0dd22491d..e7f35198ae34 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -357,8 +357,6 @@ void flush_thread(void)
357{ 357{
358 current_thread_info()->w_saved = 0; 358 current_thread_info()->w_saved = 0;
359 359
360 /* No new signal delivery by default */
361 current->thread.new_signal = 0;
362#ifndef CONFIG_SMP 360#ifndef CONFIG_SMP
363 if(last_task_used_math == current) { 361 if(last_task_used_math == current) {
364#else 362#else
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index 3e849e8e3480..3c312290c3c2 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -1,5 +1,4 @@
1/* $Id: signal.c,v 1.110 2002/02/08 03:57:14 davem Exp $ 1/* linux/arch/sparc/kernel/signal.c
2 * linux/arch/sparc/kernel/signal.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)
@@ -32,37 +31,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
32 void *fpqueue, unsigned long *fpqdepth); 31 void *fpqueue, unsigned long *fpqdepth);
33extern void fpload(unsigned long *fpregs, unsigned long *fsr); 32extern void fpload(unsigned long *fpregs, unsigned long *fsr);
34 33
35/* Signal frames: the original one (compatible with SunOS): 34struct signal_frame {
36 *
37 * Set up a signal frame... Make the stack look the way SunOS
38 * expects it to look which is basically:
39 *
40 * ---------------------------------- <-- %sp at signal time
41 * Struct sigcontext
42 * Signal address
43 * Ptr to sigcontext area above
44 * Signal code
45 * The signal number itself
46 * One register window
47 * ---------------------------------- <-- New %sp
48 */
49struct signal_sframe {
50 struct reg_window sig_window;
51 int sig_num;
52 int sig_code;
53 struct sigcontext __user *sig_scptr;
54 int sig_address;
55 struct sigcontext sig_context;
56 unsigned int extramask[_NSIG_WORDS - 1];
57};
58
59/*
60 * And the new one, intended to be used for Linux applications only
61 * (we have enough in there to work with clone).
62 * All the interesting bits are in the info field.
63 */
64
65struct new_signal_frame {
66 struct sparc_stackf ss; 35 struct sparc_stackf ss;
67 __siginfo_t info; 36 __siginfo_t info;
68 __siginfo_fpu_t __user *fpu_save; 37 __siginfo_fpu_t __user *fpu_save;
@@ -85,8 +54,7 @@ struct rt_signal_frame {
85}; 54};
86 55
87/* Align macros */ 56/* Align macros */
88#define SF_ALIGNEDSZ (((sizeof(struct signal_sframe) + 7) & (~7))) 57#define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7)))
89#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame) + 7) & (~7)))
90#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7))) 58#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
91 59
92static int _sigpause_common(old_sigset_t set) 60static int _sigpause_common(old_sigset_t set)
@@ -141,15 +109,20 @@ restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
141 return err; 109 return err;
142} 110}
143 111
144static inline void do_new_sigreturn (struct pt_regs *regs) 112asmlinkage void do_sigreturn(struct pt_regs *regs)
145{ 113{
146 struct new_signal_frame __user *sf; 114 struct signal_frame __user *sf;
147 unsigned long up_psr, pc, npc; 115 unsigned long up_psr, pc, npc;
148 sigset_t set; 116 sigset_t set;
149 __siginfo_fpu_t __user *fpu_save; 117 __siginfo_fpu_t __user *fpu_save;
150 int err; 118 int err;
151 119
152 sf = (struct new_signal_frame __user *) regs->u_regs[UREG_FP]; 120 /* Always make any pending restarted system calls return -EINTR */
121 current_thread_info()->restart_block.fn = do_no_restart_syscall;
122
123 synchronize_user_stack();
124
125 sf = (struct signal_frame __user *) regs->u_regs[UREG_FP];
153 126
154 /* 1. Make sure we are not getting garbage from the user */ 127 /* 1. Make sure we are not getting garbage from the user */
155 if (!access_ok(VERIFY_READ, sf, sizeof(*sf))) 128 if (!access_ok(VERIFY_READ, sf, sizeof(*sf)))
@@ -198,73 +171,6 @@ segv_and_exit:
198 force_sig(SIGSEGV, current); 171 force_sig(SIGSEGV, current);
199} 172}
200 173
201asmlinkage void do_sigreturn(struct pt_regs *regs)
202{
203 struct sigcontext __user *scptr;
204 unsigned long pc, npc, psr;
205 sigset_t set;
206 int err;
207
208 /* Always make any pending restarted system calls return -EINTR */
209 current_thread_info()->restart_block.fn = do_no_restart_syscall;
210
211 synchronize_user_stack();
212
213 if (current->thread.new_signal) {
214 do_new_sigreturn(regs);
215 return;
216 }
217
218 scptr = (struct sigcontext __user *) regs->u_regs[UREG_I0];
219
220 /* Check sanity of the user arg. */
221 if (!access_ok(VERIFY_READ, scptr, sizeof(struct sigcontext)) ||
222 (((unsigned long) scptr) & 3))
223 goto segv_and_exit;
224
225 err = __get_user(pc, &scptr->sigc_pc);
226 err |= __get_user(npc, &scptr->sigc_npc);
227
228 if ((pc | npc) & 3)
229 goto segv_and_exit;
230
231 /* This is pretty much atomic, no amount locking would prevent
232 * the races which exist anyways.
233 */
234 err |= __get_user(set.sig[0], &scptr->sigc_mask);
235 /* Note that scptr + 1 points to extramask */
236 err |= __copy_from_user(&set.sig[1], scptr + 1,
237 (_NSIG_WORDS - 1) * sizeof(unsigned int));
238
239 if (err)
240 goto segv_and_exit;
241
242 sigdelsetmask(&set, ~_BLOCKABLE);
243 spin_lock_irq(&current->sighand->siglock);
244 current->blocked = set;
245 recalc_sigpending();
246 spin_unlock_irq(&current->sighand->siglock);
247
248 regs->pc = pc;
249 regs->npc = npc;
250
251 err = __get_user(regs->u_regs[UREG_FP], &scptr->sigc_sp);
252 err |= __get_user(regs->u_regs[UREG_I0], &scptr->sigc_o0);
253 err |= __get_user(regs->u_regs[UREG_G1], &scptr->sigc_g1);
254
255 /* User can only change condition codes in %psr. */
256 err |= __get_user(psr, &scptr->sigc_psr);
257 if (err)
258 goto segv_and_exit;
259
260 regs->psr &= ~(PSR_ICC);
261 regs->psr |= (psr & PSR_ICC);
262 return;
263
264segv_and_exit:
265 force_sig(SIGSEGV, current);
266}
267
268asmlinkage void do_rt_sigreturn(struct pt_regs *regs) 174asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
269{ 175{
270 struct rt_signal_frame __user *sf; 176 struct rt_signal_frame __user *sf;
@@ -351,128 +257,6 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re
351 return (void __user *)(sp - framesize); 257 return (void __user *)(sp - framesize);
352} 258}
353 259
354static inline void
355setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info)
356{
357 struct signal_sframe __user *sframep;
358 struct sigcontext __user *sc;
359 int window = 0, err;
360 unsigned long pc = regs->pc;
361 unsigned long npc = regs->npc;
362 struct thread_info *tp = current_thread_info();
363 void __user *sig_address;
364 int sig_code;
365
366 synchronize_user_stack();
367 sframep = (struct signal_sframe __user *)
368 get_sigframe(sa, regs, SF_ALIGNEDSZ);
369 if (invalid_frame_pointer(sframep, sizeof(*sframep))){
370 /* Don't change signal code and address, so that
371 * post mortem debuggers can have a look.
372 */
373 goto sigill_and_return;
374 }
375
376 sc = &sframep->sig_context;
377
378 /* We've already made sure frame pointer isn't in kernel space... */
379 err = __put_user((sas_ss_flags(regs->u_regs[UREG_FP]) == SS_ONSTACK),
380 &sc->sigc_onstack);
381 err |= __put_user(oldset->sig[0], &sc->sigc_mask);
382 err |= __copy_to_user(sframep->extramask, &oldset->sig[1],
383 (_NSIG_WORDS - 1) * sizeof(unsigned int));
384 err |= __put_user(regs->u_regs[UREG_FP], &sc->sigc_sp);
385 err |= __put_user(pc, &sc->sigc_pc);
386 err |= __put_user(npc, &sc->sigc_npc);
387 err |= __put_user(regs->psr, &sc->sigc_psr);
388 err |= __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
389 err |= __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
390 err |= __put_user(tp->w_saved, &sc->sigc_oswins);
391 if (tp->w_saved)
392 for (window = 0; window < tp->w_saved; window++) {
393 put_user((char *)tp->rwbuf_stkptrs[window],
394 &sc->sigc_spbuf[window]);
395 err |= __copy_to_user(&sc->sigc_wbuf[window],
396 &tp->reg_window[window],
397 sizeof(struct reg_window));
398 }
399 else
400 err |= __copy_to_user(sframep, (char *) regs->u_regs[UREG_FP],
401 sizeof(struct reg_window));
402
403 tp->w_saved = 0; /* So process is allowed to execute. */
404
405 err |= __put_user(signr, &sframep->sig_num);
406 sig_address = NULL;
407 sig_code = 0;
408 if (SI_FROMKERNEL (info) && (info->si_code & __SI_MASK) == __SI_FAULT) {
409 sig_address = info->si_addr;
410 switch (signr) {
411 case SIGSEGV:
412 switch (info->si_code) {
413 case SEGV_MAPERR: sig_code = SUBSIG_NOMAPPING; break;
414 default: sig_code = SUBSIG_PROTECTION; break;
415 }
416 break;
417 case SIGILL:
418 switch (info->si_code) {
419 case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break;
420 case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break;
421 case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP(info->si_trapno); break;
422 default: sig_code = SUBSIG_STACK; break;
423 }
424 break;
425 case SIGFPE:
426 switch (info->si_code) {
427 case FPE_INTDIV: sig_code = SUBSIG_IDIVZERO; break;
428 case FPE_INTOVF: sig_code = SUBSIG_FPINTOVFL; break;
429 case FPE_FLTDIV: sig_code = SUBSIG_FPDIVZERO; break;
430 case FPE_FLTOVF: sig_code = SUBSIG_FPOVFLOW; break;
431 case FPE_FLTUND: sig_code = SUBSIG_FPUNFLOW; break;
432 case FPE_FLTRES: sig_code = SUBSIG_FPINEXACT; break;
433 case FPE_FLTINV: sig_code = SUBSIG_FPOPERROR; break;
434 default: sig_code = SUBSIG_FPERROR; break;
435 }
436 break;
437 case SIGBUS:
438 switch (info->si_code) {
439 case BUS_ADRALN: sig_code = SUBSIG_ALIGNMENT; break;
440 case BUS_ADRERR: sig_code = SUBSIG_MISCERROR; break;
441 default: sig_code = SUBSIG_BUSTIMEOUT; break;
442 }
443 break;
444 case SIGEMT:
445 switch (info->si_code) {
446 case EMT_TAGOVF: sig_code = SUBSIG_TAG; break;
447 }
448 break;
449 case SIGSYS:
450 if (info->si_code == (__SI_FAULT|0x100)) {
451 sig_code = info->si_trapno;
452 break;
453 }
454 default:
455 sig_address = NULL;
456 }
457 }
458 err |= __put_user((unsigned long)sig_address, &sframep->sig_address);
459 err |= __put_user(sig_code, &sframep->sig_code);
460 err |= __put_user(sc, &sframep->sig_scptr);
461 if (err)
462 goto sigsegv;
463
464 regs->u_regs[UREG_FP] = (unsigned long) sframep;
465 regs->pc = (unsigned long) sa->sa_handler;
466 regs->npc = (regs->pc + 4);
467 return;
468
469sigill_and_return:
470 do_exit(SIGILL);
471sigsegv:
472 force_sigsegv(signr, current);
473}
474
475
476static inline int 260static inline int
477save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) 261save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
478{ 262{
@@ -508,21 +292,20 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
508 return err; 292 return err;
509} 293}
510 294
511static inline void 295static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
512new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs, 296 int signo, sigset_t *oldset)
513 int signo, sigset_t *oldset)
514{ 297{
515 struct new_signal_frame __user *sf; 298 struct signal_frame __user *sf;
516 int sigframe_size, err; 299 int sigframe_size, err;
517 300
518 /* 1. Make sure everything is clean */ 301 /* 1. Make sure everything is clean */
519 synchronize_user_stack(); 302 synchronize_user_stack();
520 303
521 sigframe_size = NF_ALIGNEDSZ; 304 sigframe_size = SF_ALIGNEDSZ;
522 if (!used_math()) 305 if (!used_math())
523 sigframe_size -= sizeof(__siginfo_fpu_t); 306 sigframe_size -= sizeof(__siginfo_fpu_t);
524 307
525 sf = (struct new_signal_frame __user *) 308 sf = (struct signal_frame __user *)
526 get_sigframe(&ka->sa, regs, sigframe_size); 309 get_sigframe(&ka->sa, regs, sigframe_size);
527 310
528 if (invalid_frame_pointer(sf, sigframe_size)) 311 if (invalid_frame_pointer(sf, sigframe_size))
@@ -586,9 +369,8 @@ sigsegv:
586 force_sigsegv(signo, current); 369 force_sigsegv(signo, current);
587} 370}
588 371
589static inline void 372static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
590new_setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, 373 int signo, sigset_t *oldset, siginfo_t *info)
591 int signo, sigset_t *oldset, siginfo_t *info)
592{ 374{
593 struct rt_signal_frame __user *sf; 375 struct rt_signal_frame __user *sf;
594 int sigframe_size; 376 int sigframe_size;
@@ -674,11 +456,9 @@ handle_signal(unsigned long signr, struct k_sigaction *ka,
674 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) 456 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
675{ 457{
676 if (ka->sa.sa_flags & SA_SIGINFO) 458 if (ka->sa.sa_flags & SA_SIGINFO)
677 new_setup_rt_frame(ka, regs, signr, oldset, info); 459 setup_rt_frame(ka, regs, signr, oldset, info);
678 else if (current->thread.new_signal)
679 new_setup_frame(ka, regs, signr, oldset);
680 else 460 else
681 setup_frame(&ka->sa, regs, signr, oldset, info); 461 setup_frame(ka, regs, signr, oldset);
682 462
683 spin_lock_irq(&current->sighand->siglock); 463 spin_lock_irq(&current->sighand->siglock);
684 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 464 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index 42bf09db9a81..f188b5dc9fd0 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -1,5 +1,4 @@
1/* $Id: sys_sparc.c,v 1.70 2001/04/14 01:12:02 davem Exp $ 1/* linux/arch/sparc/kernel/sys_sparc.c
2 * linux/arch/sparc/kernel/sys_sparc.c
3 * 2 *
4 * This file contains various random system calls that 3 * This file contains various random system calls that
5 * have a non-standard calling sequence on the Linux/sparc 4 * have a non-standard calling sequence on the Linux/sparc
@@ -395,10 +394,8 @@ sparc_sigaction (int sig, const struct old_sigaction __user *act,
395 struct k_sigaction new_ka, old_ka; 394 struct k_sigaction new_ka, old_ka;
396 int ret; 395 int ret;
397 396
398 if (sig < 0) { 397 WARN_ON_ONCE(sig >= 0);
399 current->thread.new_signal = 1; 398 sig = -sig;
400 sig = -sig;
401 }
402 399
403 if (act) { 400 if (act) {
404 unsigned long mask; 401 unsigned long mask;
@@ -446,11 +443,6 @@ sys_rt_sigaction(int sig,
446 if (sigsetsize != sizeof(sigset_t)) 443 if (sigsetsize != sizeof(sigset_t))
447 return -EINVAL; 444 return -EINVAL;
448 445
449 /* All tasks which use RT signals (effectively) use
450 * new style signals.
451 */
452 current->thread.new_signal = 1;
453
454 if (act) { 446 if (act) {
455 new_ka.ka_restorer = restorer; 447 new_ka.ka_restorer = restorer;
456 if (copy_from_user(&new_ka.sa, act, sizeof(*act))) 448 if (copy_from_user(&new_ka.sa, act, sizeof(*act)))
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
diff --git a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h
index e3006979709b..8898efbbbe07 100644
--- a/include/asm-sparc/processor.h
+++ b/include/asm-sparc/processor.h
@@ -1,5 +1,4 @@
1/* $Id: processor.h,v 1.83 2001/10/08 09:32:13 davem Exp $ 1/* include/asm-sparc/processor.h
2 * include/asm-sparc/processor.h
3 * 2 *
4 * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) 3 * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
5 */ 4 */
@@ -65,7 +64,6 @@ struct thread_struct {
65 struct fpq fpqueue[16]; 64 struct fpq fpqueue[16];
66 unsigned long flags; 65 unsigned long flags;
67 mm_segment_t current_ds; 66 mm_segment_t current_ds;
68 int new_signal;
69}; 67};
70 68
71#define SPARC_FLAG_KTHREAD 0x1 /* task is a kernel thread */ 69#define SPARC_FLAG_KTHREAD 0x1 /* task is a kernel thread */
diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
index 98252cd44dd6..71e42d1a80d9 100644
--- a/include/asm-sparc64/thread_info.h
+++ b/include/asm-sparc64/thread_info.h
@@ -1,5 +1,4 @@
1/* $Id: thread_info.h,v 1.1 2002/02/10 00:00:58 davem Exp $ 1/* thread_info.h: sparc64 low-level thread information
2 * thread_info.h: sparc64 low-level thread information
3 * 2 *
4 * Copyright (C) 2002 David S. Miller (davem@redhat.com) 3 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
5 */ 4 */
@@ -223,7 +222,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
223#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ 222#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
224#define TIF_PERFCTR 4 /* performance counters active */ 223#define TIF_PERFCTR 4 /* performance counters active */
225#define TIF_UNALIGNED 5 /* allowed to do unaligned accesses */ 224#define TIF_UNALIGNED 5 /* allowed to do unaligned accesses */
226#define TIF_NEWSIGNALS 6 /* wants new-style signals */ 225/* flag bit 6 is available */
227#define TIF_32BIT 7 /* 32-bit binary */ 226#define TIF_32BIT 7 /* 32-bit binary */
228/* flag bit 8 is available */ 227/* flag bit 8 is available */
229#define TIF_SECCOMP 9 /* secure computing */ 228#define TIF_SECCOMP 9 /* secure computing */
@@ -242,7 +241,6 @@ register struct thread_info *current_thread_info_reg asm("g6");
242#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) 241#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
243#define _TIF_PERFCTR (1<<TIF_PERFCTR) 242#define _TIF_PERFCTR (1<<TIF_PERFCTR)
244#define _TIF_UNALIGNED (1<<TIF_UNALIGNED) 243#define _TIF_UNALIGNED (1<<TIF_UNALIGNED)
245#define _TIF_NEWSIGNALS (1<<TIF_NEWSIGNALS)
246#define _TIF_32BIT (1<<TIF_32BIT) 244#define _TIF_32BIT (1<<TIF_32BIT)
247#define _TIF_SECCOMP (1<<TIF_SECCOMP) 245#define _TIF_SECCOMP (1<<TIF_SECCOMP)
248#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 246#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)