diff options
Diffstat (limited to 'arch/s390/kernel/signal.c')
| -rw-r--r-- | arch/s390/kernel/signal.c | 14 | 
1 files changed, 12 insertions, 2 deletions
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index c13a2a37ef0..d1259d87507 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -136,6 +136,10 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)  	/* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */  	regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |  		(user_sregs.regs.psw.mask & PSW_MASK_USER); +	/* Check for invalid user address space control. */ +	if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) +		regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | +			(regs->psw.mask & ~PSW_MASK_ASC);  	/* Check for invalid amode */  	if (regs->psw.mask & PSW_MASK_EA)  		regs->psw.mask |= PSW_MASK_BA; @@ -273,7 +277,10 @@ static int setup_frame(int sig, struct k_sigaction *ka,  	/* Set up registers for signal handler */  	regs->gprs[15] = (unsigned long) frame; -	regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA;	/* 64 bit amode */ +	/* Force default amode and default user address space control. */ +	regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | +		(psw_user_bits & PSW_MASK_ASC) | +		(regs->psw.mask & ~PSW_MASK_ASC);  	regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;  	regs->gprs[2] = map_signal(sig); @@ -346,7 +353,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,  	/* Set up registers for signal handler */  	regs->gprs[15] = (unsigned long) frame; -	regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA;	/* 64 bit amode */ +	/* Force default amode and default user address space control. */ +	regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | +		(psw_user_bits & PSW_MASK_ASC) | +		(regs->psw.mask & ~PSW_MASK_ASC);  	regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;  	regs->gprs[2] = map_signal(sig);  |