From patchwork Fri Mar 15 14:51:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Andrzej Siewior X-Patchwork-Id: 13593581 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4E70FC54E67 for ; Fri, 15 Mar 2024 14:52:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=QTDha9UYr04KkAW5cLP0tjgpIJLduw1Z7wVk3bZ00gY=; b=aMpNp7rY811zgv ApZN1sKQgfugxJsL03E/R71zNw3ZlfLb4OdEwYkRhyGyKSR+DY9T9Uib6J3ee80eq/sXSsjRaIVga FhW7ymwv0anWa6knHgFQ9F+4z8d4r8RIXtuWNH2GZh0n6xpjMR555wDAEi6u3pZ3iRsMDvqqW5yrH vioAu2zAUr7RS464yV44EQEOukAb8m4yGa9L1DzAOF2zP/9G/QsW3U74Xh9R4xdBRck2fSbw41Njx w7dPfaY7ypQlYPFo2cHA5wu1ThTD0hBe0QGUHNDnn7Cj+/klVPfYrO+dH88JHttSF0FBYmlZE6tsl ALJi8YykVkmoJbiq9Swg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rl8vL-00000000Z59-0jF4; Fri, 15 Mar 2024 14:52:43 +0000 Received: from galois.linutronix.de ([193.142.43.55]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rl8v0-00000000YxD-3MAk for linux-arm-kernel@lists.infradead.org; Fri, 15 Mar 2024 14:52:35 +0000 From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1710514338; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7ectyru+WVbUpcBsyI0+gtYVBXWtkG0e5PNgSg/gvNU=; b=cR6dgGfWCLofQ3c8wGW//hat4AT25inPMcko31n2/PxBaxyYkDeyLanBKztFpQ3KoISKaA 5Rb/UQ+QmjxbcLLbHEW+jV+q1yCV2rxeP3e+6uxHbQHEzxOc/rAZJ5BY3WwO9IfIjhW95Z uMKpAcxen5mmL95oSeRcdOgQhQ5YK1AwmUr4UZLL5Pr1hcxE7t7TurfgoM+4pZkR/pkSmy 9dYtVB4P8s27TagLra90sw+96YdsxuiWwojoCsZ9MAyEIZOl2m2y4P9q3zA8aqTBnezp/l Di1gy/uOvD8fs8ZF7Pz978AALGJ2cgiFJTWRKnho7VjrVNeAZWU+oXxNF+LR5Q== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1710514338; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7ectyru+WVbUpcBsyI0+gtYVBXWtkG0e5PNgSg/gvNU=; b=8/DiXtQ0DHJdHfA9UHTGgWlt2Pi5UCA6fVXXAsvLIaD65UdsC2cVEGemK0Y5RMw6t+h2Yd 5zG0Pf8pvkHj47Bw== To: linux-arm-kernel@lists.infradead.org, linux@armlinux.org.uk Cc: ardb@kernel.org, tglx@linutronix.de, Sebastian Andrzej Siewior Subject: [PATCH v4 1/4] ARM: vfp: Provide vfp_lock() for VFP locking. Date: Fri, 15 Mar 2024 15:51:00 +0100 Message-ID: <20240315145208.3598288-2-bigeasy@linutronix.de> In-Reply-To: <20240315145208.3598288-1-bigeasy@linutronix.de> References: <20240315145208.3598288-1-bigeasy@linutronix.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240315_075223_032255_7B26587A X-CRM114-Status: GOOD ( 12.68 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org kernel_neon_begin() uses local_bh_disable() to ensure exclusive access to the VFP unit. This is broken on PREEMPT_RT because a BH disabled section remains preemptible on PREEMPT_RT. Introduce vfp_lock() which uses local_bh_disable() and preempt_disable() on PREEMPT_RT. Since softirqs are processed always in thread context, disabling preemption is enough to ensure that the current context won't get interrupted by something that is using the VFP. Use it in kernel_neon_begin(). Reviewed-by: Ard Biesheuvel Signed-off-by: Sebastian Andrzej Siewior --- arch/arm/vfp/vfpmodule.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index b68efe643a12c..7d234fc82ebf6 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -55,6 +55,34 @@ extern unsigned int VFP_arch_feroceon __alias(VFP_arch); */ union vfp_state *vfp_current_hw_state[NR_CPUS]; +/* + * Claim ownership of the VFP unit. + * + * The caller may change VFP registers until vfp_unlock() is called. + * + * local_bh_disable() is used to disable preemption and to disable VFP + * processing in softirq context. On PREEMPT_RT kernels local_bh_disable() is + * not sufficient because it only serializes soft interrupt related sections + * via a local lock, but stays preemptible. Disabling preemption is the right + * choice here as bottom half processing is always in thread context on RT + * kernels so it implicitly prevents bottom half processing as well. + */ +static void vfp_lock(void) +{ + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + local_bh_disable(); + else + preempt_disable(); +} + +static void vfp_unlock(void) +{ + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + local_bh_enable(); + else + preempt_enable(); +} + /* * Is 'thread's most up to date state stored in this CPUs hardware? * Must be called from non-preemptible context. @@ -837,7 +865,7 @@ void kernel_neon_begin(void) unsigned int cpu; u32 fpexc; - local_bh_disable(); + vfp_lock(); /* * Kernel mode NEON is only allowed outside of hardirq context with @@ -868,7 +896,7 @@ void kernel_neon_end(void) { /* Disable the NEON/VFP unit. */ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); - local_bh_enable(); + vfp_unlock(); } EXPORT_SYMBOL(kernel_neon_end);