Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Jun 2018 05:37:37 +0000 (UTC)
From:      Gordon Tetlow <gordon@FreeBSD.org>
To:        doc-committers@freebsd.org, svn-doc-all@freebsd.org, svn-doc-head@freebsd.org
Subject:   svn commit: r51892 - in head/share: security/advisories security/patches/EN-18:07 security/patches/SA-18:07 xml
Message-ID:  <201806210537.w5L5bbTk069940@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gordon (src,ports committer)
Date: Thu Jun 21 05:37:37 2018
New Revision: 51892
URL: https://svnweb.freebsd.org/changeset/doc/51892

Log:
  Add today's advisory and notices.
  
  Approved by:	so
  Sponsored by:	The FreeBSD Foundation

Added:
  head/share/security/advisories/FreeBSD-EN-18:07.pmap.asc   (contents, props changed)
  head/share/security/advisories/FreeBSD-SA-18:07.lazyfpu.asc   (contents, props changed)
  head/share/security/patches/EN-18:07/
  head/share/security/patches/EN-18:07/pmap.patch   (contents, props changed)
  head/share/security/patches/EN-18:07/pmap.patch.asc   (contents, props changed)
  head/share/security/patches/SA-18:07/
  head/share/security/patches/SA-18:07/lazyfpu-11.patch   (contents, props changed)
  head/share/security/patches/SA-18:07/lazyfpu-11.patch.asc   (contents, props changed)
Modified:
  head/share/xml/advisories.xml
  head/share/xml/notices.xml

Added: head/share/security/advisories/FreeBSD-EN-18:07.pmap.asc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/advisories/FreeBSD-EN-18:07.pmap.asc	Thu Jun 21 05:37:37 2018	(r51892)
@@ -0,0 +1,144 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-EN-18:07.pmap                                           Errata Notice
+                                                          The FreeBSD Project
+
+Topic:          Incorrect TLB shootdown for Xen based guests
+
+Category:       core
+Module:         kernel
+Announced:      2018-06-21
+Credits:        Colin Percival
+Affects:        FreeBSD 11.1
+Corrected:      2018-05-22 14:36:46 UTC (stable/11, 11.2-BETA2)
+                2018-06-21 05:18:08 UTC (releng/11.1, 11.1-RELEASE-p11)
+
+For general information regarding FreeBSD Errata Notices and Security
+Advisories, including descriptions of the fields above, security
+branches, and the following sections, please visit
+<URL:https://security.FreeBSD.org/>.
+
+I.   Background
+
+CPUs rely on a Translation Lookaside Buffer (TLB) to cache virtual memory
+paging information.  When a page is unmapped from the virtual address space
+of a process on a multiprocessor system, an Inter-Processor Interrupt (IPI)
+may be sent to instruct other CPUs to invalidate ("shoot down") their TLB
+entries for the addresses in question.
+
+For virtualization-related performance reasons, FreeBSD has IPI code for the
+Xen platform which is separate from the generic x86 IPI code.
+
+II.  Problem Description
+
+In the course of changes to the FreeBSD virtual memory system to address
+FreeBSD-SA-18:03.speculative_execution, changes were made to the IPIs used
+for shooting down TLB entries.  Unfortunately, the IPI handlers for Xen were
+left non-PTI, even when PTI was enabled, which result in TLB shootdowns for
+the user mode portion of the address space not being consistently performed
+correctly.
+
+III. Impact
+
+Processes on Xen based guests may "see" pages of memory which were previously
+mapped but have since been unmapped, resulted in data being corrupted and/or
+processes crashing due to internal data structures becoming inconsistent.
+
+IV.  Workaround
+
+Only Xen based guests are affected by this issue.  All other platforms are
+not susceptible.
+
+For Xen based guests, disabling PTI will workaround the issue.  Add the
+following line to /boot/loader.conf:
+  vm.pmap.pti=0
+
+Please be aware, by disabling PTI, the system will be vulnerable to
+FreeBSD-SA-18:03.speculative_execution.
+
+V.   Solution
+
+Perform one of the following:
+
+1) Upgrade your system to a supported FreeBSD stable or release / security
+branch (releng) dated after the correction date.
+
+Afterward, reboot the system.
+
+2) To update your system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+Afterward, reboot the system.
+
+3) To update your system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 11.1]
+# fetch https://security.FreeBSD.org/patches/EN-18:07/pmap.patch
+# fetch https://security.FreeBSD.org/patches/EN-18:07/pmap.patch.asc
+# gpg --verify pmap.patch.asc
+
+b) Apply the patch.  Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile your kernel as described in
+<URL:https://www.FreeBSD.org/handbook/kernelconfig.html>; and reboot the
+system.
+
+VI.  Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path                                                      Revision
+- -------------------------------------------------------------------------
+stable/11/                                                        r334047
+releng/11.1/                                                      r335466
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>;
+
+VII. References
+
+The latest revision of this notice is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-18:07.pmap.asc>;
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlsrN3hfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cIOow/+P+zdQ8dmZcEIy7HjYdpTAbPIGNnSdvuXV5O5XGamOziTJOuEEDBxeNiE
+QE9VM8a94Ybl0CJZhfBVPhqrDpYuXOqKvnfHlcXWjppDliUPWohF6kTj4ugqGKrl
+T2VckEvjltgJQ1/XqnkE7n1LuezLcqF/RbW3xOeRkAhf3X+IXd/E3uCuw/n4yknl
+O5EvLmjq3bGlN7OfHOM4E+PHvYOxxfbjYH5S+1Z9g0/apR6HOUi9WU0hV5YEB9Cz
+hUCsnx15Nla97jD9P1xy0tr3FkPpvZRJGj2BelNaQoFNrZB7oWB9xwOmwSqxye/b
+zvp+/WUuGlo1KWU8RldzVPP6A7piuL6oAvYqW8/wcpwd9HqNGXblWz1XodpE3x1F
+TKHTGcP/e/wgU6810SolylwJKxhGVZaQK3UH1iVKPRRTw+HUR1OVDY+q7XAyFD7c
+QbKRyWQIYr2X98LhiT8TMVssharFg7AcviRSDEdCYt+A6S9jiDWMe+C3hGndSSET
+Cf/0q6PQ89GQKw3lQOgwvtWlMaKPwfg3W8lxkusK5o935aXWhbRee3Hzkld7eUl0
+8/uGBCgDnSk7hPIHLDcddIKI+QT0IpHKCPlBRRoTJUhpXo/g5bVkbUnMKBZ7zf3O
+mBvci+KPc2yqp///fw1eMhgRTOOOOnXAHUMsb/FH1b+yIcikudo=
+=fw9I
+-----END PGP SIGNATURE-----

