Loading arch/sparc/kernel/signal32.c +62 −92 Original line number Diff line number Diff line Loading @@ -323,7 +323,7 @@ static int invalid_frame_pointer(void __user *fp, int fplen) return 0; } static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize) static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize) { unsigned long sp; Loading @@ -338,12 +338,7 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns return (void __user *) -1L; /* This is the X/Open sanctioned signal stack switching. */ if (sa->sa_flags & SA_ONSTACK) { if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } sp -= framesize; sp = sigsp(sp, ksig) - framesize; /* Always align the stack frame. This handles two cases. First, * sigaltstack need not be mindful of platform specific stack Loading Loading @@ -414,8 +409,8 @@ out_irqs_on: } static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset) static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs, sigset_t *oldset) { struct signal_frame32 __user *sf; int i, err, wsaved; Loading @@ -437,10 +432,12 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, sigframe_size += sizeof(__siginfo_rwin_t); sf = (struct signal_frame32 __user *) get_sigframe(&ka->sa, regs, sigframe_size); get_sigframe(ksig, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) goto sigill; if (invalid_frame_pointer(sf, sigframe_size)) { do_exit(SIGILL); return -EINVAL; } tail = (sf + 1); Loading Loading @@ -514,16 +511,16 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, err |= __put_user(rp->ins[7], &sf->ss.callers_pc); } if (err) goto sigsegv; return err; /* 3. signal handler back-trampoline and parameters */ regs->u_regs[UREG_FP] = (unsigned long) sf; regs->u_regs[UREG_I0] = signo; regs->u_regs[UREG_I0] = ksig->sig; regs->u_regs[UREG_I1] = (unsigned long) &sf->info; regs->u_regs[UREG_I2] = (unsigned long) &sf->info; /* 4. signal handler */ regs->tpc = (unsigned long) ka->sa.sa_handler; regs->tpc = (unsigned long) ksig->ka.sa.sa_handler; regs->tnpc = (regs->tpc + 4); if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; Loading @@ -531,8 +528,8 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, } /* 5. return to kernel instructions */ if (ka->ka_restorer) { regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; if (ksig->ka.ka_restorer) { regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; } else { unsigned long address = ((unsigned long)&(sf->insns[0])); Loading @@ -541,23 +538,14 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, err = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/ err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/ if (err) goto sigsegv; return err; flush_signal_insns(address); } return 0; sigill: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signo, current); return -EFAULT; } static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, unsigned long signr, sigset_t *oldset, siginfo_t *info) static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs, sigset_t *oldset) { struct rt_signal_frame32 __user *sf; int i, err, wsaved; Loading @@ -579,10 +567,12 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, sigframe_size += sizeof(__siginfo_rwin_t); sf = (struct rt_signal_frame32 __user *) get_sigframe(&ka->sa, regs, sigframe_size); get_sigframe(ksig, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) goto sigill; if (invalid_frame_pointer(sf, sigframe_size)) { do_exit(SIGILL); return -EINVAL; } tail = (sf + 1); Loading Loading @@ -627,7 +617,7 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, } /* Update the siginfo structure. */ err |= copy_siginfo_to_user32(&sf->info, info); err |= copy_siginfo_to_user32(&sf->info, &ksig->info); /* Setup sigaltstack */ err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]); Loading Loading @@ -660,16 +650,16 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, err |= __put_user(rp->ins[7], &sf->ss.callers_pc); } if (err) goto sigsegv; return err; /* 3. signal handler back-trampoline and parameters */ regs->u_regs[UREG_FP] = (unsigned long) sf; regs->u_regs[UREG_I0] = signr; regs->u_regs[UREG_I0] = ksig->sig; regs->u_regs[UREG_I1] = (unsigned long) &sf->info; regs->u_regs[UREG_I2] = (unsigned long) &sf->regs; /* 4. signal handler */ regs->tpc = (unsigned long) ka->sa.sa_handler; regs->tpc = (unsigned long) ksig->ka.sa.sa_handler; regs->tnpc = (regs->tpc + 4); if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; Loading @@ -677,8 +667,8 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, } /* 5. return to kernel instructions */ if (ka->ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; if (ksig->ka.ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; else { unsigned long address = ((unsigned long)&(sf->insns[0])); Loading @@ -690,36 +680,25 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, /* t 0x10 */ err |= __put_user(0x91d02010, &sf->insns[1]); if (err) goto sigsegv; return err; flush_signal_insns(address); } return 0; sigill: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signr, current); return -EFAULT; } static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) static inline void handle_signal32(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int err; if (ka->sa.sa_flags & SA_SIGINFO) err = setup_rt_frame32(ka, regs, signr, oldset, info); if (ksig->ka.sa.sa_flags & SA_SIGINFO) err = setup_rt_frame32(ksig, regs, oldset); else err = setup_frame32(ka, regs, signr, oldset); if (err) return; err = setup_frame32(ksig, regs, oldset); signal_delivered(signr, info, ka, regs, 0); signal_setup_done(err, ksig, 0); } static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, Loading Loading @@ -749,51 +728,42 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs */ void do_signal32(sigset_t *oldset, struct pt_regs * regs) { struct k_sigaction ka; unsigned long orig_i0; int restart_syscall; siginfo_t info; int signr; struct ksignal ksig; unsigned long orig_i0 = 0; int restart_syscall = 0; bool has_handler = get_signal(&ksig); signr = get_signal_to_deliver(&info, &ka, regs, NULL); restart_syscall = 0; orig_i0 = 0; if (pt_regs_is_syscall(regs) && (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { restart_syscall = 1; orig_i0 = regs->u_regs[UREG_G6]; } if (signr > 0) { if (has_handler) { if (restart_syscall) syscall_restart32(orig_i0, regs, &ka.sa); handle_signal32(signr, &ka, &info, oldset, regs); return; } if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { syscall_restart32(orig_i0, regs, &ksig.ka.sa); handle_signal32(&ksig, regs); } else { if (restart_syscall) { switch (regs->u_regs[UREG_I0]) { case ERESTARTNOHAND: case ERESTARTSYS: case ERESTARTNOINTR: /* replay the system call when we are done */ regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { case ERESTART_RESTARTBLOCK: regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } /* If there's no signal to deliver, we just put the saved sigmask * back */ } restore_saved_sigmask(); } } struct sigstack32 { u32 the_stack; Loading arch/sparc/kernel/signal_32.c +59 −87 Original line number Diff line number Diff line Loading @@ -186,7 +186,7 @@ static inline int invalid_frame_pointer(void __user *fp, int fplen) return 0; } static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize) static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize) { unsigned long sp = regs->u_regs[UREG_FP]; Loading @@ -198,12 +198,7 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re return (void __user *) -1L; /* This is the X/Open sanctioned signal stack switching. */ if (sa->sa_flags & SA_ONSTACK) { if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } sp -= framesize; sp = sigsp(sp, ksig) - framesize; /* Always align the stack frame. This handles two cases. First, * sigaltstack need not be mindful of platform specific stack Loading @@ -216,8 +211,8 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re return (void __user *) sp; } static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset) static int setup_frame(struct ksignal *ksig, struct pt_regs *regs, sigset_t *oldset) { struct signal_frame __user *sf; int sigframe_size, err, wsaved; Loading @@ -235,10 +230,12 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, sigframe_size += sizeof(__siginfo_rwin_t); sf = (struct signal_frame __user *) get_sigframe(&ka->sa, regs, sigframe_size); get_sigframe(ksig, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) goto sigill_and_return; if (invalid_frame_pointer(sf, sigframe_size)) { do_exit(SIGILL); return -EINVAL; } tail = sf + 1; Loading Loading @@ -277,21 +274,21 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); } if (err) goto sigsegv; return err; /* 3. signal handler back-trampoline and parameters */ regs->u_regs[UREG_FP] = (unsigned long) sf; regs->u_regs[UREG_I0] = signo; regs->u_regs[UREG_I0] = ksig->sig; regs->u_regs[UREG_I1] = (unsigned long) &sf->info; regs->u_regs[UREG_I2] = (unsigned long) &sf->info; /* 4. signal handler */ regs->pc = (unsigned long) ka->sa.sa_handler; regs->pc = (unsigned long) ksig->ka.sa.sa_handler; regs->npc = (regs->pc + 4); /* 5. return to kernel instructions */ if (ka->ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; if (ksig->ka.ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; else { regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2); Loading @@ -301,24 +298,16 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, /* t 0x10 */ err |= __put_user(0x91d02010, &sf->insns[1]); if (err) goto sigsegv; return err; /* Flush instruction space. */ flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); } return 0; sigill_and_return: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signo, current); return -EFAULT; } static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset, siginfo_t *info) static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs, sigset_t *oldset) { struct rt_signal_frame __user *sf; int sigframe_size, wsaved; Loading @@ -334,9 +323,11 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, if (wsaved) sigframe_size += sizeof(__siginfo_rwin_t); sf = (struct rt_signal_frame __user *) get_sigframe(&ka->sa, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) goto sigill; get_sigframe(ksig, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) { do_exit(SIGILL); return -EINVAL; } tail = sf + 1; err = __put_user(regs->pc, &sf->regs.pc); Loading Loading @@ -380,21 +371,21 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); } err |= copy_siginfo_to_user(&sf->info, info); err |= copy_siginfo_to_user(&sf->info, &ksig->info); if (err) goto sigsegv; return err; regs->u_regs[UREG_FP] = (unsigned long) sf; regs->u_regs[UREG_I0] = signo; regs->u_regs[UREG_I0] = ksig->sig; regs->u_regs[UREG_I1] = (unsigned long) &sf->info; regs->u_regs[UREG_I2] = (unsigned long) &sf->regs; regs->pc = (unsigned long) ka->sa.sa_handler; regs->pc = (unsigned long) ksig->ka.sa.sa_handler; regs->npc = (regs->pc + 4); if (ka->ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; if (ksig->ka.ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; else { regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2); Loading @@ -404,38 +395,25 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, /* t 0x10 */ err |= __put_user(0x91d02010, &sf->insns[1]); if (err) goto sigsegv; return err; /* Flush instruction space. */ flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); } return 0; sigill: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signo, current); return -EFAULT; } static inline void handle_signal(unsigned long signr, 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; if (ka->sa.sa_flags & SA_SIGINFO) err = setup_rt_frame(ka, regs, signr, oldset, info); if (ksig->ka.sa.sa_flags & SA_SIGINFO) err = setup_rt_frame(ksig, regs, oldset); else err = setup_frame(ka, regs, signr, oldset); if (err) return; signal_delivered(signr, info, ka, regs, 0); err = setup_frame(ksig, regs, oldset); signal_setup_done(err, ksig, 0); } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, Loading Loading @@ -465,10 +443,9 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, */ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) { struct k_sigaction ka; struct ksignal ksig; int restart_syscall; siginfo_t info; int signr; bool has_handler; /* It's a lot of work and synchronization to add a new ptrace * register for GDB to save and restore in order to get Loading @@ -491,7 +468,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) regs->u_regs[UREG_G6] = orig_i0; signr = get_signal_to_deliver(&info, &ka, regs, NULL); has_handler = get_signal(&ksig); /* If the debugger messes with the program counter, it clears * the software "in syscall" bit, directing us to not perform Loading @@ -503,36 +480,31 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) orig_i0 = regs->u_regs[UREG_G6]; } if (signr > 0) { if (has_handler) { if (restart_syscall) syscall_restart(orig_i0, regs, &ka.sa); handle_signal(signr, &ka, &info, regs); return; } if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { syscall_restart(orig_i0, regs, &ksig.ka.sa); handle_signal(&ksig, regs); } else { if (restart_syscall) { switch (regs->u_regs[UREG_I0]) { case ERESTARTNOHAND: case ERESTARTSYS: case ERESTARTNOINTR: /* replay the system call when we are done */ regs->u_regs[UREG_I0] = orig_i0; regs->pc -= 4; regs->npc -= 4; pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { case ERESTART_RESTARTBLOCK: regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->pc -= 4; regs->npc -= 4; pt_regs_clear_syscall(regs); } /* if there's no signal to deliver, we just put the saved sigmask * back */ } restore_saved_sigmask(); } } void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) Loading arch/sparc/kernel/signal_64.c +43 −75 Original line number Diff line number Diff line Loading @@ -308,7 +308,7 @@ static int invalid_frame_pointer(void __user *fp) return 0; } static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize) { unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; Loading @@ -320,12 +320,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs * return (void __user *) -1L; /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } sp -= framesize; sp = sigsp(sp, ksig) - framesize; /* Always align the stack frame. This handles two cases. First, * sigaltstack need not be mindful of platform specific stack Loading @@ -339,8 +334,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs * } static inline int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset, siginfo_t *info) setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) { struct rt_signal_frame __user *sf; int wsaved, err, sf_size; Loading @@ -358,10 +352,12 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, if (wsaved) sf_size += sizeof(__siginfo_rwin_t); sf = (struct rt_signal_frame __user *) get_sigframe(ka, regs, sf_size); get_sigframe(ksig, regs, sf_size); if (invalid_frame_pointer (sf)) goto sigill; if (invalid_frame_pointer (sf)) { do_exit(SIGILL); /* won't return, actually */ return -EINVAL; } tail = (sf + 1); Loading Loading @@ -389,7 +385,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, /* Setup sigaltstack */ err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]); err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t)); err |= copy_to_user(&sf->mask, sigmask_to_save(), sizeof(sigset_t)); if (!wsaved) { err |= copy_in_user((u64 __user *)sf, Loading @@ -402,18 +398,18 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, rp = ¤t_thread_info()->reg_window[wsaved - 1]; err |= copy_to_user(sf, rp, sizeof(struct reg_window)); } if (info) err |= copy_siginfo_to_user(&sf->info, info); if (ksig->ka.sa.sa_flags & SA_SIGINFO) err |= copy_siginfo_to_user(&sf->info, &ksig->info); else { err |= __put_user(signo, &sf->info.si_signo); err |= __put_user(ksig->sig, &sf->info.si_signo); err |= __put_user(SI_NOINFO, &sf->info.si_code); } if (err) goto sigsegv; return err; /* 3. signal handler back-trampoline and parameters */ regs->u_regs[UREG_FP] = ((unsigned long) sf) - STACK_BIAS; regs->u_regs[UREG_I0] = signo; regs->u_regs[UREG_I0] = ksig->sig; regs->u_regs[UREG_I1] = (unsigned long) &sf->info; /* The sigcontext is passed in this way because of how it Loading @@ -423,37 +419,15 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, regs->u_regs[UREG_I2] = (unsigned long) &sf->info; /* 5. signal handler */ regs->tpc = (unsigned long) ka->sa.sa_handler; regs->tpc = (unsigned long) ksig->ka.sa.sa_handler; regs->tnpc = (regs->tpc + 4); if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } /* 4. return to kernel instructions */ regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; return 0; sigill: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signo, current); return -EFAULT; } static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { int err; err = setup_rt_frame(ka, regs, signr, oldset, (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); if (err) return; signal_delivered(signr, info, ka, regs, 0); } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, Loading Loading @@ -483,11 +457,9 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, */ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) { struct k_sigaction ka; struct ksignal ksig; int restart_syscall; sigset_t *oldset = sigmask_to_save(); siginfo_t info; int signr; bool has_handler; /* It's a lot of work and synchronization to add a new ptrace * register for GDB to save and restore in order to get Loading @@ -513,13 +485,13 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { extern void do_signal32(sigset_t *, struct pt_regs *); do_signal32(oldset, regs); extern void do_signal32(struct pt_regs *); do_signal32(regs); return; } #endif signr = get_signal_to_deliver(&info, &ka, regs, NULL); has_handler = get_signal(&ksig); restart_syscall = 0; if (pt_regs_is_syscall(regs) && Loading @@ -528,35 +500,31 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) orig_i0 = regs->u_regs[UREG_G6]; } if (signr > 0) { if (has_handler) { if (restart_syscall) syscall_restart(orig_i0, regs, &ka.sa); handle_signal(signr, &ka, &info, oldset, regs); return; } if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { syscall_restart(orig_i0, regs, &ksig.ka.sa); signal_setup_done(setup_rt_frame(&ksig, regs), &ksig, 0); } else { if (restart_syscall) { switch (regs->u_regs[UREG_I0]) { case ERESTARTNOHAND: case ERESTARTSYS: case ERESTARTNOINTR: /* replay the system call when we are done */ regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { case ERESTART_RESTARTBLOCK: regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } /* If there's no signal to deliver, we just put the saved sigmask * back */ } restore_saved_sigmask(); } } void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) { Loading Loading
arch/sparc/kernel/signal32.c +62 −92 Original line number Diff line number Diff line Loading @@ -323,7 +323,7 @@ static int invalid_frame_pointer(void __user *fp, int fplen) return 0; } static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize) static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize) { unsigned long sp; Loading @@ -338,12 +338,7 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns return (void __user *) -1L; /* This is the X/Open sanctioned signal stack switching. */ if (sa->sa_flags & SA_ONSTACK) { if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } sp -= framesize; sp = sigsp(sp, ksig) - framesize; /* Always align the stack frame. This handles two cases. First, * sigaltstack need not be mindful of platform specific stack Loading Loading @@ -414,8 +409,8 @@ out_irqs_on: } static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset) static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs, sigset_t *oldset) { struct signal_frame32 __user *sf; int i, err, wsaved; Loading @@ -437,10 +432,12 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, sigframe_size += sizeof(__siginfo_rwin_t); sf = (struct signal_frame32 __user *) get_sigframe(&ka->sa, regs, sigframe_size); get_sigframe(ksig, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) goto sigill; if (invalid_frame_pointer(sf, sigframe_size)) { do_exit(SIGILL); return -EINVAL; } tail = (sf + 1); Loading Loading @@ -514,16 +511,16 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, err |= __put_user(rp->ins[7], &sf->ss.callers_pc); } if (err) goto sigsegv; return err; /* 3. signal handler back-trampoline and parameters */ regs->u_regs[UREG_FP] = (unsigned long) sf; regs->u_regs[UREG_I0] = signo; regs->u_regs[UREG_I0] = ksig->sig; regs->u_regs[UREG_I1] = (unsigned long) &sf->info; regs->u_regs[UREG_I2] = (unsigned long) &sf->info; /* 4. signal handler */ regs->tpc = (unsigned long) ka->sa.sa_handler; regs->tpc = (unsigned long) ksig->ka.sa.sa_handler; regs->tnpc = (regs->tpc + 4); if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; Loading @@ -531,8 +528,8 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, } /* 5. return to kernel instructions */ if (ka->ka_restorer) { regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; if (ksig->ka.ka_restorer) { regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; } else { unsigned long address = ((unsigned long)&(sf->insns[0])); Loading @@ -541,23 +538,14 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, err = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/ err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/ if (err) goto sigsegv; return err; flush_signal_insns(address); } return 0; sigill: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signo, current); return -EFAULT; } static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, unsigned long signr, sigset_t *oldset, siginfo_t *info) static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs, sigset_t *oldset) { struct rt_signal_frame32 __user *sf; int i, err, wsaved; Loading @@ -579,10 +567,12 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, sigframe_size += sizeof(__siginfo_rwin_t); sf = (struct rt_signal_frame32 __user *) get_sigframe(&ka->sa, regs, sigframe_size); get_sigframe(ksig, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) goto sigill; if (invalid_frame_pointer(sf, sigframe_size)) { do_exit(SIGILL); return -EINVAL; } tail = (sf + 1); Loading Loading @@ -627,7 +617,7 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, } /* Update the siginfo structure. */ err |= copy_siginfo_to_user32(&sf->info, info); err |= copy_siginfo_to_user32(&sf->info, &ksig->info); /* Setup sigaltstack */ err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]); Loading Loading @@ -660,16 +650,16 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, err |= __put_user(rp->ins[7], &sf->ss.callers_pc); } if (err) goto sigsegv; return err; /* 3. signal handler back-trampoline and parameters */ regs->u_regs[UREG_FP] = (unsigned long) sf; regs->u_regs[UREG_I0] = signr; regs->u_regs[UREG_I0] = ksig->sig; regs->u_regs[UREG_I1] = (unsigned long) &sf->info; regs->u_regs[UREG_I2] = (unsigned long) &sf->regs; /* 4. signal handler */ regs->tpc = (unsigned long) ka->sa.sa_handler; regs->tpc = (unsigned long) ksig->ka.sa.sa_handler; regs->tnpc = (regs->tpc + 4); if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; Loading @@ -677,8 +667,8 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, } /* 5. return to kernel instructions */ if (ka->ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; if (ksig->ka.ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; else { unsigned long address = ((unsigned long)&(sf->insns[0])); Loading @@ -690,36 +680,25 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, /* t 0x10 */ err |= __put_user(0x91d02010, &sf->insns[1]); if (err) goto sigsegv; return err; flush_signal_insns(address); } return 0; sigill: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signr, current); return -EFAULT; } static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) static inline void handle_signal32(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int err; if (ka->sa.sa_flags & SA_SIGINFO) err = setup_rt_frame32(ka, regs, signr, oldset, info); if (ksig->ka.sa.sa_flags & SA_SIGINFO) err = setup_rt_frame32(ksig, regs, oldset); else err = setup_frame32(ka, regs, signr, oldset); if (err) return; err = setup_frame32(ksig, regs, oldset); signal_delivered(signr, info, ka, regs, 0); signal_setup_done(err, ksig, 0); } static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, Loading Loading @@ -749,51 +728,42 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs */ void do_signal32(sigset_t *oldset, struct pt_regs * regs) { struct k_sigaction ka; unsigned long orig_i0; int restart_syscall; siginfo_t info; int signr; struct ksignal ksig; unsigned long orig_i0 = 0; int restart_syscall = 0; bool has_handler = get_signal(&ksig); signr = get_signal_to_deliver(&info, &ka, regs, NULL); restart_syscall = 0; orig_i0 = 0; if (pt_regs_is_syscall(regs) && (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { restart_syscall = 1; orig_i0 = regs->u_regs[UREG_G6]; } if (signr > 0) { if (has_handler) { if (restart_syscall) syscall_restart32(orig_i0, regs, &ka.sa); handle_signal32(signr, &ka, &info, oldset, regs); return; } if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { syscall_restart32(orig_i0, regs, &ksig.ka.sa); handle_signal32(&ksig, regs); } else { if (restart_syscall) { switch (regs->u_regs[UREG_I0]) { case ERESTARTNOHAND: case ERESTARTSYS: case ERESTARTNOINTR: /* replay the system call when we are done */ regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { case ERESTART_RESTARTBLOCK: regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } /* If there's no signal to deliver, we just put the saved sigmask * back */ } restore_saved_sigmask(); } } struct sigstack32 { u32 the_stack; Loading
arch/sparc/kernel/signal_32.c +59 −87 Original line number Diff line number Diff line Loading @@ -186,7 +186,7 @@ static inline int invalid_frame_pointer(void __user *fp, int fplen) return 0; } static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize) static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize) { unsigned long sp = regs->u_regs[UREG_FP]; Loading @@ -198,12 +198,7 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re return (void __user *) -1L; /* This is the X/Open sanctioned signal stack switching. */ if (sa->sa_flags & SA_ONSTACK) { if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } sp -= framesize; sp = sigsp(sp, ksig) - framesize; /* Always align the stack frame. This handles two cases. First, * sigaltstack need not be mindful of platform specific stack Loading @@ -216,8 +211,8 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re return (void __user *) sp; } static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset) static int setup_frame(struct ksignal *ksig, struct pt_regs *regs, sigset_t *oldset) { struct signal_frame __user *sf; int sigframe_size, err, wsaved; Loading @@ -235,10 +230,12 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, sigframe_size += sizeof(__siginfo_rwin_t); sf = (struct signal_frame __user *) get_sigframe(&ka->sa, regs, sigframe_size); get_sigframe(ksig, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) goto sigill_and_return; if (invalid_frame_pointer(sf, sigframe_size)) { do_exit(SIGILL); return -EINVAL; } tail = sf + 1; Loading Loading @@ -277,21 +274,21 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); } if (err) goto sigsegv; return err; /* 3. signal handler back-trampoline and parameters */ regs->u_regs[UREG_FP] = (unsigned long) sf; regs->u_regs[UREG_I0] = signo; regs->u_regs[UREG_I0] = ksig->sig; regs->u_regs[UREG_I1] = (unsigned long) &sf->info; regs->u_regs[UREG_I2] = (unsigned long) &sf->info; /* 4. signal handler */ regs->pc = (unsigned long) ka->sa.sa_handler; regs->pc = (unsigned long) ksig->ka.sa.sa_handler; regs->npc = (regs->pc + 4); /* 5. return to kernel instructions */ if (ka->ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; if (ksig->ka.ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; else { regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2); Loading @@ -301,24 +298,16 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, /* t 0x10 */ err |= __put_user(0x91d02010, &sf->insns[1]); if (err) goto sigsegv; return err; /* Flush instruction space. */ flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); } return 0; sigill_and_return: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signo, current); return -EFAULT; } static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset, siginfo_t *info) static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs, sigset_t *oldset) { struct rt_signal_frame __user *sf; int sigframe_size, wsaved; Loading @@ -334,9 +323,11 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, if (wsaved) sigframe_size += sizeof(__siginfo_rwin_t); sf = (struct rt_signal_frame __user *) get_sigframe(&ka->sa, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) goto sigill; get_sigframe(ksig, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) { do_exit(SIGILL); return -EINVAL; } tail = sf + 1; err = __put_user(regs->pc, &sf->regs.pc); Loading Loading @@ -380,21 +371,21 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); } err |= copy_siginfo_to_user(&sf->info, info); err |= copy_siginfo_to_user(&sf->info, &ksig->info); if (err) goto sigsegv; return err; regs->u_regs[UREG_FP] = (unsigned long) sf; regs->u_regs[UREG_I0] = signo; regs->u_regs[UREG_I0] = ksig->sig; regs->u_regs[UREG_I1] = (unsigned long) &sf->info; regs->u_regs[UREG_I2] = (unsigned long) &sf->regs; regs->pc = (unsigned long) ka->sa.sa_handler; regs->pc = (unsigned long) ksig->ka.sa.sa_handler; regs->npc = (regs->pc + 4); if (ka->ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; if (ksig->ka.ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; else { regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2); Loading @@ -404,38 +395,25 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, /* t 0x10 */ err |= __put_user(0x91d02010, &sf->insns[1]); if (err) goto sigsegv; return err; /* Flush instruction space. */ flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); } return 0; sigill: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signo, current); return -EFAULT; } static inline void handle_signal(unsigned long signr, 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; if (ka->sa.sa_flags & SA_SIGINFO) err = setup_rt_frame(ka, regs, signr, oldset, info); if (ksig->ka.sa.sa_flags & SA_SIGINFO) err = setup_rt_frame(ksig, regs, oldset); else err = setup_frame(ka, regs, signr, oldset); if (err) return; signal_delivered(signr, info, ka, regs, 0); err = setup_frame(ksig, regs, oldset); signal_setup_done(err, ksig, 0); } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, Loading Loading @@ -465,10 +443,9 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, */ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) { struct k_sigaction ka; struct ksignal ksig; int restart_syscall; siginfo_t info; int signr; bool has_handler; /* It's a lot of work and synchronization to add a new ptrace * register for GDB to save and restore in order to get Loading @@ -491,7 +468,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) regs->u_regs[UREG_G6] = orig_i0; signr = get_signal_to_deliver(&info, &ka, regs, NULL); has_handler = get_signal(&ksig); /* If the debugger messes with the program counter, it clears * the software "in syscall" bit, directing us to not perform Loading @@ -503,36 +480,31 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) orig_i0 = regs->u_regs[UREG_G6]; } if (signr > 0) { if (has_handler) { if (restart_syscall) syscall_restart(orig_i0, regs, &ka.sa); handle_signal(signr, &ka, &info, regs); return; } if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { syscall_restart(orig_i0, regs, &ksig.ka.sa); handle_signal(&ksig, regs); } else { if (restart_syscall) { switch (regs->u_regs[UREG_I0]) { case ERESTARTNOHAND: case ERESTARTSYS: case ERESTARTNOINTR: /* replay the system call when we are done */ regs->u_regs[UREG_I0] = orig_i0; regs->pc -= 4; regs->npc -= 4; pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { case ERESTART_RESTARTBLOCK: regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->pc -= 4; regs->npc -= 4; pt_regs_clear_syscall(regs); } /* if there's no signal to deliver, we just put the saved sigmask * back */ } restore_saved_sigmask(); } } void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) Loading
arch/sparc/kernel/signal_64.c +43 −75 Original line number Diff line number Diff line Loading @@ -308,7 +308,7 @@ static int invalid_frame_pointer(void __user *fp) return 0; } static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize) { unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; Loading @@ -320,12 +320,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs * return (void __user *) -1L; /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { if (sas_ss_flags(sp) == 0) sp = current->sas_ss_sp + current->sas_ss_size; } sp -= framesize; sp = sigsp(sp, ksig) - framesize; /* Always align the stack frame. This handles two cases. First, * sigaltstack need not be mindful of platform specific stack Loading @@ -339,8 +334,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs * } static inline int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset, siginfo_t *info) setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) { struct rt_signal_frame __user *sf; int wsaved, err, sf_size; Loading @@ -358,10 +352,12 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, if (wsaved) sf_size += sizeof(__siginfo_rwin_t); sf = (struct rt_signal_frame __user *) get_sigframe(ka, regs, sf_size); get_sigframe(ksig, regs, sf_size); if (invalid_frame_pointer (sf)) goto sigill; if (invalid_frame_pointer (sf)) { do_exit(SIGILL); /* won't return, actually */ return -EINVAL; } tail = (sf + 1); Loading Loading @@ -389,7 +385,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, /* Setup sigaltstack */ err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]); err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t)); err |= copy_to_user(&sf->mask, sigmask_to_save(), sizeof(sigset_t)); if (!wsaved) { err |= copy_in_user((u64 __user *)sf, Loading @@ -402,18 +398,18 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, rp = ¤t_thread_info()->reg_window[wsaved - 1]; err |= copy_to_user(sf, rp, sizeof(struct reg_window)); } if (info) err |= copy_siginfo_to_user(&sf->info, info); if (ksig->ka.sa.sa_flags & SA_SIGINFO) err |= copy_siginfo_to_user(&sf->info, &ksig->info); else { err |= __put_user(signo, &sf->info.si_signo); err |= __put_user(ksig->sig, &sf->info.si_signo); err |= __put_user(SI_NOINFO, &sf->info.si_code); } if (err) goto sigsegv; return err; /* 3. signal handler back-trampoline and parameters */ regs->u_regs[UREG_FP] = ((unsigned long) sf) - STACK_BIAS; regs->u_regs[UREG_I0] = signo; regs->u_regs[UREG_I0] = ksig->sig; regs->u_regs[UREG_I1] = (unsigned long) &sf->info; /* The sigcontext is passed in this way because of how it Loading @@ -423,37 +419,15 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, regs->u_regs[UREG_I2] = (unsigned long) &sf->info; /* 5. signal handler */ regs->tpc = (unsigned long) ka->sa.sa_handler; regs->tpc = (unsigned long) ksig->ka.sa.sa_handler; regs->tnpc = (regs->tpc + 4); if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } /* 4. return to kernel instructions */ regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer; return 0; sigill: do_exit(SIGILL); return -EINVAL; sigsegv: force_sigsegv(signo, current); return -EFAULT; } static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { int err; err = setup_rt_frame(ka, regs, signr, oldset, (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); if (err) return; signal_delivered(signr, info, ka, regs, 0); } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, Loading Loading @@ -483,11 +457,9 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, */ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) { struct k_sigaction ka; struct ksignal ksig; int restart_syscall; sigset_t *oldset = sigmask_to_save(); siginfo_t info; int signr; bool has_handler; /* It's a lot of work and synchronization to add a new ptrace * register for GDB to save and restore in order to get Loading @@ -513,13 +485,13 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { extern void do_signal32(sigset_t *, struct pt_regs *); do_signal32(oldset, regs); extern void do_signal32(struct pt_regs *); do_signal32(regs); return; } #endif signr = get_signal_to_deliver(&info, &ka, regs, NULL); has_handler = get_signal(&ksig); restart_syscall = 0; if (pt_regs_is_syscall(regs) && Loading @@ -528,35 +500,31 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) orig_i0 = regs->u_regs[UREG_G6]; } if (signr > 0) { if (has_handler) { if (restart_syscall) syscall_restart(orig_i0, regs, &ka.sa); handle_signal(signr, &ka, &info, oldset, regs); return; } if (restart_syscall && (regs->u_regs[UREG_I0] == ERESTARTNOHAND || regs->u_regs[UREG_I0] == ERESTARTSYS || regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { syscall_restart(orig_i0, regs, &ksig.ka.sa); signal_setup_done(setup_rt_frame(&ksig, regs), &ksig, 0); } else { if (restart_syscall) { switch (regs->u_regs[UREG_I0]) { case ERESTARTNOHAND: case ERESTARTSYS: case ERESTARTNOINTR: /* replay the system call when we are done */ regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { case ERESTART_RESTARTBLOCK: regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; pt_regs_clear_syscall(regs); } /* If there's no signal to deliver, we just put the saved sigmask * back */ } restore_saved_sigmask(); } } void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) { Loading