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

Reply via email to