aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/linuxkpi/common/src/linux_fpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/linuxkpi/common/src/linux_fpu.c')
-rw-r--r--sys/compat/linuxkpi/common/src/linux_fpu.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/sys/compat/linuxkpi/common/src/linux_fpu.c b/sys/compat/linuxkpi/common/src/linux_fpu.c
index 976e55e68ca1..08f7e075d827 100644
--- a/sys/compat/linuxkpi/common/src/linux_fpu.c
+++ b/sys/compat/linuxkpi/common/src/linux_fpu.c
@@ -30,21 +30,44 @@
#include <sys/proc.h>
#include <sys/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/fpu/api.h>
+
+#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
+
#include <machine/fpu.h>
-struct fpu_kern_ctx *__lkpi_fpu_ctx;
-unsigned int __lkpi_fpu_ctx_level = 0;
+/*
+ * Technically the Linux API isn't supposed to allow nesting sections
+ * either, but currently used versions of GPU drivers rely on nesting
+ * working, so we only enter the section on the outermost level.
+ */
+
+void
+lkpi_kernel_fpu_begin(void)
+{
+ if ((current->fpu_ctx_level)++ == 0)
+ fpu_kern_enter(curthread, NULL, FPU_KERN_NOCTX);
+}
+
+void
+lkpi_kernel_fpu_end(void)
+{
+ if (--(current->fpu_ctx_level) == 0)
+ fpu_kern_leave(curthread, NULL);
+}
+
+#else
-static void
-linux_fpu_init(void *arg __unused)
+void
+lkpi_kernel_fpu_begin(void)
{
- __lkpi_fpu_ctx = fpu_kern_alloc_ctx(0);
}
-SYSINIT(linux_fpu, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_fpu_init, NULL);
-static void
-linux_fpu_uninit(void *arg __unused)
+void
+lkpi_kernel_fpu_end(void)
{
- fpu_kern_free_ctx(__lkpi_fpu_ctx);
}
-SYSUNINIT(linux_fpu, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_fpu_uninit, NULL);
+
+#endif