Module Name: src Committed By: maxv Date: Wed Nov 27 06:24:33 UTC 2019
Modified Files: src/sys/arch/x86/include: cpu.h fpu.h src/sys/arch/x86/x86: cpu.c fpu.c Log Message: Add a small API for in-kernel FPU operations. fpu_kern_enter(); /* do FPU stuff */ fpu_kern_leave(); To generate a diff of this commit: cvs rdiff -u -r1.113 -r1.114 src/sys/arch/x86/include/cpu.h cvs rdiff -u -r1.19 -r1.20 src/sys/arch/x86/include/fpu.h cvs rdiff -u -r1.176 -r1.177 src/sys/arch/x86/x86/cpu.c cvs rdiff -u -r1.59 -r1.60 src/sys/arch/x86/x86/fpu.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/include/cpu.h diff -u src/sys/arch/x86/include/cpu.h:1.113 src/sys/arch/x86/include/cpu.h:1.114 --- src/sys/arch/x86/include/cpu.h:1.113 Sat Nov 23 19:40:37 2019 +++ src/sys/arch/x86/include/cpu.h Wed Nov 27 06:24:33 2019 @@ -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 @@ struct cpu_info { 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 Index: src/sys/arch/x86/include/fpu.h diff -u src/sys/arch/x86/include/fpu.h:1.19 src/sys/arch/x86/include/fpu.h:1.20 --- src/sys/arch/x86/include/fpu.h:1.19 Sat Oct 12 06:31:03 2019 +++ src/sys/arch/x86/include/fpu.h Wed Nov 27 06:24:33 2019 @@ -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_sigreset(struct lwp *); 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 *); Index: src/sys/arch/x86/x86/cpu.c diff -u src/sys/arch/x86/x86/cpu.c:1.176 src/sys/arch/x86/x86/cpu.c:1.177 --- src/sys/arch/x86/x86/cpu.c:1.176 Sat Nov 23 19:40:37 2019 +++ src/sys/arch/x86/x86/cpu.c Wed Nov 27 06:24:33 2019 @@ -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 @@ cpu_attach(device_t parent, device_t sel 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(). */ Index: src/sys/arch/x86/x86/fpu.c diff -u src/sys/arch/x86/x86/fpu.c:1.59 src/sys/arch/x86/x86/fpu.c:1.60 --- src/sys/arch/x86/x86/fpu.c:1.59 Wed Oct 30 16:32:04 2019 +++ src/sys/arch/x86/x86/fpu.c Wed Nov 27 06:24:33 2019 @@ -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 @@ fpu_lwp_area(struct lwp *l) 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 @@ fpu_save(void) 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 @@ fpu_lwp_abandon(struct lwp *l) /* -------------------------------------------------------------------------- */ +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