From patchwork Thu May 17 12:40:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Andrzej Siewior X-Patchwork-Id: 10406725 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 D49BC60155 for ; Thu, 17 May 2018 12:41:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A304428C9F for ; Thu, 17 May 2018 12:41:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9F8C928B8E; Thu, 17 May 2018 12:41:39 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.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 8A82D28BDD for ; Thu, 17 May 2018 12:41:10 +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:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Subject:To:From :Date:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=cxcxrg00scrjDTgvjLFitziwefI+3KoY48cnfsXwwi4=; b=TyO2Tuvwrz61QW SD9LbzmostvM0dm+Js3RbekMHTKdsCAnYp1N7Q7svIGbpJj9q7atnTDrFw6+VxOBLD6JQ1wN1lY+f Uz28YI0ga0Jc/Ma2jJYylJKx0fPmPwOgbRWKtYG7mOqP/Aoq/3PK8kuxzmo5Pa8RZXEff0xv/Zvks 44cy1DoJkhTBxpuxrg5t0jCJ8PRqtFcpuCBP3fhPMKI35eAtrIwFWxdQBVEfix+l0P8ZA3MqbU91W aI2mdWVMidtHFH/wZY6xCCH8sZhrwJQYRO5iY1IzRJhJKl3NLUWFAB8UohTVajlkDoSGAlmVeeFdC JZqb8JUbJwZanrX0v+iA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fJIDH-0000Oh-Mc; Thu, 17 May 2018 12:40:55 +0000 Received: from galois.linutronix.de ([2a01:7a0:2:106d:700::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fJICp-0007nG-Mf for linux-arm-kernel@lists.infradead.org; Thu, 17 May 2018 12:40:31 +0000 Received: from bigeasy by Galois.linutronix.de with local (Exim 4.80) (envelope-from ) id 1fJICV-0007TT-1H; Thu, 17 May 2018 14:40:07 +0200 Date: Thu, 17 May 2018 14:40:06 +0200 From: Sebastian Andrzej Siewior To: linux-rt-users@vger.kernel.org Subject: [PATCH RT] arm64: fpsimd: use a local_lock() in addition to local_bh_disable() Message-ID: <20180517124006.ohygrrpg7z2moqqt@linutronix.de> MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20180323 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180517_054027_964661_A6840390 X-CRM114-Status: GOOD ( 15.05 ) 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: Catalin Marinas , Will Deacon , linux-kernel@vger.kernel.org, Steven Rostedt , tglx@linutronix.de, linux-arm-kernel@lists.infradead.org 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 In v4.16-RT I noticed a number of warnings from task_fpsimd_load(). The code disables BH and expects that it is not preemptible. On -RT the task remains preemptible but remains the same CPU. This may corrupt the content of the SIMD registers if the task is preempted during saving/restoring those registers. Add a locallock around next to the local_bh_disable(). This fulfill the requirement that the code is not invoked again in different context on the same CPU while it remains preemptible. The preempt_disable() + local_bh_enable() combo in kernel_neon_begin() is not working on -RT. We don't use NEON in kernel mode on RT right now but this still should be addressed. Signed-off-by: Sebastian Andrzej Siewior --- arch/arm64/kernel/fpsimd.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index e7226c4c7493..3a5cd1908874 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -235,7 +236,7 @@ static void sve_user_enable(void) * whether TIF_SVE is clear or set, since these are not vector length * dependent. */ - +static DEFINE_LOCAL_IRQ_LOCK(fpsimd_lock); /* * Update current's FPSIMD/SVE registers from thread_struct. * @@ -594,6 +595,7 @@ int sve_set_vector_length(struct task_struct *task, * non-SVE thread. */ if (task == current) { + local_lock(fpsimd_lock); local_bh_disable(); task_fpsimd_save(); @@ -604,8 +606,10 @@ int sve_set_vector_length(struct task_struct *task, if (test_and_clear_tsk_thread_flag(task, TIF_SVE)) sve_to_fpsimd(task); - if (task == current) + if (task == current) { + local_unlock(fpsimd_lock); local_bh_enable(); + } /* * Force reallocation of task SVE state to the correct size @@ -838,6 +842,7 @@ asmlinkage void do_sve_acc(unsigned int esr, struct pt_regs *regs) sve_alloc(current); local_bh_disable(); + local_lock(fpsimd_lock); task_fpsimd_save(); fpsimd_to_sve(current); @@ -849,6 +854,7 @@ asmlinkage void do_sve_acc(unsigned int esr, struct pt_regs *regs) if (test_and_set_thread_flag(TIF_SVE)) WARN_ON(1); /* SVE access shouldn't have trapped */ + local_unlock(fpsimd_lock); local_bh_enable(); } @@ -926,6 +932,7 @@ void fpsimd_flush_thread(void) return; local_bh_disable(); + local_lock(fpsimd_lock); memset(¤t->thread.fpsimd_state, 0, sizeof(struct fpsimd_state)); fpsimd_flush_task_state(current); @@ -967,6 +974,7 @@ void fpsimd_flush_thread(void) set_thread_flag(TIF_FOREIGN_FPSTATE); + local_unlock(fpsimd_lock); local_bh_enable(); } @@ -980,7 +988,9 @@ void fpsimd_preserve_current_state(void) return; local_bh_disable(); + local_lock(fpsimd_lock); task_fpsimd_save(); + local_unlock(fpsimd_lock); local_bh_enable(); } @@ -1022,12 +1032,14 @@ void fpsimd_restore_current_state(void) return; local_bh_disable(); + local_lock(fpsimd_lock); if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) { task_fpsimd_load(); fpsimd_bind_to_cpu(); } + local_unlock(fpsimd_lock); local_bh_enable(); } @@ -1042,6 +1054,7 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state) return; local_bh_disable(); + local_lock(fpsimd_lock); current->thread.fpsimd_state.user_fpsimd = *state; if (system_supports_sve() && test_thread_flag(TIF_SVE)) @@ -1052,6 +1065,7 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state) if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) fpsimd_bind_to_cpu(); + local_unlock(fpsimd_lock); local_bh_enable(); } @@ -1116,6 +1130,7 @@ void kernel_neon_begin(void) BUG_ON(!may_use_simd()); local_bh_disable(); + local_lock(fpsimd_lock); __this_cpu_write(kernel_neon_busy, true); @@ -1128,6 +1143,7 @@ void kernel_neon_begin(void) /* Invalidate any task state remaining in the fpsimd regs: */ fpsimd_flush_cpu_state(); + local_unlock(fpsimd_lock); preempt_disable(); local_bh_enable();