--- zzzz-none-000/linux-3.10.107/arch/parisc/kernel/signal.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/parisc/kernel/signal.c 2021-02-04 17:41:59.000000000 +0000 @@ -9,8 +9,7 @@ * * Like the IA-64, we are a recent enough port (we are *starting* * with glibc2.2) that we do not need to support the old non-realtime - * Linux signals. Therefore we don't. HP/UX signals will go in - * arch/parisc/hpux/signal.c when we figure out how to do them. + * Linux signals. Therefore we don't. */ #include @@ -56,13 +55,6 @@ #define A(__x) ((unsigned long)(__x)) /* - * Atomically swap in the new signal mask, and wait for a signal. - */ -#ifdef CONFIG_64BIT -#include "sys32.h" -#endif - -/* * Do a signal return - restore sigcontext. */ @@ -85,7 +77,7 @@ err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq)); err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq)); err |= __get_user(regs->sar, &sc->sc_sar); - DBG(2,"restore_sigcontext: iaoq is 0x%#lx / 0x%#lx\n", + DBG(2,"restore_sigcontext: iaoq is %#lx / %#lx\n", regs->iaoq[0],regs->iaoq[1]); DBG(2,"restore_sigcontext: r28 is %ld\n", regs->gr[28]); return err; @@ -106,7 +98,7 @@ sigframe_size = PARISC_RT_SIGFRAME_SIZE32; #endif - current_thread_info()->restart_block.fn = do_no_restart_syscall; + current->restart_block.fn = do_no_restart_syscall; /* Unwind the user stack to get the rt_sigframe structure. */ frame = (struct rt_sigframe __user *) @@ -234,8 +226,8 @@ } static long -setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs *regs, int in_syscall) +setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs, + int in_syscall) { struct rt_sigframe __user *frame; unsigned long rp, usp; @@ -248,10 +240,10 @@ usp = (regs->gr[30] & ~(0x01UL)); /*FIXME: frame_size parameter is unused, remove it. */ - frame = get_sigframe(ka, usp, sizeof(*frame)); + frame = get_sigframe(&ksig->ka, usp, sizeof(*frame)); DBG(1,"SETUP_RT_FRAME: START\n"); - DBG(1,"setup_rt_frame: frame %p info %p\n", frame, info); + DBG(1,"setup_rt_frame: frame %p info %p\n", frame, ksig->info); #ifdef CONFIG_64BIT @@ -260,7 +252,7 @@ if (is_compat_task()) { DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); - err |= copy_siginfo_to_user32(&compat_frame->info, info); + err |= copy_siginfo_to_user32(&compat_frame->info, &ksig->info); err |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]); DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc); DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext); @@ -272,7 +264,7 @@ #endif { DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info); - err |= copy_siginfo_to_user(&frame->info, info); + err |= copy_siginfo_to_user(&frame->info, &ksig->info); err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]); DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc); DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext); @@ -282,7 +274,7 @@ } if (err) - goto give_sigsegv; + return -EFAULT; /* Set up to return from userspace. If provided, use a stub already in userspace. The first words of tramp are used to @@ -319,9 +311,9 @@ rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP]; if (err) - goto give_sigsegv; + return -EFAULT; - haddr = A(ka->sa.sa_handler); + haddr = A(ksig->ka.sa.sa_handler); /* The sa_handler may be a pointer to a function descriptor */ #ifdef CONFIG_64BIT if (is_compat_task()) { @@ -333,7 +325,7 @@ err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc)); if (err) - goto give_sigsegv; + return -EFAULT; haddr = fdesc.addr; regs->gr[19] = fdesc.gp; @@ -346,7 +338,7 @@ err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc)); if (err) - goto give_sigsegv; + return -EFAULT; haddr = fdesc.addr; regs->gr[19] = fdesc.gp; @@ -393,7 +385,7 @@ } regs->gr[2] = rp; /* userland return pointer */ - regs->gr[26] = sig; /* signal number */ + regs->gr[26] = ksig->sig; /* signal number */ #ifdef CONFIG_64BIT if (is_compat_task()) { @@ -417,11 +409,6 @@ current->comm, current->pid, frame, regs->gr[30], regs->iaoq[0], regs->iaoq[1], rp); - return 1; - -give_sigsegv: - DBG(1,"setup_rt_frame: sending SIGSEGV\n"); - force_sigsegv(sig, current); return 0; } @@ -430,20 +417,19 @@ */ static void -handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, - struct pt_regs *regs, int in_syscall) +handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall) { + int ret; sigset_t *oldset = sigmask_to_save(); + DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n", - sig, ka, info, oldset, regs); + ksig->sig, ksig->ka, ksig->info, oldset, regs); /* Set up the stack frame */ - if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall)) - return; + ret = setup_rt_frame(ksig, oldset, regs, in_syscall); - signal_delivered(sig, info, ka, regs, - test_thread_flag(TIF_SINGLESTEP) || - test_thread_flag(TIF_BLOCKSTEP)); + signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP) || + test_thread_flag(TIF_BLOCKSTEP)); DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n", regs->gr[28]); @@ -535,6 +521,9 @@ case -ERESTART_RESTARTBLOCK: { /* Restart the system call - no handlers present */ unsigned int *usp = (unsigned int *)regs->gr[30]; + unsigned long start = (unsigned long) &usp[2]; + unsigned long end = (unsigned long) &usp[5]; + long err = 0; /* Setup a trampoline to restart the syscall * with __NR_restart_syscall @@ -546,23 +535,21 @@ * 16: ldi __NR_restart_syscall, %r20 */ #ifdef CONFIG_64BIT - put_user(regs->gr[31] >> 32, &usp[0]); - put_user(regs->gr[31] & 0xffffffff, &usp[1]); - put_user(0x0fc010df, &usp[2]); + err |= put_user(regs->gr[31] >> 32, &usp[0]); + err |= put_user(regs->gr[31] & 0xffffffff, &usp[1]); + err |= put_user(0x0fc010df, &usp[2]); #else - put_user(regs->gr[31], &usp[0]); - put_user(0x0fc0109f, &usp[2]); + err |= put_user(regs->gr[31], &usp[0]); + err |= put_user(0x0fc0109f, &usp[2]); #endif - put_user(0xe0008200, &usp[3]); - put_user(0x34140000, &usp[4]); + err |= put_user(0xe0008200, &usp[3]); + err |= put_user(0x34140000, &usp[4]); - /* Stack is 64-byte aligned, and we only need - * to flush 1 cache line. - * Flushing one cacheline is cheap. - * "sync" on bigger (> 4 way) boxes is not. - */ - flush_user_dcache_range(regs->gr[30], regs->gr[30] + 4); - flush_user_icache_range(regs->gr[30], regs->gr[30] + 4); + WARN_ON(err); + + /* flush data/instruction cache for new insns */ + flush_user_dcache_range(start, end); + flush_user_icache_range(start, end); regs->gr[31] = regs->gr[30] + 8; return; @@ -591,22 +578,18 @@ asmlinkage void do_signal(struct pt_regs *regs, long in_syscall) { - siginfo_t info; - struct k_sigaction ka; - int signr; + struct ksignal ksig; DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n", regs, regs->sr[7], in_syscall); - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); - - if (signr > 0) { + if (get_signal(&ksig)) { + DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); /* Restart a system call if necessary. */ if (in_syscall) - syscall_restart(regs, &ka); + syscall_restart(regs, &ksig.ka); - handle_signal(signr, &info, &ka, regs, in_syscall); + handle_signal(&ksig, regs, in_syscall); return; }