Added: head/share/security/advisories/FreeBSD-SA-18:07.lazyfpu.asc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/advisories/FreeBSD-SA-18:07.lazyfpu.asc	Thu Jun 21 05:37:37 2018	(r51892)
@@ -0,0 +1,147 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-SA-18:07.lazyfpu                                    Security Advisory
+                                                          The FreeBSD Project
+
+Topic:          Lazy FPU State Restore Information Disclosure
+
+Category:       core
+Module:         kernel
+Announced:      2018-06-21
+Credits:        Julian Stecklina from Amazon Germany
+                Thomas Prescher from Cyberus Technology GmbH
+                Zdenek Sojka from SYSGO AG
+                Colin Percival
+Affects:        All supported version of FreeBSD.
+Corrected:      2018-06-14 18:50:49 UTC (stable/11, 11.2-PRERELEASE)
+                2018-06-15 13:21:37 UTC (releng/11.2, 11.2-RC3)
+                2018-06-21 05:17:13 UTC (releng/11.1, 11.1-RELEASE-p11)
+CVE Name:       CVE-2018-3665
+
+Special Note:   This advisory only addresses this issue for FreeBSD 11.x on
+                i386 and amd64.  We expect to update this advisory to include
+                10.x in the near future.
+
+For general information regarding FreeBSD Security Advisories,
+including descriptions of the fields above, security branches, and the
+following sections, please visit <URL:https://security.FreeBSD.org/>.
+
+I.   Background
+
+Modern CPUs have a floating point unit (FPU) which needs to maintain state
+per thread.  One technique is to only save and to only restore the FPU state
+for a thread when a thread attempts to utilize the FPU.  This technique is
+called Lazy FPU state restore.
+
+II.  Problem Description
+
+A subset of Intel processors can allow a local thread to infer data from
+another thread through a speculative execution side channel when Lazy FPU
+state restore is used.
+
+III. Impact
+
+Any local thread can potentially read FPU state information from other
+threads running on the host.  This could include cryptographic keys when the
+AES-NI CPU feature is present.
+
+IV.  Workaround
+
+No workaround is available, but non-Intel branded CPUs are not believed
+to be vulnerable.
+
+V.   Solution
+
+The patch changes from Lazy FPU state restore to Eager FPU state restore.
+This new technique is the recommended practice from Intel and in some cases
+can actually increase performance, depending on workload.
+
+Perform one of the following:
+
+1) Upgrade your vulnerable system to a supported FreeBSD stable or
+release / security branch (releng) dated after the correction date.
+
+Afterward, reboot the system.
+
+2) To update your vulnerable system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+Afterward, reboot the system.
+
+3) To update your vulnerable system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 11.1]
+# fetch https://security.FreeBSD.org/patches/SA-18:07/lazyfpu-11.patch
+# fetch https://security.FreeBSD.org/patches/SA-18:07/lazyfpu-11.patch.asc
+# gpg --verify lazyfpu-11.patch.asc
+
+b) Apply the patch.  Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile your kernel as described in
+<URL:https://www.FreeBSD.org/handbook/kernelconfig.html>; and reboot the
+system.
+
+VI.  Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path                                                      Revision
+- -------------------------------------------------------------------------
+stable/11/                                                        r335169
+releng/11.2/                                                      r335196
+releng/11.1/                                                      r335465
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>;
+
+VII. References
+
+<URL:https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00145.html>;
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3665>;
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-18:07.lazyfpu.asc>;
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlsrN1hfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJTLA/+Kt7QLkNCVudaiE+d+VMuC2f1aGhqoyd+36xL9rNsn2ShZhIo+gq1dhXn
+2lJiOYCPN5cJkasj1YdP2bSIv25nTcFMp0rKOww0A1scOnzi66LAD+DXmGVUhmaA
+MPyrnuL7rbuPq9ls9FGAO2XURwB9IrGYtqPuVWmNyn+HyKBYcGCkL5+UEnHeUCg8
+oopJudZgrGBVMFCsqG6K/b+3uc397Hyq0PZzpyWFfkaxrbTwVMMwgWyTxIYaPVs7
+2g7WK2JWjJNk0IWQGot9qpKYDRyxc9PPFX/0blwOLe1Wwrt5nEF+9av89HQJ6PXF
++Ws5w8Gnhi9wWuK19ew1j0nvP+f0zw09r4GuEzhZXADAz733HNK5dtsS/dMJi2wa
+9fQ0s1joT3JFDvWZKUQS2mNuhpvBfYoI0d0OEJT2H2eycFYe4B+VNhB2V1e9wLn6
+9X4+Vbc2LEOF09klQQFMYNMEyQzLtfq2gHIoD37sCw9mMrYKWjgy3NhY5AKrfGHG
+OcBsvnaXCW/x9/kV9Pfoel/psrmjcQdp4QEKAZbRNwvJG5sGhtsQXTp0Nk+BCuVy
+G0NNB9306dLfk0OTZ02SiOUjVagXObyo+LgWTBO6FryDlHVkopsYNkB5oRx9fLrm
+68r7OXidl0ndGqnh87meMVH1/Fu/rr09Jd4osIzS+Gc0Dt7NOEQ=
+=8fnI
+-----END PGP SIGNATURE-----

