Module Name: src
Committed By: martin
Date: Sat Jun 23 11:39:02 UTC 2018
Modified Files:
src/sys/arch/amd64/amd64 [netbsd-8]: locore.S
src/sys/arch/i386/i386 [netbsd-8]: locore.S
src/sys/arch/x86/include [netbsd-8]: cpu.h fpu.h
src/sys/arch/x86/x86 [netbsd-8]: fpu.c identcpu.c vm_machdep.c
x86_machdep.c
Log Message:
Pull up the following, via patch, requested by maxv in ticket #897:
sys/arch/amd64/amd64/locore.S 1.166 (patch)
sys/arch/i386/i386/locore.S 1.157 (patch)
sys/arch/x86/include/cpu.h 1.92 (patch)
sys/arch/x86/include/fpu.h 1.9 (patch)
sys/arch/x86/x86/fpu.c 1.33-1.39 (patch)
sys/arch/x86/x86/identcpu.c 1.72 (patch)
sys/arch/x86/x86/vm_machdep.c 1.34 (patch)
sys/arch/x86/x86/x86_machdep.c 1.116,1.117 (patch)
Support eager fpu switch, to work around INTEL-SA-00145.
Provide a sysctl machdep.fpu_eager, which gets automatically
initialized to 1 on affected CPUs.
To generate a diff of this commit:
cvs rdiff -u -r1.123.6.6 -r1.123.6.7 src/sys/arch/amd64/amd64/locore.S
cvs rdiff -u -r1.145.6.3 -r1.145.6.4 src/sys/arch/i386/i386/locore.S
cvs rdiff -u -r1.71.2.6 -r1.71.2.7 src/sys/arch/x86/include/cpu.h
cvs rdiff -u -r1.6 -r1.6.28.1 src/sys/arch/x86/include/fpu.h
cvs rdiff -u -r1.12.8.1 -r1.12.8.2 src/sys/arch/x86/x86/fpu.c
cvs rdiff -u -r1.55.2.3 -r1.55.2.4 src/sys/arch/x86/x86/identcpu.c
cvs rdiff -u -r1.28.6.3 -r1.28.6.4 src/sys/arch/x86/x86/vm_machdep.c
cvs rdiff -u -r1.91.4.3 -r1.91.4.4 src/sys/arch/x86/x86/x86_machdep.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/amd64/amd64/locore.S
diff -u src/sys/arch/amd64/amd64/locore.S:1.123.6.6 src/sys/arch/amd64/amd64/locore.S:1.123.6.7
--- src/sys/arch/amd64/amd64/locore.S:1.123.6.6 Sat May 5 15:00:29 2018
+++ src/sys/arch/amd64/amd64/locore.S Sat Jun 23 11:39:01 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.123.6.6 2018/05/05 15:00:29 martin Exp $ */
+/* $NetBSD: locore.S,v 1.123.6.7 2018/06/23 11:39:01 martin Exp $ */
/*
* Copyright-o-rama!
@@ -1094,6 +1094,20 @@ skip_save:
popq %rdx
#endif
+#ifndef XEN
+ /* RDI/RSI got clobbered. */
+ movq %r13,%rdi
+ movq %r12,%rsi
+
+ pushq %rdx
+ movb _C_LABEL(x86_fpu_eager),%dl
+ testb %dl,%dl
+ jz .Lno_eagerfpu
+ callq _C_LABEL(fpu_eagerswitch)
+.Lno_eagerfpu:
+ popq %rdx
+#endif
+
/* Switch to newlwp's stack. */
movq L_PCB(%r12),%r14
movq PCB_RSP(%r14),%rsp
Index: src/sys/arch/i386/i386/locore.S
diff -u src/sys/arch/i386/i386/locore.S:1.145.6.3 src/sys/arch/i386/i386/locore.S:1.145.6.4
--- src/sys/arch/i386/i386/locore.S:1.145.6.3 Tue Mar 13 15:47:44 2018
+++ src/sys/arch/i386/i386/locore.S Sat Jun 23 11:39:02 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.145.6.3 2018/03/13 15:47:44 martin Exp $ */
+/* $NetBSD: locore.S,v 1.145.6.4 2018/06/23 11:39:02 martin Exp $ */
/*
* Copyright-o-rama!
@@ -128,7 +128,7 @@
*/
#include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.145.6.3 2018/03/13 15:47:44 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.145.6.4 2018/06/23 11:39:02 martin Exp $");
#include "opt_compat_oldboot.h"
#include "opt_copy_symtab.h"
@@ -1089,6 +1089,19 @@ ENTRY(cpu_switchto)
movl %ebp,PCB_EBP(%eax)
skip_save:
+#ifndef XEN
+ pushl %edx
+ movb _C_LABEL(x86_fpu_eager),%dl
+ testb %dl,%dl
+ jz .Lno_eagerfpu
+ pushl %edi
+ pushl %esi
+ call _C_LABEL(fpu_eagerswitch)
+ addl $8,%esp
+.Lno_eagerfpu:
+ popl %edx
+#endif
+
/* Switch to newlwp's stack. */
movl L_PCB(%edi),%ebx
movl PCB_EBP(%ebx),%ebp
Index: src/sys/arch/x86/include/cpu.h
diff -u src/sys/arch/x86/include/cpu.h:1.71.2.6 src/sys/arch/x86/include/cpu.h:1.71.2.7
--- src/sys/arch/x86/include/cpu.h:1.71.2.6 Sat Jun 9 15:12:21 2018
+++ src/sys/arch/x86/include/cpu.h Sat Jun 23 11:39:02 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.71.2.6 2018/06/09 15:12:21 martin Exp $ */
+/* $NetBSD: cpu.h,v 1.71.2.7 2018/06/23 11:39:02 martin Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -424,6 +424,7 @@ extern int x86_fpu_save;
#define FPU_SAVE_XSAVEOPT 3
extern unsigned int x86_fpu_save_size;
extern uint64_t x86_xsave_features;
+extern bool x86_fpu_eager;
extern void (*x86_cpu_idle)(void);
#define cpu_idle() (*x86_cpu_idle)()
Index: src/sys/arch/x86/include/fpu.h
diff -u src/sys/arch/x86/include/fpu.h:1.6 src/sys/arch/x86/include/fpu.h:1.6.28.1
--- src/sys/arch/x86/include/fpu.h:1.6 Tue Feb 25 22:16:52 2014
+++ src/sys/arch/x86/include/fpu.h Sat Jun 23 11:39:02 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu.h,v 1.6 2014/02/25 22:16:52 dsl Exp $ */
+/* $NetBSD: fpu.h,v 1.6.28.1 2018/06/23 11:39:02 martin Exp $ */
#ifndef _X86_FPU_H_
#define _X86_FPU_H_
@@ -15,6 +15,8 @@ void fpuinit(struct cpu_info *);
void fpusave_lwp(struct lwp *, bool);
void fpusave_cpu(bool);
+void fpu_eagerswitch(struct lwp *, struct lwp *);
+
void fpu_set_default_cw(struct lwp *, unsigned int);
void fputrap(struct trapframe *);
Index: src/sys/arch/x86/x86/fpu.c
diff -u src/sys/arch/x86/x86/fpu.c:1.12.8.1 src/sys/arch/x86/x86/fpu.c:1.12.8.2
--- src/sys/arch/x86/x86/fpu.c:1.12.8.1 Thu Dec 21 19:33:15 2017
+++ src/sys/arch/x86/x86/fpu.c Sat Jun 23 11:39:02 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu.c,v 1.12.8.1 2017/12/21 19:33:15 snj Exp $ */
+/* $NetBSD: fpu.c,v 1.12.8.2 2018/06/23 11:39:02 martin Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc. All
@@ -96,7 +96,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.12.8.1 2017/12/21 19:33:15 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.12.8.2 2018/06/23 11:39:02 martin Exp $");
#include "opt_multiprocessor.h"
@@ -107,6 +107,8 @@ __KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.12
#include <sys/file.h>
#include <sys/proc.h>
#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/xcall.h>
#include <machine/cpu.h>
#include <machine/intr.h>
@@ -125,6 +127,8 @@ __KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.12
#define stts() HYPERVISOR_fpu_taskswitch(1)
#endif
+bool x86_fpu_eager __read_mostly = false;
+
static inline union savefpu *
process_fpframe(struct lwp *lwp)
{
@@ -228,6 +232,89 @@ fpuinit(struct cpu_info *ci)
}
static void
+fpu_clear_amd(void)
+{
+ /*
+ * AMD FPUs do not restore FIP, FDP, and FOP on fxrstor and xrstor
+ * when FSW.ES=0, leaking other threads' execution history.
+ *
+ * Clear them manually by loading a zero (fldummy). We do this
+ * unconditionally, regardless of FSW.ES.
+ *
+ * Before that, clear the ES bit in the x87 status word if it is
+ * currently set, in order to avoid causing a fault in the
+ * upcoming load.
+ *
+ * Newer generations of AMD CPUs have CPUID_Fn80000008_EBX[2],
+ * which indicates that FIP/FDP/FOP are restored (same behavior
+ * as Intel). We're not using it though.
+ */
+ if (fngetsw() & 0x80)
+ fnclex();
+ fldummy();
+}
+
+static void
+fpu_save(struct lwp *l)
+{
+ struct pcb *pcb = lwp_getpcb(l);
+
+ if (i386_use_fxsave) {
+ if (x86_xsave_features != 0)
+ xsave(&pcb->pcb_savefpu, x86_xsave_features);
+ else
+ fxsave(&pcb->pcb_savefpu);
+ } else {
+ fnsave(&pcb->pcb_savefpu);
+ }
+}
+
+static void
+fpu_restore(struct lwp *l)
+{
+ struct pcb *pcb = lwp_getpcb(l);
+
+ if (i386_use_fxsave) {
+ if (x86_xsave_features != 0) {
+ xrstor(&pcb->pcb_savefpu, x86_xsave_features);
+ } else {
+ fpu_clear_amd();
+ fxrstor(&pcb->pcb_savefpu);
+ }
+ } else {
+ frstor(&pcb->pcb_savefpu);
+ }
+}
+
+static void
+fpu_eagerrestore(struct lwp *l)
+{
+ struct pcb *pcb = lwp_getpcb(l);
+ struct cpu_info *ci = curcpu();
+
+ clts();
+ KASSERT(ci->ci_fpcurlwp == NULL);
+ KASSERT(pcb->pcb_fpcpu == NULL);
+ ci->ci_fpcurlwp = l;
+ pcb->pcb_fpcpu = ci;
+ fpu_restore(l);
+}
+
+void
+fpu_eagerswitch(struct lwp *oldlwp, struct lwp *newlwp)
+{
+ int s;
+
+ s = splhigh();
+ fpusave_cpu(true);
+ if (!(newlwp->l_flag & LW_SYSTEM))
+ fpu_eagerrestore(newlwp);
+ splx(s);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void
send_sigill(void *rip)
{
/* No fpu (486SX) - send SIGILL */
@@ -358,6 +445,11 @@ fpudna(struct trapframe *frame)
pcb = lwp_getpcb(l);
fl = ci->ci_fpcurlwp;
if (fl != NULL) {
+ if (__predict_false(x86_fpu_eager)) {
+ panic("%s: FPU busy with EagerFPU enabled",
+ __func__);
+ }
+
/*
* It seems we can get here on Xen even if we didn't
* switch lwp. In this case do nothing
@@ -373,6 +465,11 @@ fpudna(struct trapframe *frame)
/* Save our state if on a remote CPU. */
if (pcb->pcb_fpcpu != NULL) {
+ if (__predict_false(x86_fpu_eager)) {
+ panic("%s: LWP busy with EagerFPU enabled",
+ __func__);
+ }
+
/* Explicitly disable preemption before dropping spl. */
kpreempt_disable();
splx(s);
@@ -394,28 +491,7 @@ fpudna(struct trapframe *frame)
ci->ci_fpcurlwp = l;
pcb->pcb_fpcpu = ci;
- if (i386_use_fxsave) {
- if (x86_xsave_features != 0) {
- xrstor(&pcb->pcb_savefpu, x86_xsave_features);
- } else {
- /*
- * AMD FPU's do not restore FIP, FDP, and FOP on
- * fxrstor, leaking other process's execution history.
- * Clear them manually by loading a zero.
- *
- * Clear the ES bit in the x87 status word if it is
- * currently set, in order to avoid causing a fault
- * in the upcoming load.
- */
- if (fngetsw() & 0x80)
- fnclex();
- fldummy();
-
- fxrstor(&pcb->pcb_savefpu);
- }
- } else {
- frstor(&pcb->pcb_savefpu);
- }
+ fpu_restore(l);
KASSERT(ci == curcpu());
splx(s);
@@ -442,14 +518,7 @@ fpusave_cpu(bool save)
if (save) {
clts();
- if (i386_use_fxsave) {
- if (x86_xsave_features != 0)
- xsave(&pcb->pcb_savefpu, x86_xsave_features);
- else
- fxsave(&pcb->pcb_savefpu);
- } else {
- fnsave(&pcb->pcb_savefpu);
- }
+ fpu_save(l);
}
stts();
@@ -516,17 +585,28 @@ fpu_set_default_cw(struct lwp *l, unsign
fpu_save->sv_os.fxo_dflt_cw = x87_cw;
}
-/*
- * Exec needs to clear the fpu save area to avoid leaking info from the
- * old process to userspace.
- */
void
fpu_save_area_clear(struct lwp *l, unsigned int x87_cw)
{
union savefpu *fpu_save;
+ struct pcb *pcb __diagused;
+ int s;
- fpusave_lwp(l, false);
+ KASSERT(l == curlwp);
+ KASSERT((l->l_flag & LW_SYSTEM) == 0);
fpu_save = process_fpframe(l);
+ pcb = lwp_getpcb(l);
+
+ s = splhigh();
+ if (x86_fpu_eager) {
+ KASSERT(pcb->pcb_fpcpu == NULL ||
+ pcb->pcb_fpcpu == curcpu());
+ fpusave_cpu(false);
+ } else {
+ splx(s);
+ fpusave_lwp(l, false);
+ }
+ KASSERT(pcb->pcb_fpcpu == NULL);
if (i386_use_fxsave) {
memset(&fpu_save->sv_xmm, 0, sizeof(fpu_save->sv_xmm));
@@ -539,6 +619,11 @@ fpu_save_area_clear(struct lwp *l, unsig
fpu_save->sv_87.s87_cw = x87_cw;
}
fpu_save->sv_os.fxo_dflt_cw = x87_cw;
+
+ if (x86_fpu_eager) {
+ fpu_eagerrestore(l);
+ splx(s);
+ }
}
/* For signal handlers the register values don't matter */
@@ -572,6 +657,8 @@ fpu_save_area_fork(struct pcb *pcb2, con
if (extra > 0)
memcpy(pcb2 + 1, pcb1 + 1, extra);
+
+ KASSERT(pcb2->pcb_fpcpu == NULL);
}
@@ -651,3 +738,110 @@ process_read_fpregs_s87(struct lwp *l, s
memcpy(fpregs, &fpu_save->sv_87, sizeof(fpu_save->sv_87));
}
}
+
+/* -------------------------------------------------------------------------- */
+
+static volatile unsigned long eagerfpu_cpu_barrier1 __cacheline_aligned;
+static volatile unsigned long eagerfpu_cpu_barrier2 __cacheline_aligned;
+
+static void
+eager_change_cpu(void *arg1, void *arg2)
+{
+ struct cpu_info *ci = curcpu();
+ bool enabled = (bool)arg1;
+ int s;
+
+ s = splhigh();
+
+ /* Rendez-vous 1. */
+ atomic_dec_ulong(&eagerfpu_cpu_barrier1);
+ while (atomic_cas_ulong(&eagerfpu_cpu_barrier1, 0, 0) != 0) {
+ x86_pause();
+ }
+
+ fpusave_cpu(true);
+ if (ci == &cpu_info_primary) {
+ x86_fpu_eager = enabled;
+ }
+
+ /* Rendez-vous 2. */
+ atomic_dec_ulong(&eagerfpu_cpu_barrier2);
+ while (atomic_cas_ulong(&eagerfpu_cpu_barrier2, 0, 0) != 0) {
+ x86_pause();
+ }
+
+ splx(s);
+}
+
+static int
+eager_change(bool enabled)
+{
+ struct cpu_info *ci = NULL;
+ CPU_INFO_ITERATOR cii;
+ uint64_t xc;
+
+ mutex_enter(&cpu_lock);
+
+ /*
+ * We expect all the CPUs to be online.
+ */
+ for (CPU_INFO_FOREACH(cii, ci)) {
+ struct schedstate_percpu *spc = &ci->ci_schedstate;
+ if (spc->spc_flags & SPCF_OFFLINE) {
+ printf("[!] cpu%d offline, EagerFPU not changed\n",
+ cpu_index(ci));
+ mutex_exit(&cpu_lock);
+ return EOPNOTSUPP;
+ }
+ }
+
+ /* Initialize the barriers */
+ eagerfpu_cpu_barrier1 = ncpu;
+ eagerfpu_cpu_barrier2 = ncpu;
+
+ printf("[+] %s EagerFPU...",
+ enabled ? "Enabling" : "Disabling");
+ xc = xc_broadcast(0, eager_change_cpu,
+ (void *)enabled, NULL);
+ xc_wait(xc);
+ printf(" done!\n");
+
+ mutex_exit(&cpu_lock);
+
+ return 0;
+}
+
+static int
+sysctl_machdep_fpu_eager(SYSCTLFN_ARGS)
+{
+ struct sysctlnode node;
+ int error;
+ bool val;
+
+ val = *(bool *)rnode->sysctl_data;
+
+ node = *rnode;
+ node.sysctl_data = &val;
+
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (error != 0 || newp == NULL)
+ return error;
+
+ if (val == x86_fpu_eager)
+ return 0;
+ return eager_change(val);
+}
+
+void sysctl_eagerfpu_init(struct sysctllog **);
+
+void
+sysctl_eagerfpu_init(struct sysctllog **clog)
+{
+ sysctl_createv(clog, 0, NULL, NULL,
+ CTLFLAG_READWRITE,
+ CTLTYPE_BOOL, "fpu_eager",
+ SYSCTL_DESCR("Whether the kernel uses Eager FPU Switch"),
+ sysctl_machdep_fpu_eager, 0,
+ &x86_fpu_eager, 0,
+ CTL_MACHDEP, CTL_CREATE, CTL_EOL);
+}
Index: src/sys/arch/x86/x86/identcpu.c
diff -u src/sys/arch/x86/x86/identcpu.c:1.55.2.3 src/sys/arch/x86/x86/identcpu.c:1.55.2.4
--- src/sys/arch/x86/x86/identcpu.c:1.55.2.3 Sun Apr 1 08:51:47 2018
+++ src/sys/arch/x86/x86/identcpu.c Sat Jun 23 11:39:02 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: identcpu.c,v 1.55.2.3 2018/04/01 08:51:47 martin Exp $ */
+/* $NetBSD: identcpu.c,v 1.55.2.4 2018/06/23 11:39:02 martin Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.55.2.3 2018/04/01 08:51:47 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.55.2.4 2018/06/23 11:39:02 martin Exp $");
#include "opt_xen.h"
@@ -730,11 +730,59 @@ cpu_probe_old_fpu(struct cpu_info *ci)
}
#endif
+#ifndef XEN
+static void
+cpu_probe_fpu_leak(struct cpu_info *ci)
+{
+ /*
+ * INTEL-SA-00145. Affected CPUs are from Family 6.
+ */
+ if (cpu_vendor != CPUVENDOR_INTEL) {
+ return;
+ }
+ if (CPUID_TO_FAMILY(ci->ci_signature) != 6) {
+ return;
+ }
+
+ switch (CPUID_TO_MODEL(ci->ci_signature)) {
+ /* Atom CPUs are not vulnerable. */
+ case 0x1c: /* Pineview */
+ case 0x26: /* Lincroft */
+ case 0x27: /* Penwell */
+ case 0x35: /* Cloverview */
+ case 0x36: /* Cedarview */
+ case 0x37: /* Baytrail / Valleyview (Silvermont) */
+ case 0x4d: /* Avaton / Rangely (Silvermont) */
+ case 0x4c: /* Cherrytrail / Brasswell */
+ case 0x4a: /* Merrifield */
+ case 0x5a: /* Moorefield */
+ case 0x5c: /* Goldmont */
+ case 0x5f: /* Denverton */
+ case 0x7a: /* Gemini Lake */
+ break;
+
+ /* Knights CPUs are not vulnerable. */
+ case 0x57: /* Knights Landing */
+ case 0x85: /* Knights Mill */
+ break;
+
+ /* The rest is vulnerable. */
+ default:
+ x86_fpu_eager = true;
+ break;
+ }
+}
+#endif
+
static void
cpu_probe_fpu(struct cpu_info *ci)
{
u_int descs[4];
+#ifndef XEN
+ cpu_probe_fpu_leak(ci);
+#endif
+
#ifdef i386 /* amd64 always has fxsave, sse and sse2 */
/* If we have FXSAVE/FXRESTOR, use them. */
if ((ci->ci_feat_val[0] & CPUID_FXSR) == 0) {
Index: src/sys/arch/x86/x86/vm_machdep.c
diff -u src/sys/arch/x86/x86/vm_machdep.c:1.28.6.3 src/sys/arch/x86/x86/vm_machdep.c:1.28.6.4
--- src/sys/arch/x86/x86/vm_machdep.c:1.28.6.3 Thu Mar 22 16:59:04 2018
+++ src/sys/arch/x86/x86/vm_machdep.c Sat Jun 23 11:39:02 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: vm_machdep.c,v 1.28.6.3 2018/03/22 16:59:04 martin Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.28.6.4 2018/06/23 11:39:02 martin Exp $ */
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.28.6.3 2018/03/22 16:59:04 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.28.6.4 2018/06/23 11:39:02 martin Exp $");
#include "opt_mtrr.h"
@@ -157,6 +157,10 @@ cpu_lwp_fork(struct lwp *l1, struct lwp
/* Copy the PCB from parent. */
memcpy(pcb2, pcb1, sizeof(struct pcb));
+
+ /* FPU state not installed. */
+ pcb2->pcb_fpcpu = NULL;
+
/* Copy any additional fpu state */
fpu_save_area_fork(pcb2, pcb1);
Index: src/sys/arch/x86/x86/x86_machdep.c
diff -u src/sys/arch/x86/x86/x86_machdep.c:1.91.4.3 src/sys/arch/x86/x86/x86_machdep.c:1.91.4.4
--- src/sys/arch/x86/x86/x86_machdep.c:1.91.4.3 Sat Jun 9 15:12:21 2018
+++ src/sys/arch/x86/x86/x86_machdep.c Sat Jun 23 11:39:02 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: x86_machdep.c,v 1.91.4.3 2018/06/09 15:12:21 martin Exp $ */
+/* $NetBSD: x86_machdep.c,v 1.91.4.4 2018/06/23 11:39:02 martin Exp $ */
/*-
* Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.91.4.3 2018/06/09 15:12:21 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.91.4.4 2018/06/23 11:39:02 martin Exp $");
#include "opt_modular.h"
#include "opt_physmem.h"
@@ -1201,6 +1201,11 @@ SYSCTL_SETUP(sysctl_machdep_setup, "sysc
sysctl_speculation_init(clog);
#endif
+#ifndef XEN
+ void sysctl_eagerfpu_init(struct sysctllog **);
+ sysctl_eagerfpu_init(clog);
+#endif
+
/* None of these can ever change once the system has booted */
const_sysctl(clog, "fpu_present", CTLTYPE_INT, i386_fpu_present,
CPU_FPU_PRESENT);