Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src-draft/trunk]: src/sys/arch/aarch64 Draft fpu_kthread_enter/leave for aar...
details: https://anonhg.NetBSD.org/src-all/rev/5f0c9efc2bac
branches: trunk
changeset: 934741:5f0c9efc2bac
user: Taylor R Campbell <riastradh%NetBSD.org@localhost>
date: Wed Jun 17 18:29:42 2020 +0000
description:
Draft fpu_kthread_enter/leave for aarch64.
diffstat:
sys/arch/aarch64/aarch64/fpu.c | 63 ++++++++++++++++++++++++++++++++++++++++-
sys/arch/aarch64/include/fpu.h | 3 +
sys/arch/aarch64/include/proc.h | 1 +
3 files changed, 66 insertions(+), 1 deletions(-)
diffs (114 lines):
diff -r e7941432a3cd -r 5f0c9efc2bac sys/arch/aarch64/aarch64/fpu.c
--- a/sys/arch/aarch64/aarch64/fpu.c Thu Jun 04 03:23:00 2020 +0000
+++ b/sys/arch/aarch64/aarch64/fpu.c Wed Jun 17 18:29:42 2020 +0000
@@ -175,6 +175,59 @@
__asm __volatile ("isb");
}
+static const struct fpreg zero_fpreg;
+
+int
+fpu_kthread_enter(void)
+{
+ struct lwp *l = curlwp;
+ int system_fpu = l->l_md.md_flags & MDL_SYSTEM_FPU;
+
+ KASSERTMSG(l->l_flag & LW_SYSTEM,
+ "fpu_kthread_enter is allowed only in kthreads");
+ KASSERTMSG(curcpu()->ci_kfpu_spl == -1,
+ "fpu_kthread_enter is not allowed between fpu_kern_enter/leave");
+
+ if (!system_fpu) {
+ /*
+ * Notify the FPU fault handler to save the FPU state
+ * for us.
+ */
+ l->l_md.md_flags |= MDL_SYSTEM_FPU;
+
+ /* Enable the FPU. */
+ fpu_state_load(l, 0);
+ }
+
+ return system_fpu;
+}
+
+void
+fpu_kthread_leave(int system_fpu)
+{
+ struct lwp *l = curlwp;
+
+ KASSERTMSG(l->l_flag & LW_SYSTEM,
+ "fpu_kthread_leave is allowed only in kthreads");
+ KASSERTMSG(l->l_md.md_flags & MDL_SYSTEM_FPU,
+ "fpu_kthread_leave without fpu_kthread_enter");
+
+ if (!system_fpu) {
+ /*
+ * Zero the fpu registers; otherwise we might leak
+ * secrets through Spectre-class attacks to userland,
+ * even if there are no bugs in fpu state management.
+ */
+ load_fpregs(&zero_fpreg);
+
+ /* Disable the FPU. */
+ fpu_state_release(l);
+
+ /* Stop asking to save our FPU state. */
+ l->l_md.md_flags &= ~MDL_SYSTEM_FPU;
+ }
+}
+
void
fpu_kern_enter(void)
{
@@ -182,6 +235,10 @@
struct cpu_info *ci;
int s;
+ /* Nothing needed if we're in a kthread with FPU enabled. */
+ if (l->l_md.md_flags & MDL_SYSTEM_FPU)
+ return;
+
/*
* Block all interrupts. We must block preemption since -- if
* this is a user thread -- there is nowhere to save the kernel
@@ -214,10 +271,14 @@
void
fpu_kern_leave(void)
{
- static const struct fpreg zero_fpreg;
+ struct lwp *l = curlwp;
struct cpu_info *ci = curcpu();
int s;
+ /* Nothing needed if we're in a kthread with FPU enabled. */
+ if (l->l_md.md_flags & MDL_SYSTEM_FPU)
+ return;
+
KASSERT(ci->ci_cpl == IPL_HIGH);
KASSERT(ci->ci_kfpu_spl != -1);
diff -r e7941432a3cd -r 5f0c9efc2bac sys/arch/aarch64/include/fpu.h
--- a/sys/arch/aarch64/include/fpu.h Thu Jun 04 03:23:00 2020 +0000
+++ b/sys/arch/aarch64/include/fpu.h Wed Jun 17 18:29:42 2020 +0000
@@ -29,6 +29,9 @@
#ifndef _AARCH64_FPU_H_
#define _AARCH64_FPU_H_
+int fpu_kthread_enter(void);
+void fpu_kthread_leave(int);
+
void fpu_kern_enter(void);
void fpu_kern_leave(void);
diff -r e7941432a3cd -r 5f0c9efc2bac sys/arch/aarch64/include/proc.h
--- a/sys/arch/aarch64/include/proc.h Thu Jun 04 03:23:00 2020 +0000
+++ b/sys/arch/aarch64/include/proc.h Wed Jun 17 18:29:42 2020 +0000
@@ -43,6 +43,7 @@
struct trapframe *md_utf;
uint64_t md_cpacr;
uint32_t md_flags;
+#define MDL_SYSTEM_FPU __BIT(0)
uint64_t md_ia_kern[2]; /* APIAKey{Lo,Hi}_EL1 used in the kernel */
uint64_t md_ia_user[2]; /* APIAKey{Lo,Hi}_EL1 used in user-process */
Home |
Main Index |
Thread Index |
Old Index