From patchwork Fri Jun 28 13:46:16 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: 13716168 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 8F5CDC3064D for ; Fri, 28 Jun 2024 13:47:32 +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=GnSyvEIlj7F9IRVbgoytJSD4TReYwLjwz36HympkhFM=; b=YuXyogosLdQV7q/iVfsTjw+f/2 e/CAbDTj2l37GKlq0D5k0xFA/EBcOkBJaXA6DeI9P1q6W5XBybkQ/Niq+XPizqUC09zBo2/BS1kOp NkGoBeD1esJGX5LoKsaOm7gCiBIGKxjqBNN/k5zwEopY9HeJk7AiX+VZxSI48SvR2Eb0f/LtAG5nk I8AydcMxD6gb/jZw7LIbd+GD8RJfnqrPAr6sPOIep/SH6uVp8CD6g8UUBXvN/woQB/4IUzrc22rrX feAHmD4NmktGcgXEa4gPuXLgsGOvbm8L2QhnIbgufVGRY2vcA+bn4u6szoW+8BH6QbnCgTu2wxy3q M0q1/D4Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sNBwe-0000000DrTW-2kFn; Fri, 28 Jun 2024 13:47:20 +0000 Received: from galois.linutronix.de ([2a0a:51c0:0:12e:550::1]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sNBwG-0000000DrNg-3gxT for linux-arm-kernel@lists.infradead.org; Fri, 28 Jun 2024 13:47:02 +0000 From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1719582414; 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=GnSyvEIlj7F9IRVbgoytJSD4TReYwLjwz36HympkhFM=; b=wRgy+ei+R+OkG7SzBN94bu0IF7iyUfw0g2ZBpP6VL2KWb/eYDYaB2Xodq+V6k2vC7ago7R dlV2Pz40r6J2DAjygBKhHTh+os106S5J6r/ryCAMgdJDi0La9MZw+CwPTv3yp1wtxgfln6 LzilQeCT8qBlHrelRgkgAXaVcfs0/ELCZuWVLFU9TuxDwEuZzBUHkP/OWwBy5GXWfQGNul KyzUXuhX4r8xNwNdJr9z5FuqJu7E8jqTw2aISH0eWBQX8fdpaz3jyh+IpodghqQSbiHCdK yReztxZUDJ4zZfri0P1dEgZmznHXIBhr0eHiVAAkG5T++HP/60FPS1Nk9X/cjA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1719582414; 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=GnSyvEIlj7F9IRVbgoytJSD4TReYwLjwz36HympkhFM=; b=6ZPSXdSjxl5uCUDNGjstbfx8anGJ9WhhuxMjD115GAMk7iMu98KqhOUaZ1j+i/DCe825Vn LBUYz2oR+0J8tkBA== To: linux-arm-kernel@lists.infradead.org Cc: Arnd Bergmann , Russell King , Thomas Gleixner , Sebastian Andrzej Siewior , Ard Biesheuvel Subject: [PATCH v5 1/4] ARM: vfp: Provide vfp_lock() for VFP locking. Date: Fri, 28 Jun 2024 15:46:16 +0200 Message-ID: <20240628134648.1852041-2-bigeasy@linutronix.de> In-Reply-To: <20240628134648.1852041-1-bigeasy@linutronix.de> References: <20240628134648.1852041-1-bigeasy@linutronix.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240628_064657_455585_8E149CFF X-CRM114-Status: GOOD ( 13.60 ) 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);