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/d04b1fa5c54c
branches: trunk
changeset: 1005048:d04b1fa5c54c
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 df52eee36d8d -r d04b1fa5c54c 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 df52eee36d8d -r d04b1fa5c54c 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 df52eee36d8d -r d04b1fa5c54c 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 df52eee36d8d -r d04b1fa5c54c 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