From patchwork Wed Mar 22 14:50:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Martin X-Patchwork-Id: 9639215 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 41706602CB for ; Wed, 22 Mar 2017 15:18:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 323CA28420 for ; Wed, 22 Mar 2017 15:18:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 26DAB28461; Wed, 22 Mar 2017 15:18:52 +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 6FC0428420 for ; Wed, 22 Mar 2017 15:18:51 +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=KFOdNmN5WQMGkIdRsBN2P0HPB615mstN7+LJaKPjTOc=; b=Icl+J2qwTIP1ldZ0vogVhq9TIC yVl6ZfrGb1y3u9yhVwRCjjVRAiqRGAsInwaHwq0Mq9czg6XHd7yvf8zjssFEuY+VMP7+BUpk0VjcL XhC9AQz+iHzlh1BmH3Tv2f2HcY44Nz2pfAasI8JGjB7ftlNU7nQ8COBKcO0lWOIppEiCnLYihFMY6 bLEJFL//V435z6wZ6984UtuxM6N+UbB+m8z2nr7uxzjAKXUAIL1808kX0nEYCerU9V8aRzL/d7mhH N6+gE+0y1PKbEDMUhXoGRyJcmQ2uLSgdrfooZ4QAxMI16jmALpu94We2FyvFVeLYspBSZSAOy1kEi xFSd4EaA==; 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 1cqi2D-0005Gx-TK; Wed, 22 Mar 2017 15:18:50 +0000 Received: from merlin.infradead.org ([2001:4978:20e::2]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cqhxm-00018w-Do for linux-arm-kernel@bombadil.infradead.org; Wed, 22 Mar 2017 15:14:14 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.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=PDv3dT6ERQLqcAOfMBo1P7UR1DWFVsBoXFXJEaW3fmw=; b=viDfhItVdSi4NEoJwhMDbo3BM O5sZGF6DczkjDANxzHkyFPOsT7ACcBm+ENwrPeSZVnLqgptaoamFXOiy8mll5T7hjzjwPiYciY2mh mJagtbHzjNTvBgY+vlExsBc8MBrixgo8c79AGXgAnCqg9Vk294aVNa2+YIQltH/J3X0vMkN3VfXdK mp/tkQ6X5zwbF0CdUWjDoSf6LUGr/K2ZUlgTdxIjVryzmWfCiNosXBSubW/bZTns4DME83BvlJNsB 5CjzGClKBy/cVhZlXARlJYwWU6Qn4wWacgVP9XXoidfD+tqjhb4j8XcNvefa77F9WBJX8jAFbyFKR 9MFCfg86A==; Received: from foss.arm.com ([217.140.101.70]) by merlin.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cqhdd-0006ja-El for linux-arm-kernel@lists.infradead.org; Wed, 22 Mar 2017 14:53: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 133CE1477; Wed, 22 Mar 2017 07:53:10 -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 72AA43F575; Wed, 22 Mar 2017 07:53:08 -0700 (PDT) From: Dave Martin To: linux-arm-kernel@lists.infradead.org Subject: [RFC PATCH v2 22/41] arm64/sve: Implement FPSIMD-only context for tasks not using SVE Date: Wed, 22 Mar 2017 14:50:52 +0000 Message-Id: <1490194274-30569-23-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_105325_683159_E9CE3C8F X-CRM114-Status: GOOD ( 14.18 ) 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 To reduce unnecessary context switch overhead, we don't need to switch the whole SVE state for tasks that are not using it. This patch restores the FPSIMD-only behaviour for tasks that have never used SVE. Note that coredumps and ptrace may see FPSIMD/SVE out of sync at present -- this will be fixed later. SVE state is saved on signal delivery only for tasks that have used SVE. However, it should be possible to add SVE state on return from a signal handler when the task didn't have any SVE state previously. The caller may need to add its own SVE record to the signal frame in this case. Signed-off-by: Dave Martin --- arch/arm64/kernel/fpsimd.c | 28 ++++++++++++++++++---------- arch/arm64/kernel/signal.c | 5 ++++- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 749f4f0..260438d 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -156,6 +156,10 @@ void do_sve_acc(unsigned int esr, struct pt_regs *regs) if (test_and_set_thread_flag(TIF_SVE)) BUG(); + BUG_ON(is_compat_task()); + + fpsimd_to_sve(current); + asm ("mrs %0, cpacr_el1" : "=r" (tmp)); asm volatile ("msr cpacr_el1, %0" :: "r" (tmp | (1 << 17))); /* Serialised by exception return to user */ @@ -210,7 +214,8 @@ void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs) static void task_fpsimd_load(struct task_struct *task) { - if (IS_ENABLED(CONFIG_ARM64_SVE) && (elf_hwcap & HWCAP_SVE)) + if (IS_ENABLED(CONFIG_ARM64_SVE) && + test_tsk_thread_flag(task, TIF_SVE)) sve_load_state(sve_pffr(task), &task->thread.fpsimd_state.fpsr); else @@ -222,7 +227,8 @@ static void task_fpsimd_save(struct task_struct *task) /* FIXME: remove task argument? */ BUG_ON(task != current); - if (IS_ENABLED(CONFIG_ARM64_SVE) && (elf_hwcap & HWCAP_SVE)) + if (IS_ENABLED(CONFIG_ARM64_SVE) && + test_tsk_thread_flag(task, TIF_SVE)) sve_save_state(sve_pffr(task), &task->thread.fpsimd_state.fpsr); else @@ -253,11 +259,9 @@ void fpsimd_thread_switch(struct task_struct *next) if (__this_cpu_read(fpsimd_last_state) == st && st->cpu == smp_processor_id()) - clear_ti_thread_flag(task_thread_info(next), - TIF_FOREIGN_FPSTATE); + clear_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE); else - set_ti_thread_flag(task_thread_info(next), - TIF_FOREIGN_FPSTATE); + set_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE); } } @@ -304,7 +308,8 @@ void fpsimd_preserve_current_state(void) void fpsimd_signal_preserve_current_state(void) { fpsimd_preserve_current_state(); - sve_to_fpsimd(current); + if (test_thread_flag(TIF_SVE)) + sve_to_fpsimd(current); } /* @@ -354,7 +359,7 @@ void fpsimd_update_current_state(struct fpsimd_state *state) return; preempt_disable(); - if (IS_ENABLED(CONFIG_ARM64_SVE)) { + if (IS_ENABLED(CONFIG_ARM64_SVE) && test_thread_flag(TIF_SVE)) { current->thread.fpsimd_state = *state; fpsimd_to_sve(current); } @@ -398,8 +403,8 @@ void kernel_neon_begin_partial(u32 num_regs) * 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 && + if (IS_ENABLED(CONFIG_ARM64_SVE) && + test_thread_flag(TIF_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); @@ -527,6 +532,9 @@ static int __init fpsimd_init(void) if (!(elf_hwcap & HWCAP_ASIMD)) pr_notice("Advanced SIMD is not implemented\n"); + if (!(elf_hwcap & HWCAP_SVE)) + pr_info("Scalable Vector Extension available\n"); + return 0; } late_initcall(fpsimd_init); diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index c3e15e2..619dca5 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -259,6 +259,7 @@ static int __restore_sve_fpsimd_context(struct user_ctxs *user, preempt_disable(); set_thread_flag(TIF_FOREIGN_FPSTATE); + set_thread_flag(TIF_SVE); BUG_ON(SVE_SIG_REGS_SIZE(vq) > sizeof(*task_sve_regs)); BUG_ON(round_up(SVE_SIG_REGS_SIZE(vq), 16) < sizeof(*task_sve_regs)); @@ -543,9 +544,11 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user) return err; } - if (IS_ENABLED(CONFIG_ARM64_SVE) && (elf_hwcap & HWCAP_SVE)) { + if (IS_ENABLED(CONFIG_ARM64_SVE) && test_thread_flag(TIF_SVE)) { unsigned int vq = sve_vq_from_vl(sve_get_vl()); + BUG_ON(!(elf_hwcap & HWCAP_SVE)); + err = sigframe_alloc(user, &user->sve_offset, SVE_SIG_CONTEXT_SIZE(vq)); if (err)