From patchwork Thu May 23 07:28:23 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 2605041 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) by patchwork2.kernel.org (Postfix) with ESMTP id 8C82FDFB78 for ; Thu, 23 May 2013 07:29:45 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UfPxs-0000bM-6E; Thu, 23 May 2013 07:29:32 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UfPxl-0003DI-LF; Thu, 23 May 2013 07:29:25 +0000 Received: from mail-we0-x22b.google.com ([2a00:1450:400c:c03::22b]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UfPxb-0003CF-Ab for linux-arm-kernel@lists.infradead.org; Thu, 23 May 2013 07:29:16 +0000 Received: by mail-we0-f171.google.com with SMTP id t59so1920680wes.30 for ; Thu, 23 May 2013 00:28:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:x-gm-message-state; bh=Z1/zZJLG2eAhpMFh/DrbM1AJRalYF259U1ec/cxf+iY=; b=dxGfFNO8WMJp69ABFeTYgG2RJ05B7H7s42IoqeampG6pMNiJIh9iQyrlPKSpDyA4m4 xf592kSpbaFahU+xUbm2l+XweYdFO7TY0OzjKFcR4NWtYAX4+8UsW7s+dmvd6kwUbbk5 WChCjlRS+0yEeWoCWfRPH3vT3mmP/CIIkWP8ljRd9wURIJydSBSv8sbVdgqLQv0R/l3C 3OB7t8PK5Dhd4p98AycyJJYT8dS0Yoyr97iQPsMKniEGQPpE12W2WYvDJLLBZwPlnHPg rnrFj6Cj0YcXuMofFtlsr42x2TDSlqHqg818RbRJ4Q+A56NzK+elyjakDwPz9fJ3chpB vG4A== X-Received: by 10.180.198.175 with SMTP id jd15mr1659387wic.28.1369294129114; Thu, 23 May 2013 00:28:49 -0700 (PDT) Received: from ards-mac-mini.local (cag06-7-83-153-85-71.fbx.proxad.net. [83.153.85.71]) by mx.google.com with ESMTPSA id q13sm15606441wie.8.2013.05.23.00.28.47 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 23 May 2013 00:28:48 -0700 (PDT) From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 1/2] ARM: add support for kernel mode NEON/VFP Date: Thu, 23 May 2013 09:28:23 +0200 Message-Id: <1369294104-3849-1-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 1.8.1.2 X-Gm-Message-State: ALoCoQlNeI0sVD8NCy8O+gIk6uFqU6ikbiHYC3i8jKswPO1N3IgeuVp0STBZ9DEmGdk5hwKd+UOG X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130523_032915_483776_7299EA5E X-CRM114-Status: GOOD ( 16.04 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Ard Biesheuvel , nico@linaro.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org In order to safely support the use of NEON or VFP instructions in kernel mode, some precautions need to be taken: - the userland context that may be present in the registers (even if the NEON/VFP is currently disabled) must be stored under the correct task (which may not be 'current' in the UP case), - to avoid having to keep track of additional vfpstates for the kernel side, disallow the use of NEON/VFP in interrupt context and run with preemption disabled, - after use, re-enable preemption and re-enable the lazy restore machinery by disabling the NEON/VFP unit. This patch adds the functions kernel_vfp_begin() and kernel_vfp_end() which take care of the above. Signed-off-by: Ard Biesheuvel --- arch/arm/include/asm/vfp.h | 5 +++++ arch/arm/vfp/vfpmodule.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/arch/arm/include/asm/vfp.h b/arch/arm/include/asm/vfp.h index f4ab34f..a488876 100644 --- a/arch/arm/include/asm/vfp.h +++ b/arch/arm/include/asm/vfp.h @@ -82,3 +82,8 @@ #define VFPOPDESC_UNUSED_BIT (24) #define VFPOPDESC_UNUSED_MASK (0xFF << VFPOPDESC_UNUSED_BIT) #define VFPOPDESC_OPDESC_MASK (~(VFPOPDESC_LENGTH_MASK | VFPOPDESC_UNUSED_MASK)) + +#ifndef __ASSEMBLY__ +void kernel_vfp_begin(void); +void kernel_vfp_end(void); +#endif diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 5dfbb0b..ab1eeae 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -649,6 +650,44 @@ static int vfp_hotplug(struct notifier_block *b, unsigned long action, } /* + * Kernel-side NEON/VFP support functions + */ +void kernel_vfp_begin(void) +{ + struct thread_info *thread = current_thread_info(); + unsigned int cpu; + u32 fpexc; + + /* Avoid using the NEON/VFP in interrupt context */ + might_sleep(); + cpu = get_cpu(); + + fpexc = fmrx(FPEXC) | FPEXC_EN; + fmxr(FPEXC, fpexc); + + /* + * Save the userland NEON/VFP state. Under UP, the owner could be a task + * other than 'current' + */ + if (vfp_state_in_hw(cpu, thread)) + vfp_save_state(&thread->vfpstate, fpexc); +#ifndef CONFIG_SMP + else if (vfp_current_hw_state[cpu] != NULL) + vfp_save_state(vfp_current_hw_state[cpu], fpexc); +#endif + vfp_current_hw_state[cpu] = NULL; +} +EXPORT_SYMBOL(kernel_vfp_begin); + +void kernel_vfp_end(void) +{ + /* Disable the NEON/VFP unit. */ + fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); + put_cpu(); +} +EXPORT_SYMBOL(kernel_vfp_end); + +/* * VFP support code initialisation. */ static int __init vfp_init(void)