Added: head/share/security/patches/EN-18:07/pmap.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/patches/EN-18:07/pmap.patch	Thu Jun 21 05:37:37 2018	(r51892)
@@ -0,0 +1,78 @@
+--- sys/x86/xen/xen_apic.c.orig
++++ sys/x86/xen/xen_apic.c
+@@ -41,6 +41,7 @@
+ #include <machine/cpufunc.h>
+ #include <machine/cpu.h>
+ #include <machine/intr_machdep.h>
++#include <machine/md_var.h>
+ #include <machine/smp.h>
+ 
+ #include <x86/apicreg.h>
+@@ -439,6 +440,46 @@
+ 	invltlb_pcid_handler();
+ 	return (FILTER_HANDLED);
+ }
++
++static int
++xen_invltlb_invpcid_pti(void *arg)
++{
++
++	invltlb_invpcid_pti_handler();
++	return (FILTER_HANDLED);
++}
++
++static int
++xen_invlpg_invpcid_handler(void *arg)
++{
++
++	invlpg_invpcid_handler();
++	return (FILTER_HANDLED);
++}
++
++static int
++xen_invlpg_pcid_handler(void *arg)
++{
++
++	invlpg_pcid_handler();
++	return (FILTER_HANDLED);
++}
++
++static int
++xen_invlrng_invpcid_handler(void *arg)
++{
++
++	invlrng_invpcid_handler();
++	return (FILTER_HANDLED);
++}
++
++static int
++xen_invlrng_pcid_handler(void *arg)
++{
++
++	invlrng_pcid_handler();
++	return (FILTER_HANDLED);
++}
+ #endif
+ 
+ static int
+@@ -529,8 +570,18 @@
+ 
+ #ifdef __amd64__
+ 	if (pmap_pcid_enabled) {
+-		xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter = invpcid_works ?
+-		    xen_invltlb_invpcid : xen_invltlb_pcid;
++		if (pti)
++			xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter =
++			    invpcid_works ? xen_invltlb_invpcid_pti :
++			    xen_invltlb_pcid;
++		else
++			xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter =
++			    invpcid_works ? xen_invltlb_invpcid :
++			    xen_invltlb_pcid;
++		xen_ipis[IPI_TO_IDX(IPI_INVLPG)].filter = invpcid_works ?
++		    xen_invlpg_invpcid_handler : xen_invlpg_pcid_handler;
++		xen_ipis[IPI_TO_IDX(IPI_INVLRNG)].filter = invpcid_works ?
++		    xen_invlrng_invpcid_handler : xen_invlrng_pcid_handler;
+ 	}
+ #endif
+ 	CPU_FOREACH(i)

