patch-2.1.45 linux/arch/sparc64/kernel/signal32.c
Next file: linux/arch/sparc64/kernel/smp.c
Previous file: linux/arch/sparc64/kernel/signal.c
Back to the patch index
Back to the overall index
- Lines: 182
- Date:
Wed Jul 16 19:22:50 1997
- Orig file:
v2.1.44/linux/arch/sparc64/kernel/signal32.c
- Orig date:
Mon Jul 7 08:18:54 1997
diff -u --recursive --new-file v2.1.44/linux/arch/sparc64/kernel/signal32.c linux/arch/sparc64/kernel/signal32.c
@@ -1,4 +1,4 @@
-/* $Id: signal32.c,v 1.23 1997/07/05 07:09:15 davem Exp $
+/* $Id: signal32.c,v 1.26 1997/07/14 03:10:31 davem Exp $
* arch/sparc64/kernel/signal32.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -245,7 +245,6 @@
#endif
int old_status = current->tss.sstk_info.cur_status;
unsigned psr;
- int i;
synchronize_user_stack();
regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
@@ -292,13 +291,9 @@
}
else
#endif
- /* XXX Perhaps we need a copy_in_user()? -DaveM */
- for (i = 0; i < 16; i++) {
- u32 temp;
-
- get_user (temp, (((u32 *)(regs->u_regs[UREG_FP]))+i));
- put_user (temp, (((u32 *)sframep)+i));
- }
+ copy_in_user((u32 *)sframep,
+ (u32 *)(regs->u_regs[UREG_FP]),
+ sizeof(struct reg_window32));
current->tss.w_saved = 0; /* So process is allowed to execute. */
__put_user(signr, &sframep->sig_num);
@@ -351,8 +346,7 @@
printk("new_setup_frame32(%s:%d): invalid_frame_pointer(%p, %d)\n",
current->comm, current->pid, sf, sigframe_size);
#endif
- lock_kernel ();
- do_exit(SIGILL);
+ goto sigill;
}
if (current->tss.w_saved != 0) {
@@ -360,8 +354,7 @@
printk ("%s[%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
#endif
- lock_kernel ();
- do_exit (SIGILL);
+ goto sigill;
}
/* 2. Save the current process state */
@@ -384,13 +377,9 @@
__put_user(oldmask, &sf->info.si_mask);
- /* XXX Perhaps we need a copy_in_user()? -DaveM */
- for (i = 0; i < sizeof(struct reg_window32)/4; i++) {
- u32 tmp;
-
- __get_user(tmp, (((u32 *)regs->u_regs[UREG_FP])+i));
- __put_user(tmp, (((u32 *)sf)+i));
- }
+ copy_in_user((u32 *)sf,
+ (u32 *)(regs->u_regs[UREG_FP]),
+ sizeof(struct reg_window32));
/* 3. return to kernel instructions */
__put_user(0x821020d8, &sf->insns[0]); /* mov __NR_sigreturn, %g1 */
@@ -423,6 +412,11 @@
: "memory");
}
}
+ return;
+
+sigill:
+ lock_kernel();
+ do_exit(SIGILL);
}
/* Setup a Solaris stack frame */
@@ -614,16 +608,16 @@
if (tp->w_saved){
printk ("Uh oh, w_saved is: 0x%lx\n", tp->w_saved);
- do_exit(SIGSEGV);
+ goto sigsegv;
}
if (((unsigned long) c) & 3){
printk ("Unaligned structure passed\n");
- do_exit (SIGSEGV);
+ goto sigsegv;
}
if(!__access_ok((unsigned long)c, sizeof(*c))) {
/* Miguel, add nice debugging msg _here_. ;-) */
- do_exit(SIGSEGV);
+ goto sigsegv;
}
/* Check for valid PC and nPC */
@@ -632,7 +626,7 @@
__get_user(npc, &((*gr)[SVR4_NPC]));
if((pc | npc) & 3) {
printk ("setcontext, PC or nPC were bogus\n");
- do_exit (SIGSEGV);
+ goto sigsegv;
}
/* Retrieve information from passed ucontext */
/* note that nPC is ored a 1, this is used to inform entry.S */
@@ -655,6 +649,9 @@
__get_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
return -EINTR;
+sigsegv:
+ lock_kernel();
+ do_exit(SIGSEGV);
}
static inline void handle_signal32(unsigned long signr, struct sigaction *sa,
@@ -671,8 +668,11 @@
}
if(sa->sa_flags & SA_ONESHOT)
sa->sa_handler = NULL;
- if(!(sa->sa_flags & SA_NOMASK))
+ if(!(sa->sa_flags & SA_NOMASK)) {
+ spin_lock_irq(¤t->sigmask_lock);
current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE;
+ spin_unlock_irq(¤t->sigmask_lock);
+ }
}
static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
@@ -708,7 +708,11 @@
while ((signr = current->signal & mask) != 0) {
signr = ffz(~signr);
- clear_bit(signr + 32, ¤t->signal);
+
+ spin_lock_irq(¤t->sigmask_lock);
+ current->signal &= ~(1 << signr);
+ spin_unlock_irq(¤t->sigmask_lock);
+
sa = current->sig->action + signr;
signr++;
if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
@@ -722,7 +726,9 @@
if (signr == SIGSTOP)
continue;
if (_S(signr) & current->blocked) {
+ spin_lock_irq(¤t->sigmask_lock);
current->signal |= _S(signr);
+ spin_unlock_irq(¤t->sigmask_lock);
continue;
}
sa = current->sig->action + signr - 1;
@@ -765,8 +771,10 @@
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV: case SIGBUS:
if(current->binfmt && current->binfmt->core_dump) {
+ lock_kernel();
if(current->binfmt->core_dump(signr, regs))
signr |= 0x80;
+ unlock_kernel();
}
#ifdef DEBUG_SIGNALS
/* Very useful to debug dynamic linker problems */
@@ -775,9 +783,15 @@
#endif
/* fall through */
default:
+ spin_lock_irq(¤t->sigmask_lock);
current->signal |= _S(signr & 0x7f);
+ spin_unlock_irq(¤t->sigmask_lock);
+
current->flags |= PF_SIGNALED;
+
+ lock_kernel();
do_exit(signr);
+ unlock_kernel();
}
}
if(restart_syscall)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov