Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src-draft/trunk]: src/sys/sys New functions kthread_fpu_enter/exit.
details: https://anonhg.NetBSD.org/src-all/rev/14228ccdcddb
branches: trunk
changeset: 936591:14228ccdcddb
user: Taylor R Campbell <riastradh%NetBSD.org@localhost>
date: Fri Jul 31 02:02:15 2020 +0000
description:
New functions kthread_fpu_enter/exit.
The MI definitions don't do anything but maintain a flag, but MD code
can define kthread_fpu_enter/exit_md to actually enable/disable the
FPU. (These are almost pcu_save/discard, except they apply to all
PCUs on systems that use pcu(9).)
diffstat:
share/man/man9/kthread.9 | 40 +++++++++++++++++++++++++++-
sys/kern/kern_kthread.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++
sys/kern/kern_stub.c | 4 ++
sys/sys/kthread.h | 7 ++++
sys/sys/lwp.h | 1 +
5 files changed, 120 insertions(+), 1 deletions(-)
diffs (191 lines):
diff -r d28870fa345f -r 14228ccdcddb share/man/man9/kthread.9
--- a/share/man/man9/kthread.9 Thu Jul 30 13:50:27 2020 +0000
+++ b/share/man/man9/kthread.9 Fri Jul 31 02:02:15 2020 +0000
@@ -33,7 +33,9 @@
.Sh NAME
.Nm kthread_create ,
.Nm kthread_exit ,
-.Nm kthread_join
+.Nm kthread_join ,
+.Nm kthread_fpu_enter ,
+.Nm kthread_fpu_exit
.Nd kernel threads
.Sh SYNOPSIS
.In sys/kthread.h
@@ -44,6 +46,10 @@
.Fn kthread_exit "int ecode"
.Ft int
.Fn kthread_join "lwp_t *l"
+.Ft int
+.Fn kthread_fpu_enter
+.Ft void
+.Fn kthread_fpu_exit "int s"
.Sh DESCRIPTION
Kernel threads are light-weight processes which execute entirely
within the kernel.
@@ -51,6 +57,13 @@
Any process can request the creation of a new kernel thread.
Kernel threads are not swapped out during memory congestion.
The VM space and limits are shared with proc0 (usually swapper).
+.Pp
+If the machine has any per-CPU floating-point units or SIMD vector
+units that are normally available to user threads, they can be used by
+kthreads between
+.Fn kthread_fpu_enter
+and
+.fn kthread_fpu_exit .
.Sh FUNCTIONS
.Bl -tag -width compact
.It Fn kthread_create "pri" "flags" "ci" "func" "arg" "newlp" "fmt" "..."
@@ -155,6 +168,31 @@
.Dv KTHREAD_MUSTJOIN
flag and would wait on
.Fa kthread_exit .
+.It Fn kthread_fpu_enter
+Allow the current kthread to use any machine-dependent per-CPU
+floating-point units or SIMD vector units normally available to user
+threads.
+Returns a cookie that must be passed to
+.Fn kthread_fpu_exit
+when done.
+.Pp
+Matching pairs of
+.Fn kthread_fpu_enter
+and
+.Fn kthread_fpu_exit
+may be nested.
+.It Fn kthread_fpu_exit "s"
+Restore the current kthread's access to machine-dependent per-CPU
+floating-point units or SIMD vector units to what it was before the
+call to
+.Fn kthread_fpu_enter
+that returned
+.Fa s .
+.Pp
+On the last
+.Fn kthread_fpu_exit ,
+zero all the units' registers to avoid leaking secrets \(em such units
+are often used for cryptography.
.El
.Sh RETURN VALUES
Upon successful completion,
diff -r d28870fa345f -r 14228ccdcddb sys/kern/kern_kthread.c
--- a/sys/kern/kern_kthread.c Thu Jul 30 13:50:27 2020 +0000
+++ b/sys/kern/kern_kthread.c Fri Jul 31 02:02:15 2020 +0000
@@ -34,6 +34,7 @@
__KERNEL_RCSID(0, "$NetBSD: kern_kthread.c,v 1.45 2020/01/08 17:38:42 ad Exp $");
#include <sys/param.h>
+#include <sys/cpu.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
@@ -216,3 +217,71 @@
return 0;
}
+
+/*
+ * kthread_fpu_enter()
+ *
+ * Allow the current lwp, which must be a kthread, to use the FPU.
+ * Return a cookie that must be passed to kthread_fpu_exit when
+ * done. Must be used only in thread context. Recursive -- you
+ * can call kthread_fpu_enter several times in a row as long as
+ * you pass the cookies in reverse order to kthread_fpu_exit.
+ */
+int
+kthread_fpu_enter(void)
+{
+ struct lwp *l = curlwp;
+ int s;
+
+ KASSERTMSG(!cpu_intr_p(),
+ "%s is not allowed in interrupt context", __func__);
+ KASSERTMSG(!cpu_softintr_p(),
+ "%s is not allowed in interrupt context", __func__);
+
+ /*
+ * Remember whether this thread already had FPU access, and
+ * mark this thread as having FPU access.
+ */
+ lwp_lock(l);
+ KASSERTMSG(l->l_flag & LW_SYSTEM,
+ "%s is allowed only in kthreads", __func__);
+ s = l->l_flag & LW_SYSTEM_FPU;
+ l->l_flag |= LW_SYSTEM_FPU;
+ lwp_unlock(l);
+
+ /* Take MD steps to enable the FPU if necessary. */
+ if (s == 0)
+ kthread_fpu_enter_md();
+
+ return s;
+}
+
+/*
+ * kthread_fpu_exit(s)
+ *
+ * Restore the current lwp's FPU access to what it was before the
+ * matching call to kthread_fpu_enter() that returned s. Must be
+ * used only in thread context.
+ */
+void
+kthread_fpu_exit(int s)
+{
+ struct lwp *l = curlwp;
+
+ KASSERT(s == (s & LW_SYSTEM_FPU));
+ KASSERTMSG(!cpu_intr_p(),
+ "%s is not allowed in interrupt context", __func__);
+ KASSERTMSG(!cpu_softintr_p(),
+ "%s is not allowed in interrupt context", __func__);
+
+ lwp_lock(l);
+ KASSERTMSG(l->l_flag & LW_SYSTEM,
+ "%s is allowed only in kthreads", __func__);
+ KASSERT(l->l_flag & LW_SYSTEM_FPU);
+ l->l_flag ^= s ^ LW_SYSTEM_FPU;
+ lwp_unlock(l);
+
+ /* Take MD steps to zero and disable the FPU if necessary. */
+ if (s == 0)
+ kthread_fpu_exit_md();
+}
diff -r d28870fa345f -r 14228ccdcddb sys/kern/kern_stub.c
--- a/sys/kern/kern_stub.c Thu Jul 30 13:50:27 2020 +0000
+++ b/sys/kern/kern_stub.c Fri Jul 31 02:02:15 2020 +0000
@@ -328,3 +328,7 @@
return memcmp(&t1, &t2, sizeof(t1)) == 0;
}
+
+/* Stubs for architectures with no kernel FPU access. */
+__weak_alias(kthread_fpu_enter_md, voidop);
+__weak_alias(kthread_fpu_exit_md, voidop);
diff -r d28870fa345f -r 14228ccdcddb sys/sys/kthread.h
--- a/sys/sys/kthread.h Thu Jul 30 13:50:27 2020 +0000
+++ b/sys/sys/kthread.h Fri Jul 31 02:02:15 2020 +0000
@@ -56,4 +56,11 @@
void kthread_exit(int) __dead;
int kthread_join(lwp_t *);
+int kthread_fpu_enter(void);
+void kthread_fpu_exit(int);
+
+/* Internal MD routines -- for use only by kthread_fpu_enter/exit. */
+void kthread_fpu_enter_md(void);
+void kthread_fpu_exit_md(void);
+
#endif /* _SYS_KTHREAD_H_ */
diff -r d28870fa345f -r 14228ccdcddb sys/sys/lwp.h
--- a/sys/sys/lwp.h Thu Jul 30 13:50:27 2020 +0000
+++ b/sys/sys/lwp.h Fri Jul 31 02:02:15 2020 +0000
@@ -256,6 +256,7 @@
#define LW_STIMO 0x00000040 /* Sleep timed out */
#define LW_SINTR 0x00000080 /* Sleep is interruptible. */
#define LW_SYSTEM 0x00000200 /* Kernel thread */
+#define LW_SYSTEM_FPU 0x00000400 /* Kernel thread with vector/FP enabled */
#define LW_DBGSUSPEND 0x00010000 /* Suspend by debugger */
#define LW_WSUSPEND 0x00020000 /* Suspend before return to user */
#define LW_BATCH 0x00040000 /* LWP tends to hog CPU */
Home |
Main Index |
Thread Index |
Old Index