linux/arch/arm64/include/asm/simd.h
<<
>>
Prefs
   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/compiler.h>
  10#include <linux/irqflags.h>
  11#include <linux/percpu.h>
  12#include <linux/preempt.h>
  13#include <linux/types.h>
  14
  15DECLARE_PER_CPU(bool, fpsimd_context_busy);
  16
  17#ifdef CONFIG_KERNEL_MODE_NEON
  18
  19/*
  20 * may_use_simd - whether it is allowable at this time to issue SIMD
  21 *                instructions or access the SIMD register file
  22 *
  23 * Callers must not assume that the result remains true beyond the next
  24 * preempt_enable() or return from softirq context.
  25 */
  26static __must_check inline bool may_use_simd(void)
  27{
  28        /*
  29         * We must make sure that the SVE has been initialized properly
  30         * before using the SIMD in kernel.
  31         * fpsimd_context_busy is only set while preemption is disabled,
  32         * and is clear whenever preemption is enabled. Since
  33         * this_cpu_read() is atomic w.r.t. preemption, fpsimd_context_busy
  34         * cannot change under our feet -- if it's set we cannot be
  35         * migrated, and if it's clear we cannot be migrated to a CPU
  36         * where it is set.
  37         */
  38        return !WARN_ON(!system_capabilities_finalized()) &&
  39               system_supports_fpsimd() &&
  40               !in_hardirq() && !irqs_disabled() && !in_nmi() &&
  41               !this_cpu_read(fpsimd_context_busy);
  42}
  43
  44#else /* ! CONFIG_KERNEL_MODE_NEON */
  45
  46static __must_check inline bool may_use_simd(void) {
  47        return false;
  48}
  49
  50#endif /* ! CONFIG_KERNEL_MODE_NEON */
  51
  52#endif
  53