Add a small API for in-kernel FPU operations.

fpu_kern_enter();
	/* do FPU stuff */
	fpu_kern_leave();
This commit is contained in:
maxv 2019-11-27 06:24:33 +00:00
parent 9191368464
commit 9684bbd4f4
4 changed files with 63 additions and 13 deletions

View File

@ -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

View File

@ -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 *);

View File

@ -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 self, void *aux)
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(). */

View File

@ -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