summaryrefslogtreecommitdiffhomepage
path: root/src/compat/simd/include/linux
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2018-09-17 05:49:02 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2018-09-17 06:03:01 +0200
commitb5d6181c6f56aaaee4da1a747e84a54b769df0a6 (patch)
tree0bfc4c506d50439a8f76f3c9f2e395d05b085dde /src/compat/simd/include/linux
parent399d5bb850b0e0d0269ef14bb52720221cb526a4 (diff)
crypto: pass simd by reference
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src/compat/simd/include/linux')
-rw-r--r--src/compat/simd/include/linux/simd.h44
1 files changed, 28 insertions, 16 deletions
diff --git a/src/compat/simd/include/linux/simd.h b/src/compat/simd/include/linux/simd.h
index f31059d..1a0ecae 100644
--- a/src/compat/simd/include/linux/simd.h
+++ b/src/compat/simd/include/linux/simd.h
@@ -17,49 +17,61 @@
#endif
typedef enum {
- HAVE_NO_SIMD,
- HAVE_FULL_SIMD
+ HAVE_NO_SIMD = 1 << 0,
+ HAVE_FULL_SIMD = 1 << 1,
+ HAVE_SIMD_IN_USE = 1 << 31
} simd_context_t;
-static __must_check inline simd_context_t simd_get(void)
+static inline void simd_get(simd_context_t *ctx)
{
bool have_simd = false;
#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) && !defined(CONFIG_PREEMPT_RT_BASE)
have_simd = irq_fpu_usable();
- if (have_simd)
- kernel_fpu_begin();
#elif IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && !defined(CONFIG_PREEMPT_RT_BASE)
#if defined(CONFIG_ARM64)
have_simd = true; /* ARM64 supports NEON in any context. */
#elif defined(CONFIG_ARM)
have_simd = may_use_simd(); /* ARM doesn't support NEON in interrupt context. */
#endif
- if (have_simd)
- kernel_neon_begin();
#endif
- return have_simd ? HAVE_FULL_SIMD : HAVE_NO_SIMD;
+ *ctx = have_simd ? HAVE_FULL_SIMD : HAVE_NO_SIMD;
}
-static inline void simd_put(simd_context_t prior_context)
+static inline void simd_put(simd_context_t *ctx)
{
#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) && !defined(CONFIG_PREEMPT_RT_BASE)
- if (prior_context != HAVE_NO_SIMD)
+ if (*ctx & HAVE_SIMD_IN_USE)
kernel_fpu_end();
#elif IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && !defined(CONFIG_PREEMPT_RT_BASE)
- if (prior_context != HAVE_NO_SIMD)
+ if (*ctx & HAVE_SIMD_IN_USE)
kernel_neon_end();
#endif
+ *ctx = HAVE_NO_SIMD;
}
-static __must_check inline simd_context_t simd_relax(simd_context_t prior_context)
+static inline void simd_relax(simd_context_t *ctx)
{
#ifdef CONFIG_PREEMPT
- if (prior_context != HAVE_NO_SIMD && need_resched()) {
- simd_put(prior_context);
- return simd_get();
+ if ((*ctx & HAVE_SIMD_IN_USE) && need_resched()) {
+ simd_put(ctx);
+ simd_get(ctx);
}
#endif
- return prior_context;
+}
+
+static __must_check inline bool simd_use(simd_context_t *ctx)
+{
+ if (!(*ctx & HAVE_FULL_SIMD))
+ return false;
+ if (*ctx & HAVE_SIMD_IN_USE)
+ return true;
+#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) && !defined(CONFIG_PREEMPT_RT_BASE)
+ kernel_fpu_begin();
+#elif IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && !defined(CONFIG_PREEMPT_RT_BASE)
+ kernel_neon_begin();
+#endif
+ *ctx |= HAVE_SIMD_IN_USE;
+ return true;
}
#endif /* _WG_SIMD_H */