Module Name:    src
Committed By:   maxv
Date:           Tue Oct 31 15:16:10 UTC 2017

Modified Files:
        src/sys/arch/x86/x86: fpu.c

Log Message:
Initialize xstate_bv with the structures that were just filled in,
otherwise xrstor does not restore them. This can happen only if userland
calls setcontext without having used the FPU before.

Until rev1.15 xstate_bv was implicitly initialized because the xsave area
was not zeroed out properly.


To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 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/x86/fpu.c
diff -u src/sys/arch/x86/x86/fpu.c:1.17 src/sys/arch/x86/x86/fpu.c:1.18
--- src/sys/arch/x86/x86/fpu.c:1.17	Tue Oct 31 12:02:20 2017
+++ src/sys/arch/x86/x86/fpu.c	Tue Oct 31 15:16:10 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: fpu.c,v 1.17 2017/10/31 12:02:20 maxv Exp $	*/
+/*	$NetBSD: fpu.c,v 1.18 2017/10/31 15:16:10 maxv 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.17 2017/10/31 12:02:20 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.18 2017/10/31 15:16:10 maxv Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -574,6 +574,16 @@ process_write_fpregs_xmm(struct lwp *l, 
 		memcpy(&fpu_save->sv_xmm, fpregs, sizeof(fpu_save->sv_xmm));
 		/* Invalid bits in the mxcsr_mask will cause faults */
 		fpu_save->sv_xmm.fx_mxcsr_mask &= __INITIAL_MXCSR_MASK__;
+
+		/*
+		 * Make sure the x87 and SSE bits are set in xstate_bv.
+		 * Otherwise xrstor will not restore them.
+		 */
+		if (x86_fpu_save == FPU_SAVE_XSAVE ||
+		    x86_fpu_save == FPU_SAVE_XSAVEOPT) {
+			fpu_save->sv_xsave_hdr.xsh_xstate_bv |=
+			    (XCR0_X87 | XCR0_SSE);
+		}
 	} else {
 		process_xmm_to_s87(fpregs, &fpu_save->sv_87);
 	}
@@ -589,6 +599,16 @@ process_write_fpregs_s87(struct lwp *l, 
 		fpusave_lwp(l, true);
 		fpu_save = process_fpframe(l);
 		process_s87_to_xmm(fpregs, &fpu_save->sv_xmm);
+
+		/*
+		 * Make sure the x87 and SSE bits are set in xstate_bv.
+		 * Otherwise xrstor will not restore them.
+		 */
+		if (x86_fpu_save == FPU_SAVE_XSAVE ||
+		    x86_fpu_save == FPU_SAVE_XSAVEOPT) {
+			fpu_save->sv_xsave_hdr.xsh_xstate_bv |=
+			    (XCR0_X87 | XCR0_SSE);
+		}
 	} else {
 		fpusave_lwp(l, false);
 		fpu_save = process_fpframe(l);

Reply via email to