--- zzzz-none-000/linux-3.10.107/arch/cris/arch-v32/kernel/signal.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/cris/arch-v32/kernel/signal.c 2021-02-04 17:41:59.000000000 +0000 @@ -19,7 +19,6 @@ #include #include #include -#include #include extern unsigned long cris_signal_return_page; @@ -59,7 +58,7 @@ unsigned long old_usp; /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; + current->restart_block.fn = do_no_restart_syscall; /* * Restore the registers from &sc->regs. sc is already checked @@ -72,6 +71,9 @@ /* Make that the user-mode flag is set. */ regs->ccs |= (1 << (U_CCS_BITNR + CCS_SHIFT)); + /* Don't perform syscall restarting */ + regs->exs = -1; + /* Restore the old USP. */ err |= __get_user(old_usp, &sc->usp); wrusp(old_usp); @@ -189,17 +191,9 @@ /* Figure out where to put the new signal frame - usually on the stack. */ static inline void __user * -get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) +get_sigframe(struct ksignal *ksig, size_t frame_size) { - unsigned long sp; - - sp = rdusp(); - - /* This is the X/Open sanctioned signal stack switching. */ - if (ka->sa.sa_flags & SA_ONSTACK) { - if (!on_sig_stack(sp)) - sp = current->sas_ss_sp + current->sas_ss_size; - } + unsigned long sp = sigsp(rdusp(), ksig); /* Make sure the frame is dword-aligned. */ sp &= ~3; @@ -215,23 +209,22 @@ * trampoline. */ static int -setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, - struct pt_regs * regs) +setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { int err; unsigned long return_ip; struct signal_frame __user *frame; err = 0; - frame = get_sigframe(ka, regs, sizeof(*frame)); + frame = get_sigframe(ksig, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto give_sigsegv; + return -EFAULT; err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); if (err) - goto give_sigsegv; + return -EFAULT; if (_NSIG_WORDS > 1) { err |= __copy_to_user(frame->extramask, &set->sig[1], @@ -239,14 +232,14 @@ } if (err) - goto give_sigsegv; + return -EFAULT; /* * Set up to return from user-space. If provided, use a stub * already located in user-space. */ - if (ka->sa.sa_flags & SA_RESTORER) { - return_ip = (unsigned long)ka->sa.sa_restorer; + if (ksig->ka.sa.sa_flags & SA_RESTORER) { + return_ip = (unsigned long)ksig->ka.sa.sa_restorer; } else { /* Trampoline - the desired return ip is in the signal return page. */ return_ip = cris_signal_return_page; @@ -264,7 +257,7 @@ } if (err) - goto give_sigsegv; + return -EFAULT; /* * Set up registers for signal handler. @@ -273,42 +266,35 @@ * Where the code enter later. * First argument, signo. */ - regs->erp = (unsigned long) ka->sa.sa_handler; + regs->erp = (unsigned long) ksig->ka.sa.sa_handler; regs->srp = return_ip; - regs->r10 = sig; + regs->r10 = ksig->sig; /* Actually move the USP to reflect the stacked frame. */ wrusp((unsigned long)frame); return 0; - -give_sigsegv: - force_sigsegv(sig, current); - return -EFAULT; } static int -setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs * regs) +setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { int err; unsigned long return_ip; struct rt_signal_frame __user *frame; err = 0; - frame = get_sigframe(ka, regs, sizeof(*frame)); + frame = get_sigframe(ksig, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto give_sigsegv; - - /* TODO: what is the current->exec_domain stuff and invmap ? */ + return -EFAULT; err |= __put_user(&frame->info, &frame->pinfo); err |= __put_user(&frame->uc, &frame->puc); - err |= copy_siginfo_to_user(&frame->info, info); + err |= copy_siginfo_to_user(&frame->info, &ksig->info); if (err) - goto give_sigsegv; + return -EFAULT; /* Clear all the bits of the ucontext we don't use. */ err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); @@ -317,14 +303,14 @@ err |= __save_altstack(&frame->uc.uc_stack, rdusp()); if (err) - goto give_sigsegv; + return -EFAULT; /* * Set up to return from user-space. If provided, use a stub * already located in user-space. */ - if (ka->sa.sa_flags & SA_RESTORER) { - return_ip = (unsigned long) ka->sa.sa_restorer; + if (ksig->ka.sa.sa_flags & SA_RESTORER) { + return_ip = (unsigned long) ksig->ka.sa.sa_restorer; } else { /* Trampoline - the desired return ip is in the signal return page. */ return_ip = cris_signal_return_page + 6; @@ -345,7 +331,7 @@ } if (err) - goto give_sigsegv; + return -EFAULT; /* * Set up registers for signal handler. @@ -356,9 +342,9 @@ * Second argument is (siginfo_t *). * Third argument is unused. */ - regs->erp = (unsigned long) ka->sa.sa_handler; + regs->erp = (unsigned long) ksig->ka.sa.sa_handler; regs->srp = return_ip; - regs->r10 = sig; + regs->r10 = ksig->sig; regs->r11 = (unsigned long) &frame->info; regs->r12 = 0; @@ -366,17 +352,11 @@ wrusp((unsigned long)frame); return 0; - -give_sigsegv: - force_sigsegv(sig, current); - return -EFAULT; } /* Invoke a signal handler to, well, handle the signal. */ static inline void -handle_signal(int canrestart, unsigned long sig, - siginfo_t *info, struct k_sigaction *ka, - struct pt_regs * regs) +handle_signal(int canrestart, struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; @@ -404,7 +384,7 @@ * there is no handler, or the handler * was registered with SA_RESTART. */ - if (!(ka->sa.sa_flags & SA_RESTART)) { + if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { regs->r10 = -EINTR; break; } @@ -423,13 +403,12 @@ } /* Set up the stack frame. */ - if (ka->sa.sa_flags & SA_SIGINFO) - ret = setup_rt_frame(sig, ka, info, oldset, regs); + if (ksig->ka.sa.sa_flags & SA_SIGINFO) + ret = setup_rt_frame(ksig, oldset, regs); else - ret = setup_frame(sig, ka, oldset, regs); + ret = setup_frame(ksig, oldset, regs); - if (ret == 0) - signal_delivered(sig, info, ka, regs, 0); + signal_setup_done(ret, ksig, 0); } /* @@ -446,9 +425,9 @@ void do_signal(int canrestart, struct pt_regs *regs) { - int signr; - siginfo_t info; - struct k_sigaction ka; + struct ksignal ksig; + + canrestart = canrestart && ((int)regs->exs >= 0); /* * The common case should go fast, which is why this point is @@ -458,11 +437,9 @@ if (!user_mode(regs)) return; - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - - if (signr > 0) { + if (get_signal(&ksig)) { /* Whee! Actually deliver the signal. */ - handle_signal(canrestart, signr, &info, &ka, regs); + handle_signal(canrestart, &ksig, regs); return; }