aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/vfp/vfphw.S
diff options
context:
space:
mode:
authorGravatar Ard Biesheuvel <ardb@kernel.org> 2023-04-12 09:50:20 +0100
committerGravatar Russell King (Oracle) <rmk+kernel@armlinux.org.uk> 2023-04-12 10:04:56 +0100
commitc76c6c4ecbec0deb56a4f9e932b26866024a508f (patch)
treee6da7ee937a9e9ee7b29dcab602a24d2ee974714 /arch/arm/vfp/vfphw.S
parentARM: 9293/1: vfp: Pass successful return address via register R3 (diff)
downloadlinux-c76c6c4ecbec0deb56a4f9e932b26866024a508f.tar.gz
linux-c76c6c4ecbec0deb56a4f9e932b26866024a508f.tar.bz2
linux-c76c6c4ecbec0deb56a4f9e932b26866024a508f.zip
ARM: 9294/2: vfp: Fix broken softirq handling with instrumentation enabled
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 <ardb@kernel.org> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Tested-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'arch/arm/vfp/vfphw.S')
-rw-r--r--arch/arm/vfp/vfphw.S12
1 files changed, 6 insertions, 6 deletions
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index 60acd42e0578..4d8478264d82 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"