From patchwork Wed Mar 22 14:50:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Martin X-Patchwork-Id: 9639137 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 CE57A601E9 for ; Wed, 22 Mar 2017 14:57:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BBAF928458 for ; Wed, 22 Mar 2017 14:57:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AE5E928475; Wed, 22 Mar 2017 14:57:43 +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=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID 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 2DC6B28458 for ; Wed, 22 Mar 2017 14:57:43 +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=c5nRgowKmIbtUHUVr93KX5QvfvLH+pvwIBow4Ws7D38=; b=COAUYRNB65AB1maHqFVVK8/+Gr 4mcL0H0eHFHPZNt5cvfUhvJEax2iIUfgXg2ZWWblTVG6gxnC5g4I9MZeVnfqM+UP88+/NWDSYLAdp LTb/mzf84Fl4o5KpobAuhWKOeqMTYDrfHQOSRBd0mvmJY8CPVn9RNnR4GpWBKEbLePEphXYG5Xeno TdmLTobTZ6ynOrfHvqyOBmtdEQdzPXBq//hoFFtm956jPPN++/d1coShHSmBJ3DYF06AUHdRC0NX4 ru+SsFHtgFJX/1DvrAy52fnSJrZmaGKEgFr3SxRHMVf4xZnCQqICi4kkjRWRCumuMwJ9HU0D3o4Ei AC9H4Y2w==; 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 1cqhhm-0005aC-4r; Wed, 22 Mar 2017 14:57:42 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cqhd1-0007mP-2W for linux-arm-kernel@lists.infradead.org; Wed, 22 Mar 2017 14:53:00 +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 746B11576; Wed, 22 Mar 2017 07:52:28 -0700 (PDT) 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 886C33F575; Wed, 22 Mar 2017 07:52:26 -0700 (PDT) From: Dave Martin To: linux-arm-kernel@lists.infradead.org Subject: [RFC PATCH v2 13/41] arm64/sve: [BROKEN] Basic support for KERNEL_MODE_NEON Date: Wed, 22 Mar 2017 14:50:43 +0000 Message-Id: <1490194274-30569-14-git-send-email-Dave.Martin@arm.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1490194274-30569-1-git-send-email-Dave.Martin@arm.com> References: <1490194274-30569-1-git-send-email-Dave.Martin@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170322_075247_945661_54988F5F X-CRM114-Status: GOOD ( 14.90 ) 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: Florian Weimer , Ard Biesheuvel , Marc Zyngier , Catalin Marinas , Will Deacon , Szabolcs Nagy , Joseph Myers 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 In order to enable CONFIG_KERNEL_MODE_NEON and things that rely on it to be configured together with Scalable Vector Extension support in the same kernel, this patch implements basic support for saving/restoring the SVE state around kernel_neon_begin()... kernel_neon_end(). This patch is not optimal and will generally save more state than necessary, more often than necessary. Further optimisations can be implemented in future patches. This patch is not intended to allow general-purpose _SVE_ code to execute in the kernel safely. That functionality may also follow in later patches. *** This patch is broken in its current form: *** Only the FPSIMD registers are ever saved around kernel_neon_begin{, _partial}()..._end(). However, for each Vn written, the high bits of each Zn other than bits [127:0] will be zeroed. This is a feature of the SVE architecture, and can corrupt userspace SVE state with this patch as-is. Instead, we need to save the full SVE regs if they are live: but this is a potentially large cost. It may also be unacceptable to pay this cost in IRQ handlers, but we have no way to back out once an IRQ handler calls kernel_neon_begin(). This will extend the interrupt blackout associated with IRQ handlers that use FPSIMD. It may be simpler to allow kernel_neon_begin() to fail if, say, the SVE registers are live or if called in IRQ context. The caller would need to have a fallback C implementation of its number-crunching code for this case. Signed-off-by: Dave Martin --- arch/arm64/Kconfig | 1 - arch/arm64/kernel/fpsimd.c | 23 +++++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 820fad1..05b6dd3 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -936,7 +936,6 @@ endmenu config ARM64_SVE bool "ARM Scalable Vector Extension support" default y - depends on !KERNEL_MODE_NEON # until it works with SVE help The Scalable Vector Extension (SVE) is an extension to the AArch64 execution state which complements and extends the SIMD functionality diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index f8acce2..7c6417a 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -298,11 +298,27 @@ void kernel_neon_begin_partial(u32 num_regs) { if (WARN_ON(!system_supports_fpsimd())) return; + + preempt_disable(); + + /* + * For now, we have no special storage for SVE registers in + * interrupt context, so always save the userland SVE state + * if there is any, even for interrupts. + */ + if (IS_ENABLED(CONFIG_ARM64_SVE) && (elf_hwcap & HWCAP_SVE) && + current->mm && + !test_and_set_thread_flag(TIF_FOREIGN_FPSTATE)) { + fpsimd_save_state(¤t->thread.fpsimd_state); + this_cpu_write(fpsimd_last_state, NULL); + } + if (in_interrupt()) { struct fpsimd_partial_state *s = this_cpu_ptr( in_irq() ? &hardirq_fpsimdstate : &softirq_fpsimdstate); - BUG_ON(num_regs > 32); + + /* Save partial state for interrupted kernel-mode NEON code: */ fpsimd_save_partial_state(s, roundup(num_regs, 2)); } else { /* @@ -311,7 +327,6 @@ void kernel_neon_begin_partial(u32 num_regs) * that there is no longer userland FPSIMD state in the * registers. */ - preempt_disable(); if (current->mm && !test_and_set_thread_flag(TIF_FOREIGN_FPSTATE)) fpsimd_save_state(¤t->thread.fpsimd_state); @@ -328,9 +343,9 @@ void kernel_neon_end(void) struct fpsimd_partial_state *s = this_cpu_ptr( in_irq() ? &hardirq_fpsimdstate : &softirq_fpsimdstate); fpsimd_load_partial_state(s); - } else { - preempt_enable(); } + + preempt_enable(); } EXPORT_SYMBOL(kernel_neon_end);