^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2017 Linaro Ltd. <ard.biesheuvel@linaro.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #ifndef __ASM_SIMD_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define __ASM_SIMD_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/irqflags.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/percpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/preempt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) DECLARE_PER_CPU(bool, fpsimd_context_busy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #ifdef CONFIG_KERNEL_MODE_NEON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * may_use_simd - whether it is allowable at this time to issue SIMD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * instructions or access the SIMD register file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Callers must not assume that the result remains true beyond the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * preempt_enable() or return from softirq context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static __must_check inline bool may_use_simd(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * We must make sure that the SVE has been initialized properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * before using the SIMD in kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * fpsimd_context_busy is only set while preemption is disabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * and is clear whenever preemption is enabled. Since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * this_cpu_read() is atomic w.r.t. preemption, fpsimd_context_busy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * cannot change under our feet -- if it's set we cannot be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * migrated, and if it's clear we cannot be migrated to a CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * where it is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return !in_irq() && !irqs_disabled() && !in_nmi() &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) !this_cpu_read(fpsimd_context_busy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #else /* ! CONFIG_KERNEL_MODE_NEON */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static __must_check inline bool may_use_simd(void) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #endif /* ! CONFIG_KERNEL_MODE_NEON */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #endif