From aa7e04b3808614980d474735cdb0bf35ac5cdf26 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Tue, 19 Nov 2013 12:26:09 +0100 Subject: [PATCH] s390/signal: always restore saved runtime instrumentation psw bit Commit "s390: fix handling of runtime instrumentation psw bit" (5ebf250dab) changed the behavior of setting the runtime instrumentation psw bit. This commit restores the original logic: 1. When returning from the signal handler, the runtime instrumentation psw bit is restored to its saved state. 2. If the runtime instrumentation psw bit is enabled during the signal handler, it is always turned off when leaving the signal handler. The saved state is restored as described in 1. That also implies that turning on runtime instrumentation in the signal handler is only effective while running in the signal context. Signed-off-by: Hendrik Brueckner --- arch/s390/kernel/compat_signal.c | 2 +- arch/s390/kernel/signal.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index 6e2442978409..95e7ba0fbb7e 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -194,7 +194,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) return -EINVAL; /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */ - regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | + regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) | (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 | (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_RI) << 32 | (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE); diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index fb535874a246..d8fd508ccd1e 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -94,7 +94,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) return -EINVAL; /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */ - regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | + regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) | (user_sregs.regs.psw.mask & (PSW_MASK_USER | PSW_MASK_RI)); /* Check for invalid user address space control. */ if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)