Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Apr 2019 19:46:02 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r346294 - in head/sys: amd64/amd64 i386/i386
Message-ID:  <201904161946.x3GJk2uH009117@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Tue Apr 16 19:46:02 2019
New Revision: 346294
URL: https://svnweb.freebsd.org/changeset/base/346294

Log:
  Fix initial x87 state after r345562.
  
  After the referenced commit, we did not set x87 and sse valid bits in
  the xstate_bv bitmask for initial fpu state (stored in memory), when
  using XSAVE.
  
  The state is loaded into FPU register file to initialize the process
  FPU state, and since both bits were clear, the default x87 and SSE
  states were loaded.  By chance, FreeBSD ABI SSE2 state is same as FPU
  initial state, so the bug is not visible for 64bit processes.  But on
  i386, the precision control should be set to double (53bit mantissa),
  instead of the default double extended (64bit mantissa). For 32bit
  processes on amd64, kernel reloads control word with the right mask,
  which only left native i386 and amd64 native but using x87 as
  affected.
  
  Fix it by setting minimal required xstate_bv mask.
  
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/sys/amd64/amd64/fpu.c
  head/sys/i386/i386/npx.c

Modified: head/sys/amd64/amd64/fpu.c
==============================================================================
--- head/sys/amd64/amd64/fpu.c	Tue Apr 16 19:38:16 2019	(r346293)
+++ head/sys/amd64/amd64/fpu.c	Tue Apr 16 19:46:02 2019	(r346294)
@@ -370,6 +370,7 @@ fpuinit(void)
 static void
 fpuinitstate(void *arg __unused)
 {
+	uint64_t *xstate_bv;
 	register_t saveintr;
 	int cp[4], i, max_ext_n;
 
@@ -400,6 +401,10 @@ fpuinitstate(void *arg __unused)
 	 * Save Area.
 	 */
 	if (use_xsave) {
+		xstate_bv = (uint64_t *)((char *)(fpu_initialstate + 1) +
+		    offsetof(struct xstate_hdr, xstate_bv));
+		*xstate_bv = XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE;
+
 		max_ext_n = flsl(xsave_mask);
 		xsave_area_desc = malloc(max_ext_n * sizeof(struct
 		    xsave_area_elm_descr), M_DEVBUF, M_WAITOK | M_ZERO);

Modified: head/sys/i386/i386/npx.c
==============================================================================
--- head/sys/i386/i386/npx.c	Tue Apr 16 19:38:16 2019	(r346293)
+++ head/sys/i386/i386/npx.c	Tue Apr 16 19:46:02 2019	(r346294)
@@ -472,6 +472,7 @@ npxinit(bool bsp)
 static void
 npxinitstate(void *arg __unused)
 {
+	uint64_t *xstate_bv;
 	register_t saveintr;
 	int cp[4], i, max_ext_n;
 
@@ -507,6 +508,7 @@ npxinitstate(void *arg __unused)
 		    sizeof(npx_initialstate->sv_xmm.sv_fp));
 		bzero(npx_initialstate->sv_xmm.sv_xmm,
 		    sizeof(npx_initialstate->sv_xmm.sv_xmm));
+
 	} else
 		bzero(npx_initialstate->sv_87.sv_ac,
 		    sizeof(npx_initialstate->sv_87.sv_ac));
@@ -516,6 +518,10 @@ npxinitstate(void *arg __unused)
 	 * Save Area.
 	 */
 	if (use_xsave) {
+		xstate_bv = (uint64_t *)((char *)(npx_initialstate + 1) +
+		    offsetof(struct xstate_hdr, xstate_bv));
+		*xstate_bv = XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE;
+
 		if (xsave_mask >> 32 != 0)
 			max_ext_n = fls(xsave_mask >> 32) + 32;
 		else



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904161946.x3GJk2uH009117>