From patchwork Thu Mar 16 08:20:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 13177173 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 2B277C6FD19 for ; Thu, 16 Mar 2023 08:21:17 +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=hVMKph7mNYYy8y2QpYOVGif/N+bvNk+ICQZiDK2+ylc=; b=dGFySItvhw4tUw OLN4TEqOOVe5YpH6bZ1JXTJt1tO9nMKFZmc95xxZ4KVL6CbOIoUN9sWVINVw0FqHifSR6MZ5E/0MR d3HbbHGiHxKwyFxqIoiiKVvOVmyZE2UfNsyQ83A1IBIpvq6UZ+yeehl4/oiNG2hw7L4BLv4f22eYW ltngmVtDeGODRuDT5ZZVXtSiVP0PxWIf0mUaClsX+2sRpRlhjcFTSaC1bJEMikmo/wojk2eTKrfMm 8z8D+QwVTB6hT3ndr9zRKVK9/Wl1RS4uXhc0i8rSvVFguBsOStyHCb1+H7hOGEUre+BZa6DRqyBRD kwek590Yi0GqiDMOJ3dg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1pciqf-00FdvU-1s; Thu, 16 Mar 2023 08:20:33 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1pciqY-00FdrE-1c for linux-arm-kernel@lists.infradead.org; Thu, 16 Mar 2023 08:20:29 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 02EAD61F57; Thu, 16 Mar 2023 08:20:26 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BCE5FC4339C; Thu, 16 Mar 2023 08:20:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678954825; bh=XLUkRu1FO02a8Cpw0ONEzkZtQNXoswbOq5+Dq9VRjWw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RbI0KF0Uf/+cGcSg0c47PzvIiZFnllk+rQ8gsZjvxxqo69iDGuEXcmQ70yRMMyFJT hM1s19w98u0f/+CrDz9PhtoRsoLCZtyn23PRNPGcr2vbT9TAWCjWDOBNdBN4LMAZ6l BOtXy/inNO4isWxaqG8JH5X7lwt73CiUONLrJBfyOXHIk6njO7E3OO+iOBNf1uWG05 pLEX9eAOBJzRme9IZGsCdFAZVsZXVu8yvfxN4sHQuOmx1F5OywL+Ng5FKrL5VMoNgX DfMPGrPHv3TcdKtIHo5PHhZJ+ti0UVr2+U5DSnU8wL7BJGJJKv3GGCjdpZ4m6iS9CQ 9DbxJDXRd4Maw== From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org, linux@armlinux.org.uk Cc: Ard Biesheuvel , Frederic Weisbecker , Guenter Roeck , Peter Zijlstra , Linus Walleij , Arnd Bergmann Subject: [PATCH v3 3/4] ARM: vfp: Fix broken softirq handling with instrumentation enabled Date: Thu, 16 Mar 2023 09:20:06 +0100 Message-Id: <20230316082007.652669-4-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230316082007.652669-1-ardb@kernel.org> References: <20230316082007.652669-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5298; i=ardb@kernel.org; h=from:subject; bh=XLUkRu1FO02a8Cpw0ONEzkZtQNXoswbOq5+Dq9VRjWw=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIUXootH3mQLK8yazHuP/MdtT0OS3jqOnuMIq+fvTmJbcW b2y19uso5SFQYyDQVZMkUVg9t93O09PlKp1niULM4eVCWQIAxenAExkmRAjw9lznL6HJ7HWnGO7 oBZ7LXZ3V9erXOMqZd13HObmzNd60hkZXji//XFDvfD91CUfVP+scXNNmr/S/RFblKjCqZN6lbX anAA= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230316_012026_656979_3B358F76 X-CRM114-Status: GOOD ( 17.18 ) 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 Commit 62b95a7b44d1 ("ARM: 9282/1: vfp: Manipulate task VFP state with softirqs disabled") replaced the en/disable preemption calls inside the VFP state handling code with en/disabling of soft IRQs, which is necessary to allow kernel use of the VFP/SIMD unit when handling a soft IRQ. Unfortunately, when lockdep is enabled (or other instrumentation that enables TRACE_IRQFLAGS), the disable path implemented in asm fails to perform the lockdep and RCU related bookkeeping, resulting in spurious warnings and other badness. Set let's rework the VFP entry code a little bit so we can make the local_bh_disable() call from C, with all the instrumentations that happen to have been configured. Calling local_bh_enable() can be done from asm, as it is a simple wrapper around __local_bh_enable_ip(), which is always a callable function. Link: https://lore.kernel.org/all/ZBBYCSZUJOWBg1s8@localhost.localdomain/ Fixes: 62b95a7b44d1 ("ARM: 9282/1: vfp: Manipulate task VFP state with softirqs disabled") Signed-off-by: Ard Biesheuvel Reviewed-by: Linus Walleij Tested-by: Guenter Roeck --- arch/arm/include/asm/assembler.h | 13 ---------- arch/arm/vfp/entry.S | 11 +------- arch/arm/vfp/vfphw.S | 12 ++++----- arch/arm/vfp/vfpmodule.c | 27 ++++++++++++++++---- 4 files changed, 29 insertions(+), 34 deletions(-) diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 06b48ce23e1ca245..505a306e0271a9c4 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -244,19 +244,6 @@ THUMB( fpreg .req r7 ) .endm #endif - .macro local_bh_disable, ti, tmp - ldr \tmp, [\ti, #TI_PREEMPT] - add \tmp, \tmp, #SOFTIRQ_DISABLE_OFFSET - str \tmp, [\ti, #TI_PREEMPT] - .endm - - .macro local_bh_enable_ti, ti, tmp - get_thread_info \ti - ldr \tmp, [\ti, #TI_PREEMPT] - sub \tmp, \tmp, #SOFTIRQ_DISABLE_OFFSET - str \tmp, [\ti, #TI_PREEMPT] - .endm - #define USERL(l, x...) \ 9999: x; \ .pushsection __ex_table,"a"; \ diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index 6dabb47617781a5f..7483ef8bccda394c 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S @@ -24,14 +24,5 @@ ENTRY(do_vfp) mov r1, r10 mov r3, r9 - ldr r4, .LCvfp - ldr pc, [r4] @ call VFP entry point + b vfp_entry ENDPROC(do_vfp) - -ENTRY(vfp_null_entry) - ret lr -ENDPROC(vfp_null_entry) - - .align 2 -.LCvfp: - .word vfp_vector diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 60acd42e05786e95..4d8478264d82b3d2 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -75,8 +75,6 @@ @ lr = unrecognised instruction return address @ IRQs enabled. ENTRY(vfp_support_entry) - local_bh_disable r1, r4 - ldr r11, [r1, #TI_CPU] @ CPU number add r10, r1, #TI_VFPSTATE @ r10 = workspace @@ -179,9 +177,12 @@ vfp_hw_state_valid: @ else it's one 32-bit instruction, so @ always subtract 4 from the following @ instruction address. - local_bh_enable_ti r10, r4 - ret r3 @ we think we have handled things + mov lr, r3 @ we think we have handled things +local_bh_enable_and_ret: + adr r0, . + mov r1, #SOFTIRQ_DISABLE_OFFSET + b __local_bh_enable_ip @ tail call look_for_VFP_exceptions: @ Check for synchronous or asynchronous exception @@ -204,8 +205,7 @@ skip: @ not recognised by VFP DBGSTR "not VFP" - local_bh_enable_ti r10, r4 - ret lr + b local_bh_enable_and_ret process_exception: DBGSTR "bounce" diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 86fb0be41ae14b6c..3f88599c285a5d4b 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -32,10 +32,9 @@ /* * Our undef handlers (in entry.S) */ -asmlinkage void vfp_support_entry(void); -asmlinkage void vfp_null_entry(void); +asmlinkage void vfp_support_entry(u32, void *, u32, u32); -asmlinkage void (*vfp_vector)(void) = vfp_null_entry; +static bool have_vfp __ro_after_init; /* * Dual-use variable. @@ -799,7 +798,6 @@ static int __init vfp_init(void) vfpsid = fmrx(FPSID); barrier(); unregister_undef_hook(&vfp_detect_hook); - vfp_vector = vfp_null_entry; pr_info("VFP support v0.3: "); if (VFP_arch) { @@ -884,7 +882,7 @@ static int __init vfp_init(void) "arm/vfp:starting", vfp_starting_cpu, vfp_dying_cpu); - vfp_vector = vfp_support_entry; + have_vfp = true; thread_register_notifier(&vfp_notifier_block); vfp_pm_init(); @@ -906,3 +904,22 @@ static int __init vfp_init(void) } core_initcall(vfp_init); + +/* + * Entered with: + * + * r0 = instruction opcode (32-bit ARM or two 16-bit Thumb) + * r1 = thread_info pointer + * r2 = PC value to resume execution after successful emulation + * r3 = normal "successful" return address + * lr = unrecognised instruction return address + */ +asmlinkage void vfp_entry(u32 trigger, struct thread_info *ti, u32 resume_pc, + u32 resume_return_address) +{ + if (unlikely(!have_vfp)) + return; + + local_bh_disable(); + vfp_support_entry(opcode, ti, resume_pc, resume_return_address); +}