Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/x86 Add a small API for in-kernel FPU operations.



details:   https://anonhg.NetBSD.org/src/rev/4fbbcdd455a1
branches:  trunk
changeset: 461453:4fbbcdd455a1
user:      maxv <maxv%NetBSD.org@localhost>
date:      Wed Nov 27 06:24:33 2019 +0000

description:
Add a small API for in-kernel FPU operations.

        fpu_kern_enter();
        /* do FPU stuff */
        fpu_kern_leave();

diffstat:

 sys/arch/x86/include/cpu.h |   4 ++-
 sys/arch/x86/include/fpu.h |   5 ++-
 sys/arch/x86/x86/cpu.c     |   5 ++-
 sys/arch/x86/x86/fpu.c     |  62 +++++++++++++++++++++++++++++++++++++++------
 4 files changed, 63 insertions(+), 13 deletions(-)

diffs (161 lines):

diff -r 101a96b95739 -r 4fbbcdd455a1 sys/arch/x86/include/cpu.h
--- a/sys/arch/x86/include/cpu.h        Wed Nov 27 05:50:26 2019 +0000
+++ b/sys/arch/x86/include/cpu.h        Wed Nov 27 06:24:33 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.h,v 1.113 2019/11/23 19:40:37 ad Exp $     */
+/*     $NetBSD: cpu.h,v 1.114 2019/11/27 06:24:33 maxv Exp $   */
 
 /*
  * Copyright (c) 1990 The Regents of the University of California.
@@ -139,6 +139,8 @@
        uintptr_t ci_pmap_data[64 / sizeof(uintptr_t)];
        struct kcpuset *ci_tlb_cpuset;
 
+       int ci_kfpu_spl;
+
 #ifndef XENPV
        struct intrsource *ci_isources[MAX_INTR_SOURCES];
 #endif
diff -r 101a96b95739 -r 4fbbcdd455a1 sys/arch/x86/include/fpu.h
--- a/sys/arch/x86/include/fpu.h        Wed Nov 27 05:50:26 2019 +0000
+++ b/sys/arch/x86/include/fpu.h        Wed Nov 27 06:24:33 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu.h,v 1.19 2019/10/12 06:31:03 maxv Exp $    */
+/*     $NetBSD: fpu.h,v 1.20 2019/11/27 06:24:33 maxv Exp $    */
 
 #ifndef        _X86_FPU_H_
 #define        _X86_FPU_H_
@@ -30,6 +30,9 @@
 void fpu_lwp_fork(struct lwp *, struct lwp *);
 void fpu_lwp_abandon(struct lwp *l);
 
+void fpu_kern_enter(void);
+void fpu_kern_leave(void);
+
 void process_write_fpregs_xmm(struct lwp *, const struct fxsave *);
 void process_write_fpregs_s87(struct lwp *, const struct save87 *);
 
diff -r 101a96b95739 -r 4fbbcdd455a1 sys/arch/x86/x86/cpu.c
--- a/sys/arch/x86/x86/cpu.c    Wed Nov 27 05:50:26 2019 +0000
+++ b/sys/arch/x86/x86/cpu.c    Wed Nov 27 06:24:33 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.c,v 1.176 2019/11/23 19:40:37 ad Exp $     */
+/*     $NetBSD: cpu.c,v 1.177 2019/11/27 06:24:33 maxv Exp $   */
 
 /*
  * Copyright (c) 2000-2012 NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.176 2019/11/23 19:40:37 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.177 2019/11/27 06:24:33 maxv Exp $");
 
 #include "opt_ddb.h"
 #include "opt_mpbios.h"                /* for MPDEBUG */
@@ -376,6 +376,7 @@
        ci->ci_acpiid = caa->cpu_id;
        ci->ci_cpuid = caa->cpu_number;
        ci->ci_func = caa->cpu_func;
+       ci->ci_kfpu_spl = -1;
        aprint_normal("\n");
 
        /* Must be before mi_cpu_attach(). */
diff -r 101a96b95739 -r 4fbbcdd455a1 sys/arch/x86/x86/fpu.c
--- a/sys/arch/x86/x86/fpu.c    Wed Nov 27 05:50:26 2019 +0000
+++ b/sys/arch/x86/x86/fpu.c    Wed Nov 27 06:24:33 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu.c,v 1.59 2019/10/30 16:32:04 maxv Exp $    */
+/*     $NetBSD: fpu.c,v 1.60 2019/11/27 06:24:33 maxv Exp $    */
 
 /*
  * Copyright (c) 2008, 2019 The NetBSD Foundation, Inc.  All
@@ -96,7 +96,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.59 2019/10/30 16:32:04 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.60 2019/11/27 06:24:33 maxv Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -146,14 +146,9 @@
        return area;
 }
 
-/*
- * Bring curlwp's FPU state in memory. It will get installed back in the CPU
- * when returning to userland.
- */
-void
-fpu_save(void)
+static inline void
+fpu_save_lwp(struct lwp *l)
 {
-       struct lwp *l = curlwp;
        struct pcb *pcb = lwp_getpcb(l);
        union savefpu *area = &pcb->pcb_savefpu;
 
@@ -166,6 +161,16 @@
        kpreempt_enable();
 }
 
+/*
+ * Bring curlwp's FPU state in memory. It will get installed back in the CPU
+ * when returning to userland.
+ */
+void
+fpu_save(void)
+{
+       fpu_save_lwp(curlwp);
+}
+
 void
 fpuinit(struct cpu_info *ci)
 {
@@ -338,6 +343,45 @@
 
 /* -------------------------------------------------------------------------- */
 
+void
+fpu_kern_enter(void)
+{
+       struct lwp *l = curlwp;
+       struct cpu_info *ci;
+       int s;
+
+       s = splhigh();
+
+       ci = curcpu();
+       KASSERT(ci->ci_kfpu_spl == -1);
+       ci->ci_kfpu_spl = s;
+
+       /*
+        * If we are in a softint and have a pinned lwp, the fpu state is that
+        * of the pinned lwp, so save it there.
+        */
+       if ((l->l_pflag & LP_INTR) && (l->l_switchto != NULL)) {
+               fpu_save_lwp(l->l_switchto);
+       } else {
+               fpu_save_lwp(l);
+       }
+}
+
+void
+fpu_kern_leave(void)
+{
+       struct cpu_info *ci = curcpu();
+       int s;
+
+       KASSERT(ci->ci_ilevel == IPL_HIGH);
+       KASSERT(ci->ci_kfpu_spl != -1);
+       s = ci->ci_kfpu_spl;
+       ci->ci_kfpu_spl = -1;
+       splx(s);
+}
+
+/* -------------------------------------------------------------------------- */
+
 /*
  * The following table is used to ensure that the FPE_... value
  * that is passed as a trapcode to the signal handler of the user



Home | Main Index | Thread Index | Old Index