Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3532543imu; Mon, 7 Jan 2019 05:12:13 -0800 (PST) X-Google-Smtp-Source: ALg8bN5kdPvjl0h5ddhquKI7Y5iJ1OrsYGdmjO4pep69/5VGXDC6H2Q/QDDlCZcZMZNT9+7h6h6b X-Received: by 2002:a63:dd15:: with SMTP id t21mr10515641pgg.347.1546866733012; Mon, 07 Jan 2019 05:12:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546866732; cv=none; d=google.com; s=arc-20160816; b=rFZ7VMTkJHdHmJyASUztt5Zh/sfu0xeV3Z5r9fX9S/bHn42/k4m+3bKN0v8+IXa1bN YDrz9wRsbcAq6csJOl+yQG6iFpXhqjqro6OyDfMxPChX7dR1zYtVh7goMsGGec/p1joG Vzm0YAYfzpPt3acBbgIvPNMJb7FfvHX5j5XQKILwXO6FZLn+5xEr4cGHBRa8vXqhoONP hvBP+e7lxB/jrlybCJdOGeTHe7iuk9Gm7xdUETYxWxC24DeoeafNY7BwlcYDm4Nx/483 LUG76XOZXUatvA8BN2U3tAl305cG0fGpAToLs5JUYeC9QY7ugrcDKVnZzMwP0TB64efq 7o7w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=5p4rg7FCx92eBlmZI7tTqfjW3/9eMssr/mZ9pl67gOQ=; b=ko/4XKpOWWkTxQ8sZg/wLC+aspsNDXC5CdPDeIccUaSA7kLq0z+I7mKUNjwmS6hvc5 kYwpFO1Vem51yW/Jj77CABGOzMK+iePOvtbznkBtAOTtFP7SQpztYfiGpdcabtBgiQDf ZFstbCJ0Z9s6CWnaFP57DIG2B1df6p14+KaemndBrUBArTSplWDZtIHZDhtHROMG3Yqz zaPh8WowMrCpdVZ+HTlQ77Oia/g/HbXL1de6YTP5zUxCqRoAndsgtRMX4Ez0oJ5DiU84 A8PCAhn+bPTZmPXUCHybn3AO29SR+j+VXZRDSjPau2VLrAuNYF7zux2eOkPdqcDlDGNS hlCA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=2PqcbybT; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l123si2779359pfc.187.2019.01.07.05.11.57; Mon, 07 Jan 2019 05:12:12 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=2PqcbybT; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731719AbfAGNIs (ORCPT + 99 others); Mon, 7 Jan 2019 08:08:48 -0500 Received: from mail.kernel.org ([198.145.29.99]:55850 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731704AbfAGNIr (ORCPT ); Mon, 7 Jan 2019 08:08:47 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 0432B2089F; Mon, 7 Jan 2019 13:08:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1546866526; bh=AXIaqBBA8Bcfy3W4tMXQ/SqISYOUYOUv0cPxKk7lsHM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=2PqcbybTAiKakNIh+tByt4yvJitHVWcHabDR0zYmdlR/QMWGW/oYbUVd0eiAasl9z zkUwA11zwFENjTs7bnBu8pJPLJN2qx3WmnwVvfZzikLZA/iQWDqKD5TpQLAJ5LH6at nc8Dd0hzqvzyaCeMYAMMLoNKoiHaddm8Pm19l6W0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Breno Leitao , Michael Ellerman Subject: [PATCH 4.9 59/71] powerpc/tm: Set MSR[TS] just prior to recheckpoint Date: Mon, 7 Jan 2019 13:33:28 +0100 Message-Id: <20190107105336.092677480@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107105330.280153213@linuxfoundation.org> References: <20190107105330.280153213@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Breno Leitao commit e1c3743e1a20647c53b719dbf28b48f45d23f2cd upstream. On a signal handler return, the user could set a context with MSR[TS] bits set, and these bits would be copied to task regs->msr. At restore_tm_sigcontexts(), after current task regs->msr[TS] bits are set, several __get_user() are called and then a recheckpoint is executed. This is a problem since a page fault (in kernel space) could happen when calling __get_user(). If it happens, the process MSR[TS] bits were already set, but recheckpoint was not executed, and SPRs are still invalid. The page fault can cause the current process to be de-scheduled, with MSR[TS] active and without tm_recheckpoint() being called. More importantly, without TEXASR[FS] bit set also. Since TEXASR might not have the FS bit set, and when the process is scheduled back, it will try to reclaim, which will be aborted because of the CPU is not in the suspended state, and, then, recheckpoint. This recheckpoint will restore thread->texasr into TEXASR SPR, which might be zero, hitting a BUG_ON(). kernel BUG at /build/linux-sf3Co9/linux-4.9.30/arch/powerpc/kernel/tm.S:434! cpu 0xb: Vector: 700 (Program Check) at [c00000041f1576d0] pc: c000000000054550: restore_gprs+0xb0/0x180 lr: 0000000000000000 sp: c00000041f157950 msr: 8000000100021033 current = 0xc00000041f143000 paca = 0xc00000000fb86300 softe: 0 irq_happened: 0x01 pid = 1021, comm = kworker/11:1 kernel BUG at /build/linux-sf3Co9/linux-4.9.30/arch/powerpc/kernel/tm.S:434! Linux version 4.9.0-3-powerpc64le (debian-kernel@lists.debian.org) (gcc version 6.3.0 20170516 (Debian 6.3.0-18) ) #1 SMP Debian 4.9.30-2+deb9u2 (2017-06-26) enter ? for help [c00000041f157b30] c00000000001bc3c tm_recheckpoint.part.11+0x6c/0xa0 [c00000041f157b70] c00000000001d184 __switch_to+0x1e4/0x4c0 [c00000041f157bd0] c00000000082eeb8 __schedule+0x2f8/0x990 [c00000041f157cb0] c00000000082f598 schedule+0x48/0xc0 [c00000041f157ce0] c0000000000f0d28 worker_thread+0x148/0x610 [c00000041f157d80] c0000000000f96b0 kthread+0x120/0x140 [c00000041f157e30] c00000000000c0e0 ret_from_kernel_thread+0x5c/0x7c This patch simply delays the MSR[TS] set, so, if there is any page fault in the __get_user() section, it does not have regs->msr[TS] set, since the TM structures are still invalid, thus avoiding doing TM operations for in-kernel exceptions and possible process reschedule. With this patch, the MSR[TS] will only be set just before recheckpointing and setting TEXASR[FS] = 1, thus avoiding an interrupt with TM registers in invalid state. Other than that, if CONFIG_PREEMPT is set, there might be a preemption just after setting MSR[TS] and before tm_recheckpoint(), thus, this block must be atomic from a preemption perspective, thus, calling preempt_disable/enable() on this code. It is not possible to move tm_recheckpoint to happen earlier, because it is required to get the checkpointed registers from userspace, with __get_user(), thus, the only way to avoid this undesired behavior is delaying the MSR[TS] set. The 32-bits signal handler seems to be safe this current issue, but, it might be exposed to the preemption issue, thus, disabling preemption in this chunk of code. Changes from v2: * Run the critical section with preempt_disable. Fixes: 87b4e5393af7 ("powerpc/tm: Fix return of active 64bit signals") Cc: stable@vger.kernel.org (v3.9+) Signed-off-by: Breno Leitao Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/kernel/signal_32.c | 20 +++++++++++++++++- arch/powerpc/kernel/signal_64.c | 44 +++++++++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 15 deletions(-) --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -866,7 +866,23 @@ static long restore_tm_user_regs(struct /* If TM bits are set to the reserved value, it's an invalid context */ if (MSR_TM_RESV(msr_hi)) return 1; - /* Pull in the MSR TM bits from the user context */ + + /* + * Disabling preemption, since it is unsafe to be preempted + * with MSR[TS] set without recheckpointing. + */ + preempt_disable(); + + /* + * CAUTION: + * After regs->MSR[TS] being updated, make sure that get_user(), + * put_user() or similar functions are *not* called. These + * functions can generate page faults which will cause the process + * to be de-scheduled with MSR[TS] set but without calling + * tm_recheckpoint(). This can cause a bug. + * + * Pull in the MSR TM bits from the user context + */ regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr_hi & MSR_TS_MASK); /* Now, recheckpoint. This loads up all of the checkpointed (older) * registers, including FP and V[S]Rs. After recheckpointing, the @@ -891,6 +907,8 @@ static long restore_tm_user_regs(struct } #endif + preempt_enable(); + return 0; } #endif --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -452,20 +452,6 @@ static long restore_tm_sigcontexts(struc if (MSR_TM_RESV(msr)) return -EINVAL; - /* pull in MSR TS bits from user context */ - regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK); - - /* - * Ensure that TM is enabled in regs->msr before we leave the signal - * handler. It could be the case that (a) user disabled the TM bit - * through the manipulation of the MSR bits in uc_mcontext or (b) the - * TM bit was disabled because a sufficient number of context switches - * happened whilst in the signal handler and load_tm overflowed, - * disabling the TM bit. In either case we can end up with an illegal - * TM state leading to a TM Bad Thing when we return to userspace. - */ - regs->msr |= MSR_TM; - /* pull in MSR LE from user context */ regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE); @@ -557,6 +543,34 @@ static long restore_tm_sigcontexts(struc tm_enable(); /* Make sure the transaction is marked as failed */ tsk->thread.tm_texasr |= TEXASR_FS; + + /* + * Disabling preemption, since it is unsafe to be preempted + * with MSR[TS] set without recheckpointing. + */ + preempt_disable(); + + /* pull in MSR TS bits from user context */ + regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK); + + /* + * Ensure that TM is enabled in regs->msr before we leave the signal + * handler. It could be the case that (a) user disabled the TM bit + * through the manipulation of the MSR bits in uc_mcontext or (b) the + * TM bit was disabled because a sufficient number of context switches + * happened whilst in the signal handler and load_tm overflowed, + * disabling the TM bit. In either case we can end up with an illegal + * TM state leading to a TM Bad Thing when we return to userspace. + * + * CAUTION: + * After regs->MSR[TS] being updated, make sure that get_user(), + * put_user() or similar functions are *not* called. These + * functions can generate page faults which will cause the process + * to be de-scheduled with MSR[TS] set but without calling + * tm_recheckpoint(). This can cause a bug. + */ + regs->msr |= MSR_TM; + /* This loads the checkpointed FP/VEC state, if used */ tm_recheckpoint(&tsk->thread, msr); @@ -570,6 +584,8 @@ static long restore_tm_sigcontexts(struc regs->msr |= MSR_VEC; } + preempt_enable(); + return err; } #endif