1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright (C) 2017 Linaro Ltd. <ard.biesheuvel@linaro.org> 4 */ 5 6 #ifndef __ASM_SIMD_H 7 #define __ASM_SIMD_H 8 9 #include <linux/cleanup.h> 10 #include <linux/compiler.h> 11 #include <linux/irqflags.h> 12 #include <linux/percpu.h> 13 #include <linux/preempt.h> 14 #include <linux/types.h> 15 16 #include <asm/neon.h> 17 18 #ifdef CONFIG_KERNEL_MODE_NEON 19 20 /* 21 * may_use_simd - whether it is allowable at this time to issue SIMD 22 * instructions or access the SIMD register file 23 * 24 * Callers must not assume that the result remains true beyond the next 25 * preempt_enable() or return from softirq context. 26 */ 27 static __must_check inline bool may_use_simd(void) 28 { 29 /* 30 * We must make sure that the SVE has been initialized properly 31 * before using the SIMD in kernel. 32 */ 33 return !WARN_ON(!system_capabilities_finalized()) && 34 system_supports_fpsimd() && 35 !in_hardirq() && !in_nmi(); 36 } 37 38 #else /* ! CONFIG_KERNEL_MODE_NEON */ 39 40 static __must_check inline bool may_use_simd(void) { 41 return false; 42 } 43 44 #endif /* ! CONFIG_KERNEL_MODE_NEON */ 45 46 DEFINE_LOCK_GUARD_1(ksimd, 47 struct user_fpsimd_state, 48 kernel_neon_begin(_T->lock), 49 kernel_neon_end(_T->lock)) 50 51 #define scoped_ksimd() scoped_guard(ksimd, &(struct user_fpsimd_state){}) 52 53 #endif 54