diff options
Diffstat (limited to 'arch/mips/kernel/signal.c')
| -rw-r--r-- | arch/mips/kernel/signal.c | 72 | 
1 files changed, 27 insertions, 45 deletions
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 9e60d117e41e..1d57605e4615 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -280,7 +280,7 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)  	return err;  } -void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, +void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,  			  size_t frame_size)  {  	unsigned long sp; @@ -295,9 +295,7 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,  	 */  	sp -= 32; -	/* This is the X/Open sanctioned signal stack switching.  */ -	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) -		sp = current->sas_ss_sp + current->sas_ss_size; +	sp = sigsp(sp, ksig);  	return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));  } @@ -428,20 +426,20 @@ badframe:  }  #ifdef CONFIG_TRAD_SIGNALS -static int setup_frame(void *sig_return, struct k_sigaction *ka, -		       struct pt_regs *regs, int signr, sigset_t *set) +static int setup_frame(void *sig_return, struct ksignal *ksig, +		       struct pt_regs *regs, sigset_t *set)  {  	struct sigframe __user *frame;  	int err = 0; -	frame = get_sigframe(ka, regs, sizeof(*frame)); +	frame = get_sigframe(ksig, regs, sizeof(*frame));  	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) -		goto give_sigsegv; +		return -EFAULT;  	err |= setup_sigcontext(regs, &frame->sf_sc);  	err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));  	if (err) -		goto give_sigsegv; +		return -EFAULT;  	/*  	 * Arguments to signal handler: @@ -453,37 +451,32 @@ static int setup_frame(void *sig_return, struct k_sigaction *ka,  	 * $25 and c0_epc point to the signal handler, $29 points to the  	 * struct sigframe.  	 */ -	regs->regs[ 4] = signr; +	regs->regs[ 4] = ksig->sig;  	regs->regs[ 5] = 0;  	regs->regs[ 6] = (unsigned long) &frame->sf_sc;  	regs->regs[29] = (unsigned long) frame;  	regs->regs[31] = (unsigned long) sig_return; -	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; +	regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;  	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",  	       current->comm, current->pid,  	       frame, regs->cp0_epc, regs->regs[31]);  	return 0; - -give_sigsegv: -	force_sigsegv(signr, current); -	return -EFAULT;  }  #endif -static int setup_rt_frame(void *sig_return, struct k_sigaction *ka, -			  struct pt_regs *regs, int signr, sigset_t *set, -			  siginfo_t *info) +static int setup_rt_frame(void *sig_return, struct ksignal *ksig, +			  struct pt_regs *regs, sigset_t *set)  {  	struct rt_sigframe __user *frame;  	int err = 0; -	frame = get_sigframe(ka, regs, sizeof(*frame)); +	frame = get_sigframe(ksig, regs, sizeof(*frame));  	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) -		goto give_sigsegv; +		return -EFAULT;  	/* Create siginfo.  */ -	err |= copy_siginfo_to_user(&frame->rs_info, info); +	err |= copy_siginfo_to_user(&frame->rs_info, &ksig->info);  	/* Create the ucontext.	 */  	err |= __put_user(0, &frame->rs_uc.uc_flags); @@ -493,7 +486,7 @@ static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,  	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));  	if (err) -		goto give_sigsegv; +		return -EFAULT;  	/*  	 * Arguments to signal handler: @@ -505,22 +498,18 @@ static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,  	 * $25 and c0_epc point to the signal handler, $29 points to  	 * the struct rt_sigframe.  	 */ -	regs->regs[ 4] = signr; +	regs->regs[ 4] = ksig->sig;  	regs->regs[ 5] = (unsigned long) &frame->rs_info;  	regs->regs[ 6] = (unsigned long) &frame->rs_uc;  	regs->regs[29] = (unsigned long) frame;  	regs->regs[31] = (unsigned long) sig_return; -	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; +	regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;  	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",  	       current->comm, current->pid,  	       frame, regs->cp0_epc, regs->regs[31]);  	return 0; - -give_sigsegv: -	force_sigsegv(signr, current); -	return -EFAULT;  }  struct mips_abi mips_abi = { @@ -534,8 +523,7 @@ struct mips_abi mips_abi = {  	.restart	= __NR_restart_syscall  }; -static void handle_signal(unsigned long sig, siginfo_t *info, -	struct k_sigaction *ka, struct pt_regs *regs) +static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)  {  	sigset_t *oldset = sigmask_to_save();  	int ret; @@ -557,7 +545,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,  			regs->regs[2] = EINTR;  			break;  		case ERESTARTSYS: -			if (!(ka->sa.sa_flags & SA_RESTART)) { +			if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {  				regs->regs[2] = EINTR;  				break;  			} @@ -571,29 +559,23 @@ static void handle_signal(unsigned long sig, siginfo_t *info,  		regs->regs[0] = 0;		/* Don't deal with this again.	*/  	} -	if (sig_uses_siginfo(ka)) +	if (sig_uses_siginfo(&ksig->ka))  		ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset, -					  ka, regs, sig, oldset, info); +					  ksig, regs, oldset);  	else -		ret = abi->setup_frame(vdso + abi->signal_return_offset, -				       ka, regs, sig, oldset); - -	if (ret) -		return; +		ret = abi->setup_frame(vdso + abi->signal_return_offset, ksig, +				       regs, oldset); -	signal_delivered(sig, info, ka, regs, 0); +	signal_setup_done(ret, ksig, 0);  }  static void do_signal(struct pt_regs *regs)  { -	struct k_sigaction ka; -	siginfo_t info; -	int signr; +	struct ksignal ksig; -	signr = get_signal_to_deliver(&info, &ka, regs, NULL); -	if (signr > 0) { +	if (get_signal(&ksig)) {  		/* Whee!  Actually deliver the signal.	*/ -		handle_signal(signr, &info, &ka, regs); +		handle_signal(&ksig, regs);  		return;  	}  |