From patchwork Mon Jul 1 10:56:53 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: 13717902 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 A4D32C2BD09 for ; Mon, 1 Jul 2024 11:04:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=zEGdA9t+YC6ECkr5w6/6t9cS+dhhNbOxtOrmytTbblk=; b=11ObbcTx0JJar7THjq63cSlqO8 /x9f3MHEQRzsbfyhouQWZuBBUDJtoCyl6jVqroIryr9M4LShQruRApFjxvOuq0pfBJxfnH/xFC/EF ww4OTWiPMec+v6cJRjpYG6H/B5ZjTymQJKpFcCTpVkCtKkQhOZWhpKkiGlR466wi1Fkg/Yic4xlgD yHRH/hY+i8RXLOCLI5bKGTAaYk04spxgakomFRgfSb4fztYmxEQiAZzRJCOOuT+lU6Uobx29Hqyxq D8ikoHk9D07fnwlpuGXojJRXY3u6Qd2CTlEmRIRnMgbkOKMpx21/qpdbEfvQ5t2S5Pj13utLmFKUI cNv79SgA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sOEp6-00000002pdT-3udz; Mon, 01 Jul 2024 11:03:53 +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 1sOEom-00000002pYM-2xa5 for linux-arm-kernel@lists.infradead.org; Mon, 01 Jul 2024 11:03:36 +0000 From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1719831811; 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=zEGdA9t+YC6ECkr5w6/6t9cS+dhhNbOxtOrmytTbblk=; b=E7ZG+uc/LET+c76kAXr6CXEBkX9Z/HreEVnt4pqzewibHEwCZcJ+WmHLBG5DG/qwrL1gFl GJfZuSdcsyv91YAGGGzKt/HaalpE4kiaWmSCG/Ha5UAhNcSmFbejdbLTP9V7lTBjo7ztSk GgL1qWXeEYJ3u5FtNfjRuXy8Ee3w6DR8P3tuJkwTIoBpA8MRmJ6tYo5N0y94B42W5JCxI8 Cc3h+8FAu2UvzNlRy7BQnUi04JHit14S4BJft9MD36HTrwedAPyOcFRNX94uCChWxXPSTm EAeuZ71s/KhR5YxJkdCyGVrgX7HR7izGPODhNebQvMp5zMtzVSYIIlMQ/vp0gQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1719831811; 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=zEGdA9t+YC6ECkr5w6/6t9cS+dhhNbOxtOrmytTbblk=; b=pfYa7lKUUh+NylJBSXEkVokZqpbeNXcQQiGRG2vWZf5ZeFo03g3hK3ClcZQzvuSerCmVHM ipH0yoWIsacGGvCA== To: linux-arm-kernel@lists.infradead.org Cc: Arnd Bergmann , Russell King , Thomas Gleixner , Sebastian Andrzej Siewior , Ard Biesheuvel Subject: [PATCH v6 1/4] ARM: vfp: Provide vfp_state_hold() for VFP locking. Date: Mon, 1 Jul 2024 12:56:53 +0200 Message-ID: <20240701110317.99631-2-bigeasy@linutronix.de> In-Reply-To: <20240701110317.99631-1-bigeasy@linutronix.de> References: <20240701110317.99631-1-bigeasy@linutronix.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240701_040332_920273_4D7DF430 X-CRM114-Status: GOOD ( 13.71 ) 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_state_hold() 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..63de164c7fc7b 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_state_release() 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_state_hold(void) +{ + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + local_bh_disable(); + else + preempt_disable(); +} + +static void vfp_state_release(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_state_hold(); /* * 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_state_release(); } EXPORT_SYMBOL(kernel_neon_end);