--- zzzz-none-000/linux-3.10.107/arch/m68k/kernel/signal.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/m68k/kernel/signal.c 2021-02-04 17:41:59.000000000 +0000 @@ -50,6 +50,7 @@ #include #include #include +#include #ifdef CONFIG_MMU @@ -181,6 +182,13 @@ asm volatile ("movec %0,%%caar\n\t" "movec %1,%%cacr" : : "r" (vaddr + 4), "r" (temp)); + } else { + /* CPU_IS_COLDFIRE */ +#if defined(CONFIG_CACHE_COPYBACK) + flush_cf_dcache(0, DCACHE_MAX_ADDR); +#endif + /* Invalidate instruction cache for the pushed bytes */ + clear_cf_icache(vaddr, vaddr + 8); } } @@ -647,7 +655,7 @@ int err = 0; /* 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; /* get previous context */ if (copy_from_user(&context, usc, sizeof(context))) @@ -685,7 +693,7 @@ int err; /* 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; err = __get_user(temp, &uc->uc_mcontext.version); if (temp != MCONTEXT_VERSION) @@ -827,48 +835,35 @@ } 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 usp; - - /* Default to using normal stack. */ - usp = rdusp(); + unsigned long usp = sigsp(rdusp(), ksig); - /* This is the X/Open sanctioned signal stack switching. */ - if (ka->sa.sa_flags & SA_ONSTACK) { - if (!sas_ss_flags(usp)) - usp = current->sas_ss_sp + current->sas_ss_size; - } return (void __user *)((usp - frame_size) & -8UL); } -static int setup_frame (int sig, struct k_sigaction *ka, - sigset_t *set, struct pt_regs *regs) +static int setup_frame(struct ksignal *ksig, sigset_t *set, + struct pt_regs *regs) { struct sigframe __user *frame; int fsize = frame_extra_sizes(regs->format); struct sigcontext context; - int err = 0; + int err = 0, sig = ksig->sig; if (fsize < 0) { #ifdef DEBUG printk ("setup_frame: Unknown frame format %#x\n", regs->format); #endif - goto give_sigsegv; + return -EFAULT; } - frame = get_sigframe(ka, regs, sizeof(*frame) + fsize); + frame = get_sigframe(ksig, sizeof(*frame) + fsize); if (fsize) err |= copy_to_user (frame + 1, regs + 1, fsize); - err |= __put_user((current_thread_info()->exec_domain - && current_thread_info()->exec_domain->signal_invmap - && sig < 32 - ? current_thread_info()->exec_domain->signal_invmap[sig] - : sig), - &frame->sig); + err |= __put_user(sig, &frame->sig); err |= __put_user(regs->vector, &frame->code); err |= __put_user(&frame->sc, &frame->psc); @@ -891,7 +886,7 @@ #endif if (err) - goto give_sigsegv; + return -EFAULT; push_cache ((unsigned long) &frame->retcode); @@ -900,7 +895,7 @@ * to destroy is successfully copied to sigframe. */ wrusp ((unsigned long) frame); - regs->pc = (unsigned long) ka->sa.sa_handler; + regs->pc = (unsigned long) ksig->ka.sa.sa_handler; adjustformat(regs); /* @@ -926,41 +921,32 @@ tregs->sr = regs->sr; } return 0; - -give_sigsegv: - force_sigsegv(sig, current); - return err; } -static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs *regs) +static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, + struct pt_regs *regs) { struct rt_sigframe __user *frame; int fsize = frame_extra_sizes(regs->format); - int err = 0; + int err = 0, sig = ksig->sig; if (fsize < 0) { #ifdef DEBUG printk ("setup_frame: Unknown frame format %#x\n", regs->format); #endif - goto give_sigsegv; + return -EFAULT; } - frame = get_sigframe(ka, regs, sizeof(*frame)); + frame = get_sigframe(ksig, sizeof(*frame)); if (fsize) err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); - err |= __put_user((current_thread_info()->exec_domain - && current_thread_info()->exec_domain->signal_invmap - && sig < 32 - ? current_thread_info()->exec_domain->signal_invmap[sig] - : sig), - &frame->sig); + err |= __put_user(sig, &frame->sig); 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); /* Create the ucontext. */ err |= __put_user(0, &frame->uc.uc_flags); @@ -988,7 +974,7 @@ #endif /* CONFIG_MMU */ if (err) - goto give_sigsegv; + return -EFAULT; push_cache ((unsigned long) &frame->retcode); @@ -997,7 +983,7 @@ * to destroy is successfully copied to sigframe. */ wrusp ((unsigned long) frame); - regs->pc = (unsigned long) ka->sa.sa_handler; + regs->pc = (unsigned long) ksig->ka.sa.sa_handler; adjustformat(regs); /* @@ -1023,10 +1009,6 @@ tregs->sr = regs->sr; } return 0; - -give_sigsegv: - force_sigsegv(sig, current); - return err; } static inline void @@ -1066,26 +1048,22 @@ * OK, we're invoking a handler */ static void -handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, - struct pt_regs *regs) +handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int err; /* are we from a system call? */ if (regs->orig_d0 >= 0) /* If so, check system call restarting.. */ - handle_restart(regs, ka, 1); + handle_restart(regs, &ksig->ka, 1); /* set up the stack frame */ - if (ka->sa.sa_flags & SA_SIGINFO) - err = setup_rt_frame(sig, ka, info, oldset, regs); + if (ksig->ka.sa.sa_flags & SA_SIGINFO) + err = setup_rt_frame(ksig, oldset, regs); else - err = setup_frame(sig, ka, oldset, regs); - - if (err) - return; + err = setup_frame(ksig, oldset, regs); - signal_delivered(sig, info, ka, regs, 0); + signal_setup_done(err, ksig, 0); if (test_thread_flag(TIF_DELAYED_TRACE)) { regs->sr &= ~0x8000; @@ -1100,16 +1078,13 @@ */ static void do_signal(struct pt_regs *regs) { - siginfo_t info; - struct k_sigaction ka; - int signr; + struct ksignal ksig; current->thread.esp0 = (unsigned long) regs; - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - if (signr > 0) { + if (get_signal(&ksig)) { /* Whee! Actually deliver the signal. */ - handle_signal(signr, &ka, &info, regs); + handle_signal(&ksig, regs); return; }