Message ID | 20250324185927.1024543-2-ardb+git@google.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | ARM: Disallow kernel mode NEON when IRQs are disabled | expand |
On Mon, Mar 24, 2025 at 07:59:28PM +0100, Ard Biesheuvel wrote: > From: Ard Biesheuvel <ardb@kernel.org> > > Commit > > c79f81631142 ("ARM: 9283/1: permit non-nested kernel mode NEON in softirq context") > > relaxed the rules around the use of SIMD instructions in kernel mode on > ARM, to allow such use when serving a softirq. To avoid having to > preserve/restore kernel mode NEON state when such a softirq is taken, > softirqs are now disabled when using the NEON from task context. > > However, the fact that the softirq API does not allow unmasking of > softirqs with interrupts disabled was overlooked, resulting in a WARN() > in some cases, as reported by Guenter: > > WARNING: CPU: 0 PID: 1145 at kernel/softirq.c:369 __local_bh_enable_ip+0x118/0x194 > Call trace: > unwind_backtrace from show_stack+0x10/0x14 > show_stack from dump_stack_lvl+0x7c/0xac > dump_stack_lvl from __warn+0x7c/0x1b8 > __warn from warn_slowpath_fmt+0x19c/0x1a4 > warn_slowpath_fmt from __local_bh_enable_ip+0x118/0x194 > __local_bh_enable_ip from crc_t10dif_arch+0xd4/0xe8 > crc_t10dif_arch from crc_t10dif_wrapper+0x14/0x1c > crc_t10dif_wrapper from crc_main_test+0x178/0x360 > crc_main_test from kunit_try_run_case+0x78/0x1e0 > kunit_try_run_case from kunit_generic_run_threadfn_adapter+0x1c/0x34 > kunit_generic_run_threadfn_adapter from kthread+0x118/0x254 > kthread from ret_from_fork+0x14/0x28 > > While disabling softirqs is not really needed when running with IRQs > disabled (given that the only way a softirq can be delivered > asynchrously is over the back of an IRQ), let's not complicate this > logic more than needed, and simply disallow use of the NEON in kernel > mode when IRQs are disabled. > > Another approach might be to only disable and re-enable softirqs if IRQs > are enabled, but other than the test case above, there are no clear use > cases for doing non-trivial arithmetic processing (hence using an > accelerated SIMD implementation) with IRQs disabled. > > Reported-by: Guenter Roeck <linux@roeck-us.net> > Tested-by: Guenter Roeck <linux@roeck-us.net> > Link: https://lore.kernel.org/all/389b899f-893c-4855-9e30-d8920a5d6f91@roeck-us.net > Signed-off-by: Ard Biesheuvel <ardb@kernel.org> > --- > arch/arm/include/asm/simd.h | 3 ++- > arch/arm/vfp/vfpmodule.c | 1 + > 2 files changed, 3 insertions(+), 1 deletion(-) Reviewed-by: Eric Biggers <ebiggers@kernel.org> - Eric
diff --git a/arch/arm/include/asm/simd.h b/arch/arm/include/asm/simd.h index 82191dbd7e78..e604a9382960 100644 --- a/arch/arm/include/asm/simd.h +++ b/arch/arm/include/asm/simd.h @@ -4,5 +4,6 @@ static __must_check inline bool may_use_simd(void) { - return IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && !in_hardirq(); + return IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && !in_hardirq() + && !irqs_disabled(); } diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 7803d50b90f8..e559ad3cd148 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -877,6 +877,7 @@ void kernel_neon_begin(void) * the kernel mode NEON register contents never need to be preserved. */ BUG_ON(in_hardirq()); + BUG_ON(irqs_disabled()); cpu = __smp_processor_id(); fpexc = fmrx(FPEXC) | FPEXC_EN;