xref: /linux/arch/arm64/include/asm/simd.h (revision 7fc2cd2e4b398c57c9cf961cfea05eadbf34c05c)
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