aboutsummaryrefslogtreecommitdiff
path: root/share
diff options
context:
space:
mode:
authorGordon Tetlow <gordon@FreeBSD.org>2018-06-21 05:37:37 +0000
committerGordon Tetlow <gordon@FreeBSD.org>2018-06-21 05:37:37 +0000
commit94c673d3909a12b9b7fb4d1a7c27d168aedf9b6f (patch)
treeebe9a8e3d9a642726dd289d6f329efbf9f9e525d /share
parent5f4afae8713e6dc8ce80c75a66d5e897828d7e1b (diff)
downloaddoc-94c673d3909a12b9b7fb4d1a7c27d168aedf9b6f.tar.gz
doc-94c673d3909a12b9b7fb4d1a7c27d168aedf9b6f.zip
Add today's advisory and notices.
Approved by: so Sponsored by: The FreeBSD Foundation
Notes
Notes: svn path=/head/; revision=51892
Diffstat (limited to 'share')
-rw-r--r--share/security/advisories/FreeBSD-EN-18:07.pmap.asc144
-rw-r--r--share/security/advisories/FreeBSD-SA-18:07.lazyfpu.asc147
-rw-r--r--share/security/patches/EN-18:07/pmap.patch78
-rw-r--r--share/security/patches/EN-18:07/pmap.patch.asc18
-rw-r--r--share/security/patches/SA-18:07/lazyfpu-11.patch373
-rw-r--r--share/security/patches/SA-18:07/lazyfpu-11.patch.asc18
-rw-r--r--share/xml/advisories.xml13
-rw-r--r--share/xml/notices.xml13
8 files changed, 804 insertions, 0 deletions
diff --git a/share/security/advisories/FreeBSD-EN-18:07.pmap.asc b/share/security/advisories/FreeBSD-EN-18:07.pmap.asc
new file mode 100644
index 0000000000..f55482206f
--- /dev/null
+++ b/share/security/advisories/FreeBSD-EN-18:07.pmap.asc
@@ -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-----
diff --git a/share/security/advisories/FreeBSD-SA-18:07.lazyfpu.asc b/share/security/advisories/FreeBSD-SA-18:07.lazyfpu.asc
new file mode 100644
index 0000000000..8da46d4a80
--- /dev/null
+++ b/share/security/advisories/FreeBSD-SA-18:07.lazyfpu.asc
@@ -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-----
diff --git a/share/security/patches/EN-18:07/pmap.patch b/share/security/patches/EN-18:07/pmap.patch
new file mode 100644
index 0000000000..e0b0f2ca7b
--- /dev/null
+++ b/share/security/patches/EN-18:07/pmap.patch
@@ -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)
diff --git a/share/security/patches/EN-18:07/pmap.patch.asc b/share/security/patches/EN-18:07/pmap.patch.asc
new file mode 100644
index 0000000000..269024cd58
--- /dev/null
+++ b/share/security/patches/EN-18:07/pmap.patch.asc
@@ -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-----
diff --git a/share/security/patches/SA-18:07/lazyfpu-11.patch b/share/security/patches/SA-18:07/lazyfpu-11.patch
new file mode 100644
index 0000000000..39330e4cda
--- /dev/null
+++ b/share/security/patches/SA-18:07/lazyfpu-11.patch
@@ -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.
diff --git a/share/security/patches/SA-18:07/lazyfpu-11.patch.asc b/share/security/patches/SA-18:07/lazyfpu-11.patch.asc
new file mode 100644
index 0000000000..2479fd9255
--- /dev/null
+++ b/share/security/patches/SA-18:07/lazyfpu-11.patch.asc
@@ -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-----
diff --git a/share/xml/advisories.xml b/share/xml/advisories.xml
index 3020aabc5a..d9c6f21970 100644
--- a/share/xml/advisories.xml
+++ b/share/xml/advisories.xml
@@ -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>
diff --git a/share/xml/notices.xml b/share/xml/notices.xml
index 2f54d167c9..13896f3f52 100644
--- a/share/xml/notices.xml
+++ b/share/xml/notices.xml
@@ -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>