X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fcris%2Farch-v10%2Fkernel%2Fsignal.c;h=97b7af26a6475017e2062c3c1c03376974a541aa;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=6698054a576c601464f7ab406efce0926b9b372e;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c index 6698054a5..97b7af26a 100644 --- a/arch/cris/arch-v10/kernel/signal.c +++ b/arch/cris/arch-v10/kernel/signal.c @@ -180,6 +180,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) unsigned int err = 0; unsigned long old_usp; + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + /* restore the regs from &sc->regs (same as sc, since regs is first) * (sc is already checked for VERIFY_READ since the sigframe was * checked in sys_sigreturn previously) @@ -261,7 +264,6 @@ asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13, { struct rt_sigframe __user *frame = (struct rt_sigframe *)rdusp(); sigset_t set; - stack_t st; /* * Since we stacked the signal on a dword boundary, @@ -285,11 +287,8 @@ asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13, if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; - if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) + if (do_sigaltstack(&frame->uc.uc_stack, NULL, rdusp()) == -EFAULT) goto badframe; - /* It is more difficult to avoid calling this function than to - call it and ignore errors. */ - do_sigaltstack(&st, NULL, rdusp()); return regs->r10; @@ -385,9 +384,9 @@ static void setup_frame(int sig, struct k_sigaction *ka, /* trampoline - the desired return ip is the retcode itself */ return_ip = (unsigned long)&frame->retcode; /* This is movu.w __NR_sigreturn, r9; break 13; */ - err |= __put_user(0x9c5f, (short *)(frame->retcode+0)); - err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2)); - err |= __put_user(0xe93d, (short *)(frame->retcode+4)); + err |= __put_user(0x9c5f, (short __user*)(frame->retcode+0)); + err |= __put_user(__NR_sigreturn, (short __user*)(frame->retcode+2)); + err |= __put_user(0xe93d, (short __user*)(frame->retcode+4)); } if (err) @@ -406,9 +405,7 @@ static void setup_frame(int sig, struct k_sigaction *ka, return; give_sigsegv: - if (sig == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; - force_sig(SIGSEGV, current); + force_sigsegv(sig, current); } static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, @@ -447,9 +444,9 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* trampoline - the desired return ip is the retcode itself */ return_ip = (unsigned long)&frame->retcode; /* This is movu.w __NR_rt_sigreturn, r9; break 13; */ - err |= __put_user(0x9c5f, (short *)(frame->retcode+0)); - err |= __put_user(__NR_rt_sigreturn, (short *)(frame->retcode+2)); - err |= __put_user(0xe93d, (short *)(frame->retcode+4)); + err |= __put_user(0x9c5f, (short __user*)(frame->retcode+0)); + err |= __put_user(__NR_rt_sigreturn, (short __user*)(frame->retcode+2)); + err |= __put_user(0xe93d, (short __user*)(frame->retcode+4)); } if (err) @@ -472,9 +469,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, return; give_sigsegv: - if (sig == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; - force_sig(SIGSEGV, current); + force_sigsegv(sig, current); } /* @@ -483,16 +478,14 @@ give_sigsegv: extern inline void handle_signal(int canrestart, unsigned long sig, - siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) + siginfo_t *info, struct k_sigaction *ka, + sigset_t *oldset, struct pt_regs * regs) { - struct k_sigaction *ka = ¤t->sighand->action[sig-1]; - /* Are we from a system call? */ if (canrestart) { /* If so, check system call restarting.. */ switch (regs->r10) { case -ERESTART_RESTARTBLOCK: - current_thread_info()->restart_block.fn = do_no_restart_syscall; case -ERESTARTNOHAND: /* ERESTARTNOHAND means that the syscall should only be restarted if there was no handler for the signal, and since @@ -549,6 +542,7 @@ int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) { siginfo_t info; int signr; + struct k_sigaction ka; /* * We want the common case to go fast, which @@ -562,10 +556,10 @@ int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) if (!oldset) oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, regs, NULL); + signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ - handle_signal(canrestart, signr, &info, oldset, regs); + handle_signal(canrestart, signr, &info, &ka, oldset, regs); return 1; }