Added: head/share/security/patches/EN-18:07/pmap.patch.asc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/patches/EN-18:07/pmap.patch.asc	Thu Jun 21 05:37:37 2018	(r51892)
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlsrN4FfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cI6+Q//dTnLur/Dtcz8y2b00OBdUvC1GL3kcFjFhk/fwcvceIdY1m6cC6u6ypxp
+Mehewv2YENgLw0fkIu61OsqtyCDmQ+O1LKuFNZpkYqPuiVRvhwAlXTHEWjVHmP8f
+52oSgspKxuZbpMKIDIZaQUiH3Ff7BcGIx8ru50wcsfe4dWXD0YJebqkK1etPuUYV
+HuMNrqbq7cH8BgBBaRzlAABqz6qeXjLZryyE3bDT4QGEdQPvyrs0muj/TtKzqmZB
+axX/V+aClQwnXARQ+EhGxCHDU+OoX4inH1N20+ZPwq7aGTjo0B19Yo/03cV1C7vs
+3NDJWKk4oxM6QP1bUIYZ37qlX+WSXH25q8PGtWucd/YdVZR04iXOwC4G1ncmEUWi
+1jEj9V7FOBzoLqCGdL2izibemVbKjza5FvODW2gq+Xzbe2F4eube0v12wOiLRED/
+mTn71RWsImgzsRvywIsGMkaZCZm4j7gWi53dgBqNteitmw75esM000tcKhy5T5yl
+VuxkhttAODFAujz7k4BRpUebzAf0autiRjec6QTHWek5jqD+bM3nGnlPVJMIzQrX
+GVibFJga+zrqHhXVXAEKM6QEgcF4nPOlwWOIJ1mBGxomnCM5dKt+Fr1W9lFsurun
+w83zqwX12Wz+gUENgBYeAawk9O86KoXC0gqf2pphjPnihN6x7Pc=
+=6sV+
+-----END PGP SIGNATURE-----

