diff options
Diffstat (limited to 'arch/mn10300/kernel/signal.c')
| -rw-r--r-- | arch/mn10300/kernel/signal.c | 35 | 
1 files changed, 20 insertions, 15 deletions
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c index 717db14c2cc..d4de05ab786 100644 --- a/arch/mn10300/kernel/signal.c +++ b/arch/mn10300/kernel/signal.c @@ -65,10 +65,10 @@ asmlinkage long sys_sigaction(int sig,  		old_sigset_t mask;  		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||  		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) || -		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) +		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || +		    __get_user(new_ka.sa.sa_flags, &act->sa_flags) || +		    __get_user(mask, &act->sa_mask))  			return -EFAULT; -		__get_user(new_ka.sa.sa_flags, &act->sa_flags); -		__get_user(mask, &act->sa_mask);  		siginitset(&new_ka.sa.sa_mask, mask);  	} @@ -77,10 +77,10 @@ asmlinkage long sys_sigaction(int sig,  	if (!ret && oact) {  		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||  		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || -		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) +		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || +		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || +		    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))  			return -EFAULT; -		__put_user(old_ka.sa.sa_flags, &oact->sa_flags); -		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);  	}  	return ret; @@ -102,6 +102,9 @@ static int restore_sigcontext(struct pt_regs *regs,  {  	unsigned int err = 0; +	/* Always make any pending restarted system calls return -EINTR */ +	current_thread_info()->restart_block.fn = do_no_restart_syscall; +  	if (is_using_fpu(current))  		fpu_kill_state(current); @@ -330,8 +333,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,  	regs->d0 = sig;  	regs->d1 = (unsigned long) &frame->sc; -	set_fs(USER_DS); -  	/* the tracer may want to single-step inside the handler */  	if (test_thread_flag(TIF_SINGLESTEP))  		ptrace_notify(SIGTRAP); @@ -345,7 +346,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,  	return 0;  give_sigsegv: -	force_sig(SIGSEGV, current); +	force_sigsegv(sig, current);  	return -EFAULT;  } @@ -413,8 +414,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,  	regs->d0 = sig;  	regs->d1 = (long) &frame->info; -	set_fs(USER_DS); -  	/* the tracer may want to single-step inside the handler */  	if (test_thread_flag(TIF_SINGLESTEP))  		ptrace_notify(SIGTRAP); @@ -428,10 +427,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,  	return 0;  give_sigsegv: -	force_sig(SIGSEGV, current); +	force_sigsegv(sig, current);  	return -EFAULT;  } +static inline void stepback(struct pt_regs *regs) +{ +	regs->pc -= 2; +	regs->orig_d0 = -1; +} +  /*   * handle the actual delivery of a signal to userspace   */ @@ -459,7 +464,7 @@ static int handle_signal(int sig,  			/* fallthrough */  		case -ERESTARTNOINTR:  			regs->d0 = regs->orig_d0; -			regs->pc -= 2; +			stepback(regs);  		}  	} @@ -527,12 +532,12 @@ static void do_signal(struct pt_regs *regs)  		case -ERESTARTSYS:  		case -ERESTARTNOINTR:  			regs->d0 = regs->orig_d0; -			regs->pc -= 2; +			stepback(regs);  			break;  		case -ERESTART_RESTARTBLOCK:  			regs->d0 = __NR_restart_syscall; -			regs->pc -= 2; +			stepback(regs);  			break;  		}  	}  |