Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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 */
27static __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
40static __must_check inline bool may_use_simd(void) {
41 return false;
42}
43
44#endif /* ! CONFIG_KERNEL_MODE_NEON */
45
46DEFINE_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(_label) \
52 for (struct user_fpsimd_state __uninitialized __st; \
53 true; ({ goto _label; })) \
54 if (0) { \
55_label: break; \
56 } else scoped_guard(ksimd, &__st)
57
58#define scoped_ksimd() __scoped_ksimd(__UNIQUE_ID(label))
59
60#endif