1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright (C) 2017 Linaro Ltd. <ard.biesheuvel@linaro.org> 4 * Copyright (C) 2023 SiFive 5 */ 6 7 #ifndef __ASM_SIMD_H 8 #define __ASM_SIMD_H 9 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 #include <linux/thread_info.h> 16 17 #include <asm/vector.h> 18 19 #ifdef CONFIG_RISCV_ISA_V 20 /* 21 * may_use_simd - whether it is allowable at this time to issue vector 22 * instructions or access the vector 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 * RISCV_KERNEL_MODE_V is only set while preemption is disabled, 31 * and is clear whenever preemption is enabled. 32 */ 33 if (in_hardirq() || in_nmi()) 34 return false; 35 36 /* 37 * Nesting is achieved in preempt_v by spreading the control for 38 * preemptible and non-preemptible kernel-mode Vector into two fields. 39 * Only non-preempt_v can nest on top of preempt_v, if non-preempt_v is 40 * unavailable, then preempt_v is not allowed. 41 */ 42 return !(riscv_v_flags() & RISCV_KERNEL_MODE_V); 43 } 44 45 #else /* ! CONFIG_RISCV_ISA_V */ 46 47 static __must_check inline bool may_use_simd(void) 48 { 49 return false; 50 } 51 52 #endif /* ! CONFIG_RISCV_ISA_V */ 53 54 #endif 55