Added: head/share/security/patches/SA-18:07/lazyfpu-11.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/patches/SA-18:07/lazyfpu-11.patch	Thu Jun 21 05:37:37 2018	(r51892)
@@ -0,0 +1,373 @@
+--- sys/amd64/amd64/cpu_switch.S.orig
++++ sys/amd64/amd64/cpu_switch.S
+@@ -105,10 +105,10 @@
+ 
+ 	/* have we used fp, and need a save? */
+ 	cmpq	%rdi,PCPU(FPCURTHREAD)
+-	jne	3f
++	jne	2f
+ 	movq	PCB_SAVEFPU(%r8),%r8
+ 	clts
+-	cmpl	$0,use_xsave
++	cmpl	$0,use_xsave(%rip)
+ 	jne	1f
+ 	fxsave	(%r8)
+ 	jmp	2f
+@@ -120,12 +120,7 @@
+ 	/* This is patched to xsaveopt if supported, see fpuinit_bsp1() */
+ 	xsave	(%r8)
+ 	movq	%rcx,%rdx
+-2:	smsw	%ax
+-	orb	$CR0_TS,%al
+-	lmsw	%ax
+-	xorl	%eax,%eax
+-	movq	%rax,PCPU(FPCURTHREAD)
+-3:
++2:
+ 	/* Save is done.  Now fire up new thread. Leave old vmspace. */
+ 	movq	%rsi,%r12
+ 	movq	%rdi,%r13
+@@ -212,6 +207,8 @@
+ 	movq	PCB_RBX(%r8),%rbx
+ 	movq	PCB_RIP(%r8),%rax
+ 	movq	%rax,(%rsp)
++	movq	PCPU(CURTHREAD),%rdi
++	call	fpu_activate_sw
+ 	ret
+ 
+ 	/*
+--- sys/amd64/amd64/fpu.c.orig
++++ sys/amd64/amd64/fpu.c
+@@ -139,6 +139,11 @@
+ SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
+     SYSCTL_NULL_INT_PTR, 1, "Floating point instructions executed in hardware");
+ 
++int lazy_fpu_switch = 0;
++SYSCTL_INT(_hw, OID_AUTO, lazy_fpu_switch, CTLFLAG_RWTUN | CTLFLAG_NOFETCH,
++    &lazy_fpu_switch, 0,
++    "Lazily load FPU context after context switch");
++
+ int use_xsave;			/* non-static for cpu_switch.S */
+ uint64_t xsave_mask;		/* the same */
+ static	uma_zone_t fpu_save_area_zone;
+@@ -204,6 +209,7 @@
+ 	u_int cp[4];
+ 	uint64_t xsave_mask_user;
+ 
++	TUNABLE_INT_FETCH("hw.lazy_fpu_switch", &lazy_fpu_switch);
+ 	if ((cpu_feature2 & CPUID2_XSAVE) != 0) {
+ 		use_xsave = 1;
+ 		TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave);
+@@ -611,6 +617,45 @@
+ 	return (fpetable[(mxcsr & (~mxcsr >> 7)) & 0x3f]);
+ }
+ 
++static void
++restore_fpu_curthread(struct thread *td)
++{
++	struct pcb *pcb;
++
++	/*
++	 * Record new context early in case frstor causes a trap.
++	 */
++	PCPU_SET(fpcurthread, td);
++
++	stop_emulating();
++	fpu_clean_state();
++	pcb = td->td_pcb;
++
++	if ((pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
++		/*
++		 * This is the first time this thread has used the FPU or
++		 * the PCB doesn't contain a clean FPU state.  Explicitly
++		 * load an initial state.
++		 *
++		 * We prefer to restore the state from the actual save
++		 * area in PCB instead of directly loading from
++		 * fpu_initialstate, to ignite the XSAVEOPT
++		 * tracking engine.
++		 */
++		bcopy(fpu_initialstate, pcb->pcb_save,
++		    cpu_max_ext_state_size);
++		fpurestore(pcb->pcb_save);
++		if (pcb->pcb_initial_fpucw != __INITIAL_FPUCW__)
++			fldcw(pcb->pcb_initial_fpucw);
++		if (PCB_USER_FPU(pcb))
++			set_pcb_flags(pcb, PCB_FPUINITDONE |
++			    PCB_USERFPUINITDONE);
++		else
++			set_pcb_flags(pcb, PCB_FPUINITDONE);
++	} else
++		fpurestore(pcb->pcb_save);
++}
++
+ /*
+  * Device Not Available (DNA, #NM) exception handler.
+  *
+@@ -621,7 +666,9 @@
+ void
+ fpudna(void)
+ {
++	struct thread *td;
+ 
++	td = curthread;
+ 	/*
+ 	 * This handler is entered with interrupts enabled, so context
+ 	 * switches may occur before critical_enter() is executed.  If
+@@ -635,49 +682,38 @@
+ 
+ 	KASSERT((curpcb->pcb_flags & PCB_FPUNOSAVE) == 0,
+ 	    ("fpudna while in fpu_kern_enter(FPU_KERN_NOCTX)"));
+-	if (PCPU_GET(fpcurthread) == curthread) {
+-		printf("fpudna: fpcurthread == curthread\n");
++	if (__predict_false(PCPU_GET(fpcurthread) == td)) {
++		/*
++		 * Some virtual machines seems to set %cr0.TS at
++		 * arbitrary moments.  Silently clear the TS bit
++		 * regardless of the eager/lazy FPU context switch
++		 * mode.
++		 */
+ 		stop_emulating();
+-		critical_exit();
+-		return;
++	} else {
++		if (__predict_false(PCPU_GET(fpcurthread) != NULL)) {
++			panic(
++		    "fpudna: fpcurthread = %p (%d), curthread = %p (%d)\n",
++			    PCPU_GET(fpcurthread),
++			    PCPU_GET(fpcurthread)->td_tid, td, td->td_tid);
++		}
++		restore_fpu_curthread(td);
+ 	}
+-	if (PCPU_GET(fpcurthread) != NULL) {
+-		panic("fpudna: fpcurthread = %p (%d), curthread = %p (%d)\n",
+-		    PCPU_GET(fpcurthread), PCPU_GET(fpcurthread)->td_tid,
+-		    curthread, curthread->td_tid);
+-	}
+-	stop_emulating();
+-	/*
+-	 * Record new context early in case frstor causes a trap.
+-	 */
+-	PCPU_SET(fpcurthread, curthread);
++	critical_exit();
++}
+ 
+-	fpu_clean_state();
++void fpu_activate_sw(struct thread *td); /* Called from the context switch */
++void
++fpu_activate_sw(struct thread *td)
++{
+ 
+-	if ((curpcb->pcb_flags & PCB_FPUINITDONE) == 0) {
+-		/*
+-		 * This is the first time this thread has used the FPU or
+-		 * the PCB doesn't contain a clean FPU state.  Explicitly
+-		 * load an initial state.
+-		 *
+-		 * We prefer to restore the state from the actual save
+-		 * area in PCB instead of directly loading from
+-		 * fpu_initialstate, to ignite the XSAVEOPT
+-		 * tracking engine.
+-		 */
+-		bcopy(fpu_initialstate, curpcb->pcb_save,
+-		    cpu_max_ext_state_size);
+-		fpurestore(curpcb->pcb_save);
+-		if (curpcb->pcb_initial_fpucw != __INITIAL_FPUCW__)
+-			fldcw(curpcb->pcb_initial_fpucw);
+-		if (PCB_USER_FPU(curpcb))
+-			set_pcb_flags(curpcb,
+-			    PCB_FPUINITDONE | PCB_USERFPUINITDONE);
+-		else
+-			set_pcb_flags(curpcb, PCB_FPUINITDONE);
+-	} else
+-		fpurestore(curpcb->pcb_save);
+-	critical_exit();
++	if (lazy_fpu_switch || (td->td_pflags & TDP_KTHREAD) != 0 ||
++	    !PCB_USER_FPU(td->td_pcb)) {
++		PCPU_SET(fpcurthread, NULL);
++		start_emulating();
++	} else if (PCPU_GET(fpcurthread) != td) {
++		restore_fpu_curthread(td);
++	}
+ }
+ 
+ void
+--- sys/i386/i386/swtch.s.orig
++++ sys/i386/i386/swtch.s
+@@ -293,6 +293,12 @@
+ cpu_switch_load_gs:
+ 	mov	PCB_GS(%edx),%gs
+ 
++	pushl	%edx
++	pushl	PCPU(CURTHREAD)
++	call	npxswitch
++	popl	%edx
++	popl	%edx
++
+ 	/* Test if debug registers should be restored. */
+ 	testl	$PCB_DBREGS,PCB_FLAGS(%edx)
+ 	jz      1f
+--- sys/i386/isa/npx.c.orig
++++ sys/i386/isa/npx.c
+@@ -191,6 +191,11 @@
+ SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
+     &hw_float, 0, "Floating point instructions executed in hardware");
+ 
++int lazy_fpu_switch = 0;
++SYSCTL_INT(_hw, OID_AUTO, lazy_fpu_switch, CTLFLAG_RWTUN | CTLFLAG_NOFETCH,
++    &lazy_fpu_switch, 0,
++    "Lazily load FPU context after context switch");
++
+ int use_xsave;
+ uint64_t xsave_mask;
+ static	uma_zone_t fpu_save_area_zone;
+@@ -327,6 +332,7 @@
+ 	u_int cp[4];
+ 	uint64_t xsave_mask_user;
+ 
++	TUNABLE_INT_FETCH("hw.lazy_fpu_switch", &lazy_fpu_switch);
+ 	if (cpu_fxsr && (cpu_feature2 & CPUID2_XSAVE) != 0) {
+ 		use_xsave = 1;
+ 		TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave);
+@@ -785,47 +791,20 @@
+ 	return (fpetable[(mxcsr & (~mxcsr >> 7)) & 0x3f]);
+ }
+ 
+-/*
+- * Implement device not available (DNA) exception
+- *
+- * It would be better to switch FP context here (if curthread != fpcurthread)
+- * and not necessarily for every context switch, but it is too hard to
+- * access foreign pcb's.
+- */
+-
+-static int err_count = 0;
+-
+-int
+-npxdna(void)
++static void
++restore_npx_curthread(struct thread *td, struct pcb *pcb)
+ {
+ 
+-	if (!hw_float)
+-		return (0);
+-	critical_enter();
+-	if (PCPU_GET(fpcurthread) == curthread) {
+-		printf("npxdna: fpcurthread == curthread %d times\n",
+-		    ++err_count);
+-		stop_emulating();
+-		critical_exit();
+-		return (1);
+-	}
+-	if (PCPU_GET(fpcurthread) != NULL) {
+-		printf("npxdna: fpcurthread = %p (%d), curthread = %p (%d)\n",
+-		       PCPU_GET(fpcurthread),
+-		       PCPU_GET(fpcurthread)->td_proc->p_pid,
+-		       curthread, curthread->td_proc->p_pid);
+-		panic("npxdna");
+-	}
+-	stop_emulating();
+ 	/*
+ 	 * Record new context early in case frstor causes a trap.
+ 	 */
+-	PCPU_SET(fpcurthread, curthread);
++	PCPU_SET(fpcurthread, td);
+ 
++	stop_emulating();
+ 	if (cpu_fxsr)
+ 		fpu_clean_state();
+ 
+-	if ((curpcb->pcb_flags & PCB_NPXINITDONE) == 0) {
++	if ((pcb->pcb_flags & PCB_NPXINITDONE) == 0) {
+ 		/*
+ 		 * This is the first time this thread has used the FPU or
+ 		 * the PCB doesn't contain a clean FPU state.  Explicitly
+@@ -836,18 +815,54 @@
+ 		 * npx_initialstate, to ignite the XSAVEOPT
+ 		 * tracking engine.
+ 		 */
+-		bcopy(npx_initialstate, curpcb->pcb_save, cpu_max_ext_state_size);
+-		fpurstor(curpcb->pcb_save);
+-		if (curpcb->pcb_initial_npxcw != __INITIAL_NPXCW__)
+-			fldcw(curpcb->pcb_initial_npxcw);
+-		curpcb->pcb_flags |= PCB_NPXINITDONE;
+-		if (PCB_USER_FPU(curpcb))
+-			curpcb->pcb_flags |= PCB_NPXUSERINITDONE;
++		bcopy(npx_initialstate, pcb->pcb_save, cpu_max_ext_state_size);
++		fpurstor(pcb->pcb_save);
++		if (pcb->pcb_initial_npxcw != __INITIAL_NPXCW__)
++			fldcw(pcb->pcb_initial_npxcw);
++		pcb->pcb_flags |= PCB_NPXINITDONE;
++		if (PCB_USER_FPU(pcb))
++			pcb->pcb_flags |= PCB_NPXUSERINITDONE;
+ 	} else {
+-		fpurstor(curpcb->pcb_save);
++		fpurstor(pcb->pcb_save);
+ 	}
++}
++
++/*
++ * Implement device not available (DNA) exception
++ *
++ * It would be better to switch FP context here (if curthread != fpcurthread)
++ * and not necessarily for every context switch, but it is too hard to
++ * access foreign pcb's.
++ */
++int
++npxdna(void)
++{
++	struct thread *td;
++
++	if (!hw_float)
++		return (0);
++	td = curthread;
++	critical_enter();
++	if (__predict_false(PCPU_GET(fpcurthread) == td)) {
++		/*
++		 * Some virtual machines seems to set %cr0.TS at
++		 * arbitrary moments.  Silently clear the TS bit
++		 * regardless of the eager/lazy FPU context switch
++		 * mode.
++		 */
++		stop_emulating();
++	} else {
++		if (__predict_false(PCPU_GET(fpcurthread) != NULL)) {
++			printf(
++		    "npxdna: fpcurthread = %p (%d), curthread = %p (%d)\n",
++			    PCPU_GET(fpcurthread),
++			    PCPU_GET(fpcurthread)->td_proc->p_pid,
++			    td, td->td_proc->p_pid);
++			panic("npxdna");
++		}
++		restore_npx_curthread(td, td->td_pcb);
++	}
+ 	critical_exit();
+-
+ 	return (1);
+ }
+ 
+@@ -869,10 +884,22 @@
+ 		xsaveopt((char *)addr, xsave_mask);
+ 	else
+ 		fpusave(addr);
+-	start_emulating();
+-	PCPU_SET(fpcurthread, NULL);
+ }
+ 
++void npxswitch(struct thread *td, struct pcb *pcb);
++void
++npxswitch(struct thread *td, struct pcb *pcb)
++{
++
++	if (lazy_fpu_switch || (td->td_pflags & TDP_KTHREAD) != 0 ||
++	    !PCB_USER_FPU(pcb)) {
++		start_emulating();
++		PCPU_SET(fpcurthread, NULL);
++	} else if (PCPU_GET(fpcurthread) != td) {
++		restore_npx_curthread(td, pcb);
++	}
++}
++
+ /*
+  * Unconditionally save the current co-processor state across suspend and
+  * resume.

Added: head/share/security/patches/SA-18:07/lazyfpu-11.patch.asc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/security/patches/SA-18:07/lazyfpu-11.patch.asc	Thu Jun 21 05:37:37 2018	(r51892)
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlsrN2xfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJY2Q/+KyfnyHr1YphdZkXYLPTtIKCJasfR1jWSh+6Amr/QDCSvMSvvjvbg6PL0
+snVq9108ycrKU7xOBebBQRYNYuS1KlRsjcw396dhpjoVwaoQ5mxuWqeiRbSudy/N
+hFuX91E22832j1o4AsovV/vpqTREz0o4BnMrw9fUiZvuhEiPXs3VHoBcn3lCflXf
+ubJVptVVCjIK7miVY/oGtvUnzNoSujjNQekpdhHmKyWxU+PrHHhh/kJg+CVEKNr9
+IkeJV8w2NkpbXEkf59rMUxoMd4OkxlVlNuoPqWekXBwcLGwd5Uux7GAeI+X8crGA
+cim6F8zniozsip7AptQU5e8yQL/mKYsoWpsghASEu1uanvwTjkmu82f3ER7/FX08
+0MmhWcSkqGEvKlenQAajCLA7CTzXiMcB3QoCd3VYUmXZOJqcnDAijaDRZ/FMuVJV
+wGDFus4cMiDhuC+WJTE699DGmveov3C3N6O65K7KNMdsECFwfP38xzzv+wvjzCbj
+JzaYW14YYr5cgsBdL24z0Yl8Pz9vXexiFdPH+VxOaRIHZGMSQqRe0TXG85M8Pv9F
+X0tje/gbMMnBpgHui3lUY3x45srRLSn8qt/v/j3W5zoxXINZTDTdqoZT7T9pKWpD
+EmWdlLMRDDDvQceXdDebZytM/cMAUf2PS2RtWipSwC4Frqz9eYY=
+=dd45
+-----END PGP SIGNATURE-----

Modified: head/share/xml/advisories.xml
==============================================================================
--- head/share/xml/advisories.xml	Thu Jun 21 02:11:46 2018	(r51891)
+++ head/share/xml/advisories.xml	Thu Jun 21 05:37:37 2018	(r51892)
@@ -8,6 +8,19 @@
     <name>2018</name>
 
     <month>
+      <name>6</name>
+
+      <day>
+	<name>21</name>
+
+	<advisory>
+	  <name>FreeBSD-SA-18:07.lazyfpu</name>
+	</advisory>
+
+      </day>
+    </month>
+
+    <month>
       <name>5</name>
 
       <day>

Modified: head/share/xml/notices.xml
==============================================================================
--- head/share/xml/notices.xml	Thu Jun 21 02:11:46 2018	(r51891)
+++ head/share/xml/notices.xml	Thu Jun 21 05:37:37 2018	(r51892)
@@ -8,6 +8,19 @@
     <name>2018</name>
 
     <month>
+      <name>6</name>
+
+      <day>
+	<name>21</name>
+
+	<notice>
+	  <name>FreeBSD-EN-18:07.pmap</name>
+	</notice>
+
+      </day>
+    </month>
+
+    <month>
       <name>5</name>
 
       <day>



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