From patchwork Tue Sep 26 12:54:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Andrzej Siewior X-Patchwork-Id: 13399233 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 D85ABE7E62F for ; Tue, 26 Sep 2023 12:55:58 +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=kSykvOKGvKSZJLhGbZaF5o2VLsziJnzVjzQNh5T7wi0=; b=fCNq+NK7ikKE3p fvSCGmKzrsDi5lT5lUr8TmWCQNXtRY6nXW/KQSKBPUG1LbhCSwX1U3UdWTeyZczo1dUy9ywKPnX63 mdaF3jxAaOoOvHIuT7zG/2tM2KjDwXmHNmLvnwOGeIcS5KSaPnRY6FZUIZffdnzo/HWI8SM61Rzxn 0aLhuojfm2BRfwhlvpxlv3lkLIzycw5cr12LVbN8bRxUcrCUiimYGINEZelr7LDoSEx32oQzu+sD3 paKirOczhJAVPeV8kmaz+uoyLiZFrbpZAeUhqIWPFL+b5/U+UVjCOgxWRi/yLpjUzLYDxSh9/5b+m mkZAVe1oWEkqUbbycagw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1ql7b9-00GPBx-39; Tue, 26 Sep 2023 12:55:31 +0000 Received: from galois.linutronix.de ([2a0a:51c0:0:12e:550::1]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1ql7aw-00GP7O-0i for linux-arm-kernel@lists.infradead.org; Tue, 26 Sep 2023 12:55:20 +0000 From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1695732914; 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=dBpRnC0ApiIbGjESCAWlJj2jO+qaa+UVAXGivLH6ziI=; b=fI2sdpesxjZHbqVu80foOCEUJWqckqojVmfeF3hXdI5DbNMVZcYtcpt/KPztQYNAYFjndp O6DbL5IZUGhLtj5ce+Y3nTtZQ50cYn8DeQxv+XLNQQnmuFVIcZIAVxwAjg2XuMof8Hoyq/ iYgo1EadtG9IOjZp0oo6yWXjNAdvTaj5h9uDvOPkJ+srm76yei1kWQtpZREF+MBz4camda Z48JkvG9i46Jq9dewdkzKKZShjmGcf7+YUwLEDGnZxzIBYCMop0L+ye9bVgs30Rzhg5Rp4 vH1sLkQa13G5B575hJ7riN9AaixgPoS1ORmiD6YkFA7O4ZqTRJ1LWD1auRIMFw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1695732914; 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=dBpRnC0ApiIbGjESCAWlJj2jO+qaa+UVAXGivLH6ziI=; b=c5gHvOWbwWxzz5WfO51hX3lcvvPgc9Vs/7xGX2eGi8dstd3z3Z9rbLte8+GDfVeW29kxWf Usx7WZ2dGwslq0Cw== To: linux-arm-kernel@lists.infradead.org, linux@armlinux.org.uk Cc: ardb@kernel.org, tglx@linutronix.de, Sebastian Andrzej Siewior Subject: [PATCH v3 1/4] ARM: vfp: Provide vfp_lock() for VFP locking. Date: Tue, 26 Sep 2023 14:54:59 +0200 Message-Id: <20230926125502.1127015-2-bigeasy@linutronix.de> In-Reply-To: <20230926125502.1127015-1-bigeasy@linutronix.de> References: <20230926125502.1127015-1-bigeasy@linutronix.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230926_055518_403213_0B27C3FE X-CRM114-Status: GOOD ( 12.73 ) 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(). Signed-off-by: Sebastian Andrzej Siewior Reviewed-by: Ard Biesheuvel --- 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 7e8773a2d99d0..8d321cdb7ac58 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. @@ -819,7 +847,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 @@ -850,7 +878,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);