diff options
Diffstat (limited to 'arch/s390/kernel/signal.c')
| -rw-r--r-- | arch/s390/kernel/signal.c | 20 | 
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 7f6f9f35454..a8ba840294f 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -302,9 +302,13 @@ static int setup_frame(int sig, struct k_sigaction *ka,  	/* We forgot to include these in the sigcontext.  	   To avoid breaking binary compatibility, they are passed as args. */ -	regs->gprs[4] = current->thread.trap_no; -	regs->gprs[5] = current->thread.prot_addr; -	regs->gprs[6] = task_thread_info(current)->last_break; +	if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || +	    sig == SIGTRAP || sig == SIGFPE) { +		/* set extra registers only for synchronous signals */ +		regs->gprs[4] = regs->int_code & 127; +		regs->gprs[5] = regs->int_parm_long; +		regs->gprs[6] = task_thread_info(current)->last_break; +	}  	/* Place signal number on stack to allow backtrace from handler.  */  	if (__put_user(regs->gprs[2], (int __user *) &frame->signo)) @@ -434,13 +438,13 @@ void do_signal(struct pt_regs *regs)  	 * call information.  	 */  	current_thread_info()->system_call = -		test_thread_flag(TIF_SYSCALL) ? regs->svc_code : 0; +		test_thread_flag(TIF_SYSCALL) ? regs->int_code : 0;  	signr = get_signal_to_deliver(&info, &ka, regs, NULL);  	if (signr > 0) {  		/* Whee!  Actually deliver the signal.  */  		if (current_thread_info()->system_call) { -			regs->svc_code = current_thread_info()->system_call; +			regs->int_code = current_thread_info()->system_call;  			/* Check for system call restarting. */  			switch (regs->gprs[2]) {  			case -ERESTART_RESTARTBLOCK: @@ -457,7 +461,7 @@ void do_signal(struct pt_regs *regs)  				regs->gprs[2] = regs->orig_gpr2;  				regs->psw.addr =  					__rewind_psw(regs->psw, -						     regs->svc_code >> 16); +						     regs->int_code >> 16);  				break;  			}  		} @@ -488,11 +492,11 @@ void do_signal(struct pt_regs *regs)  	/* No handlers present - check for system call restart */  	clear_thread_flag(TIF_SYSCALL);  	if (current_thread_info()->system_call) { -		regs->svc_code = current_thread_info()->system_call; +		regs->int_code = current_thread_info()->system_call;  		switch (regs->gprs[2]) {  		case -ERESTART_RESTARTBLOCK:  			/* Restart with sys_restart_syscall */ -			regs->svc_code = __NR_restart_syscall; +			regs->int_code = __NR_restart_syscall;  		/* fallthrough */  		case -ERESTARTNOHAND:  		case -ERESTARTSYS:  |