diff options
Diffstat (limited to 'arch/sh/kernel/signal_32.c')
| -rw-r--r-- | arch/sh/kernel/signal_32.c | 79 | 
1 files changed, 32 insertions, 47 deletions
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index 594cd371aa28..2f002b24fb92 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c @@ -262,17 +262,17 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)  extern void __kernel_sigreturn(void);  extern void __kernel_rt_sigreturn(void); -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 err = 0; +	int err = 0, sig = ksig->sig;  	int signal; -	frame = get_sigframe(ka, regs->regs[15], sizeof(*frame)); +	frame = get_sigframe(&ksig->ka, regs->regs[15], sizeof(*frame));  	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) -		goto give_sigsegv; +		return -EFAULT;  	signal = current_thread_info()->exec_domain  		&& current_thread_info()->exec_domain->signal_invmap @@ -288,8 +288,8 @@ static int setup_frame(int sig, struct k_sigaction *ka,  	/* Set up to return from userspace.  If provided, use a stub  	   already in userspace.  */ -	if (ka->sa.sa_flags & SA_RESTORER) { -		regs->pr = (unsigned long) ka->sa.sa_restorer; +	if (ksig->ka.sa.sa_flags & SA_RESTORER) { +		regs->pr = (unsigned long) ksig->ka.sa.sa_restorer;  #ifdef CONFIG_VSYSCALL  	} else if (likely(current->mm->context.vdso)) {  		regs->pr = VDSO_SYM(&__kernel_sigreturn); @@ -309,7 +309,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,  	}  	if (err) -		goto give_sigsegv; +		return -EFAULT;  	/* Set up registers for signal handler */  	regs->regs[15] = (unsigned long) frame; @@ -319,15 +319,15 @@ static int setup_frame(int sig, struct k_sigaction *ka,  	if (current->personality & FDPIC_FUNCPTRS) {  		struct fdpic_func_descriptor __user *funcptr = -			(struct fdpic_func_descriptor __user *)ka->sa.sa_handler; +			(struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler;  		err |= __get_user(regs->pc, &funcptr->text);  		err |= __get_user(regs->regs[12], &funcptr->GOT);  	} else -		regs->pc = (unsigned long)ka->sa.sa_handler; +		regs->pc = (unsigned long)ksig->ka.sa.sa_handler;  	if (err) -		goto give_sigsegv; +		return -EFAULT;  	set_fs(USER_DS); @@ -335,23 +335,19 @@ static int setup_frame(int sig, struct k_sigaction *ka,  		 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);  	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) +static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, +			  struct pt_regs *regs)  {  	struct rt_sigframe __user *frame; -	int err = 0; +	int err = 0, sig = ksig->sig;  	int signal; -	frame = get_sigframe(ka, regs->regs[15], sizeof(*frame)); +	frame = get_sigframe(&ksig->ka, regs->regs[15], sizeof(*frame));  	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) -		goto give_sigsegv; +		return -EFAULT;  	signal = current_thread_info()->exec_domain  		&& current_thread_info()->exec_domain->signal_invmap @@ -359,7 +355,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,  		? current_thread_info()->exec_domain->signal_invmap[sig]  		: sig; -	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); @@ -371,8 +367,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,  	/* Set up to return from userspace.  If provided, use a stub  	   already in userspace.  */ -	if (ka->sa.sa_flags & SA_RESTORER) { -		regs->pr = (unsigned long) ka->sa.sa_restorer; +	if (ksig->ka.sa.sa_flags & SA_RESTORER) { +		regs->pr = (unsigned long) ksig->ka.sa.sa_restorer;  #ifdef CONFIG_VSYSCALL  	} else if (likely(current->mm->context.vdso)) {  		regs->pr = VDSO_SYM(&__kernel_rt_sigreturn); @@ -392,7 +388,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,  	}  	if (err) -		goto give_sigsegv; +		return -EFAULT;  	/* Set up registers for signal handler */  	regs->regs[15] = (unsigned long) frame; @@ -402,15 +398,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,  	if (current->personality & FDPIC_FUNCPTRS) {  		struct fdpic_func_descriptor __user *funcptr = -			(struct fdpic_func_descriptor __user *)ka->sa.sa_handler; +			(struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler;  		err |= __get_user(regs->pc, &funcptr->text);  		err |= __get_user(regs->regs[12], &funcptr->GOT);  	} else -		regs->pc = (unsigned long)ka->sa.sa_handler; +		regs->pc = (unsigned long)ksig->ka.sa.sa_handler;  	if (err) -		goto give_sigsegv; +		return -EFAULT;  	set_fs(USER_DS); @@ -418,10 +414,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,  		 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);  	return 0; - -give_sigsegv: -	force_sigsegv(sig, current); -	return -EFAULT;  }  static inline void @@ -455,22 +447,18 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs,   * OK, we're invoking a handler   */  static void -handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, -	      struct pt_regs *regs, unsigned int save_r0) +handle_signal(struct ksignal *ksig, struct pt_regs *regs, unsigned int save_r0)  {  	sigset_t *oldset = sigmask_to_save();  	int ret;  	/* 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) -		return; -	signal_delivered(sig, info, ka, regs, -			test_thread_flag(TIF_SINGLESTEP)); +	signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));  }  /* @@ -484,9 +472,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,   */  static void do_signal(struct pt_regs *regs, unsigned int save_r0)  { -	siginfo_t info; -	int signr; -	struct k_sigaction ka; +	struct ksignal ksig;  	/*  	 * We want the common case to go fast, which @@ -497,12 +483,11 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)  	if (!user_mode(regs))  		return; -	signr = get_signal_to_deliver(&info, &ka, regs, NULL); -	if (signr > 0) { -		handle_syscall_restart(save_r0, regs, &ka.sa); +	if (get_signal(&ksig)) { +		handle_syscall_restart(save_r0, regs, &ksig.ka.sa);  		/* Whee!  Actually deliver the signal.  */ -		handle_signal(signr, &ka, &info, regs, save_r0); +		handle_signal(&ksig, regs, save_r0);  		return;  	}  |