From patchwork Fri Nov 17 16:38:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Martin X-Patchwork-Id: 10063011 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9ED6D6023A for ; Fri, 17 Nov 2017 16:49:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 905D12AD35 for ; Fri, 17 Nov 2017 16:49:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 853BF2AD3E; Fri, 17 Nov 2017 16:49:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 17AD92AD35 for ; Fri, 17 Nov 2017 16:49:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=Hh8SYcZlidIDxIMmSwy1zZaEJ8t3puFY8NdHJOeRu/E=; b=FjPUQ9fhsqcw2vmT2K7gF6ndNo DsdiTDooil5tuHP1W+kn05SWhXE2Q2buxUnSOwtcOoWhm4pu6k7XV8O1R2Jv3gQIySislvPY66gLX Lqil/9AiabfvnIXwmuRtC3vPilT42Jb+xCDogGCTHqQYD+QRrchI+V0EKAImPDidSmSj+yv8NtK4r e6fn8557frcFYPmphpDYGv32JHhbSQODQGie9PAr7HqLXVUpehJBsYARTxkkpCB14mLivkD8UFoQu N9S1Oi6QLQY7pVyMqa9Tantt+KR77OeHxWpQjRt+zEOb8/K+tkv7ttfNiVTe0kbojvJkcjwK+C+ED guqJUkkg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eFjpI-0006jv-HB; Fri, 17 Nov 2017 16:49:12 +0000 Received: from casper.infradead.org ([85.118.1.10]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1eFjfs-0000EU-Nr for linux-arm-kernel@bombadil.infradead.org; Fri, 17 Nov 2017 16:39:28 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=unItyfmnajCsHr1mDmuffNmw13X4sqdFltH1A0gadWg=; b=DUcX18FcLPsPavL9LOPzAgxR6 or5G3I4waR6aPQtU7ms7nvZstNvjJ90ci5SioZzrhpU8vIDuaCkB9HI6hqc5S6YAhU2X6DS2jA+Vu t+s5IGLwpAtxM9+OwVtir7NRCNMk+OQXXD5gLNXQ7ydmlaKJL4477U3W+DVlXHwfGv5ccqKXbmNry sq24VOl+sop4K/kddA4Z39Trx/Vnm3qJTUArYBSx39whJdVWxYCey3zabGHa0J9bOooupkj1Oy8Un DuyEyRNoGxMrWUnWPhXd8LS0w3DSBxLgVlEKHE2GmRXREOnPapxOTrGJ2nW2tvEH9XpqfdaklVSxQ DporLw8Pg==; Received: from foss.arm.com ([217.140.101.70]) by casper.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eFjfo-00028n-34 for linux-arm-kernel@lists.infradead.org; Fri, 17 Nov 2017 16:39:27 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B3BB015BF; Fri, 17 Nov 2017 08:39:04 -0800 (PST) Received: from e103592.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id A46AE3F487; Fri, 17 Nov 2017 08:39:03 -0800 (PST) From: Dave Martin To: linux-arm-kernel@lists.infradead.org Subject: [RFC PATCH 2/4] arm64/sve: KVM: Avoid dereference of dead task during guest entry Date: Fri, 17 Nov 2017 16:38:53 +0000 Message-Id: <1510936735-6762-3-git-send-email-Dave.Martin@arm.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1510936735-6762-1-git-send-email-Dave.Martin@arm.com> References: <1510936735-6762-1-git-send-email-Dave.Martin@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171117_163924_424468_FCCD9F3A X-CRM114-Status: GOOD ( 17.74 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marc Zyngier , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= , kvmarm@lists.cs.columbia.edu, Christoffer Dall MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP When deciding whether to invalidate FPSIMD state cached in the cpu, the backend function sve_flush_cpu_state() attempts to dereference __this_cpu_read(fpsimd_last_state). However, this is not safe: there is no guarantee that the pointer is still valid, because the task could have exited in the meantime. For this reason, this percpu pointer should only be assigned or compared, never dereferenced. This means that we need another means to get the appropriate value of TIF_SVE for the associated task. This patch solves this issue by adding a cached copy of the TIF_SVE flag in fpsimd_last_state, which we can check without dereferencing the task pointer. Signed-off-by: Dave Martin --- arch/arm64/kernel/fpsimd.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 007140b..3dc8058 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -114,7 +114,12 @@ * returned from the 2nd syscall yet, TIF_FOREIGN_FPSTATE is still set so * whatever is in the FPSIMD registers is not saved to memory, but discarded. */ -static DEFINE_PER_CPU(struct fpsimd_state *, fpsimd_last_state); +struct fpsimd_last_state_struct { + struct fpsimd_state *st; + bool sve_in_use; +}; + +static DEFINE_PER_CPU(struct fpsimd_last_state_struct, fpsimd_last_state); /* Default VL for tasks that don't set it explicitly: */ static int sve_default_vl = -1; @@ -905,7 +910,7 @@ void fpsimd_thread_switch(struct task_struct *next) */ struct fpsimd_state *st = &next->thread.fpsimd_state; - if (__this_cpu_read(fpsimd_last_state) == st + if (__this_cpu_read(fpsimd_last_state.st) == st && st->cpu == smp_processor_id()) clear_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE); else @@ -997,9 +1002,12 @@ void fpsimd_signal_preserve_current_state(void) */ static void fpsimd_bind_to_cpu(void) { + struct fpsimd_last_state_struct *last = + this_cpu_ptr(&fpsimd_last_state); struct fpsimd_state *st = ¤t->thread.fpsimd_state; - __this_cpu_write(fpsimd_last_state, st); + last->st = st; + last->sve_in_use = test_thread_flag(TIF_SVE); st->cpu = smp_processor_id(); } @@ -1057,7 +1065,7 @@ void fpsimd_flush_task_state(struct task_struct *t) static inline void fpsimd_flush_cpu_state(void) { - __this_cpu_write(fpsimd_last_state, NULL); + __this_cpu_write(fpsimd_last_state.st, NULL); } /* @@ -1070,14 +1078,10 @@ static inline void fpsimd_flush_cpu_state(void) #ifdef CONFIG_ARM64_SVE void sve_flush_cpu_state(void) { - struct fpsimd_state *const fpstate = __this_cpu_read(fpsimd_last_state); - struct task_struct *tsk; - - if (!fpstate) - return; + struct fpsimd_last_state_struct const *last = + this_cpu_ptr(&fpsimd_last_state); - tsk = container_of(fpstate, struct task_struct, thread.fpsimd_state); - if (test_tsk_thread_flag(tsk, TIF_SVE)) + if (last->st && last->sve_in_use) fpsimd_flush_cpu_state(); } #endif /* CONFIG_ARM64_SVE */ @@ -1272,7 +1276,7 @@ static inline void fpsimd_pm_init(void) { } #ifdef CONFIG_HOTPLUG_CPU static int fpsimd_cpu_dead(unsigned int cpu) { - per_cpu(fpsimd_last_state, cpu) = NULL; + per_cpu(fpsimd_last_state.st, cpu) = NULL; return 0; }