svn commit: r51482 - in head/share: security/advisories security/patches/SA-18:03 xml
Gordon Tetlow
gordon at FreeBSD.org
Wed Mar 14 04:14:15 UTC 2018
Author: gordon (src,ports committer)
Date: Wed Mar 14 04:14:13 2018
New Revision: 51482
URL: https://svnweb.freebsd.org/changeset/doc/51482
Log:
Add FreeBSD-SA-18:03.speculative_execution.
Approved by: so
Added:
head/share/security/advisories/FreeBSD-SA-18:03.speculative_execution.asc (contents, props changed)
head/share/security/patches/SA-18:03/
head/share/security/patches/SA-18:03/speculative_execution-amd64-11.patch (contents, props changed)
head/share/security/patches/SA-18:03/speculative_execution-amd64-11.patch.asc (contents, props changed)
Modified:
head/share/xml/advisories.xml
Added: head/share/security/advisories/FreeBSD-SA-18:03.speculative_execution.asc
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/share/security/advisories/FreeBSD-SA-18:03.speculative_execution.asc Wed Mar 14 04:14:13 2018 (r51482)
@@ -0,0 +1,206 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-SA-18:03.speculative_execution Security Advisory
+ The FreeBSD Project
+
+Topic: Speculative Execution Vulnerabilities
+
+Category: core
+Module: kernel
+Announced: 2018-03-14
+Credits: Jann Horn (Google Project Zero); Werner Haas, Thomas
+ Prescher (Cyberus Technology); Daniel Gruss, Moritz Lipp,
+ Stefan Mangard, Michael Schwarz (Graz University of
+ Technology); Paul Kocher; Daniel Genkin (University of
+ Pennsylvania and University of Maryland), Mike Hamburg
+ (Rambus); Yuval Yarom (University of Adelaide and Data6)
+Affects: All supported versions of FreeBSD.
+Corrected: 2018-02-17 18:00:01 UTC (stable/11, 11.1-STABLE)
+ 2018-03-14 04:00:00 UTC (releng/11.1, 11.1-RELEASE-p8)
+CVE Name: CVE-2017-5715, CVE-2017-5754
+
+Special Note: Speculative execution vulnerability mitigation is a work
+ in progress. This advisory addresses the most significant
+ issues for FreeBSD 11.1 on amd64 CPUs. We expect to update
+ this advisory to include 10.x for amd64 CPUs. Future FreeBSD
+ releases will address this issue on i386 and other CPUs.
+ freebsd-update will include changes on i386 as part of this
+ update due to common code changes shared between amd64 and
+ i386, however it contains no functional changes for i386 (in
+ particular, it does not mitigate the issue on i386).
+
+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
+
+Many modern processors have implementation issues that allow unprivileged
+attackers to bypass user-kernel or inter-process memory access restrictions
+by exploiting speculative execution and shared resources (for example,
+caches).
+
+II. Problem Description
+
+A number of issues relating to speculative execution were found last year
+and publicly announced January 3rd. Two of these, known as Meltdown and
+Spectre V2, are addressed here.
+
+CVE-2017-5754 (Meltdown)
+- ------------------------
+
+This issue relies on an affected CPU speculatively executing instructions
+beyond a faulting instruction. When this happens, changes to architectural
+state are not committed, but observable changes may be left in micro-
+architectural state (for example, cache). This may be used to infer
+privileged data.
+
+CVE-2017-5715 (Spectre V2)
+- --------------------------
+
+Spectre V2 uses branch target injection to speculatively execute kernel code
+at an address under the control of an attacker.
+
+III. Impact
+
+An attacker may be able to read secret data from the kernel or from a
+process when executing untrusted code (for example, in a web browser).
+
+IV. Workaround
+
+No workaround is available.
+
+V. Solution
+
+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,
+and reboot.
+
+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, followed
+by a reboot into the new kernel:
+
+# freebsd-update fetch
+# freebsd-update install
+# shutdown -r now
+
+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:03/speculative_execution-amd64-11.patch
+# fetch https://security.FreeBSD.org/patches/SA-18:03/speculative_execution-amd64-11.patch.asc
+# gpg --verify speculative_execution-amd64-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
+
+CVE-2017-5754 (Meltdown)
+- ------------------------
+
+The mitigation is known as Page Table Isolation (PTI). PTI largely separates
+kernel and user mode page tables, so that even during speculative execution
+most of the kernel's data is unmapped and not accessible.
+
+A demonstration of the Meltdown vulnerability is available at
+https://github.com/dag-erling/meltdown. A positive result is definitive
+(that is, the vulnerability exists with certainty). A negative result
+indicates either that the CPU is not affected, or that the test is not
+capable of demonstrating the issue on the CPU (and may need to be modified).
+
+A patched kernel will automatically enable PTI on Intel CPUs. The status can
+be checked via the vm.pmap.pti sysctl:
+
+# sysctl vm.pmap.pti
+vm.pmap.pti: 1
+
+The default setting can be overridden by setting the loader tunable
+vm.pmap.pti to 1 or 0 in /boot/loader.conf. This setting takes effect only
+at boot.
+
+PTI introduces a performance regression. The observed performance loss is
+significant in microbenchmarks of system call overhead, but is much smaller
+for many real workloads.
+
+CVE-2017-5715 (Spectre V2)
+- --------------------------
+
+There are two common mitigations for Spectre V2. This patch includes a
+mitigation using Indirect Branch Restricted Speculation, a feature available
+via a microcode update from processor manufacturers. The alternate
+mitigation, Retpoline, is a feature available in newer compilers. The
+feasibility of applying Retpoline to stable branches and/or releases is under
+investigation.
+
+The patch includes the IBRS mitigation for Spectre V2. To use the mitigation
+the system must have an updated microcode; with older microcode a patched
+kernel will function without the mitigation.
+
+IBRS can be disabled via the hw.ibrs_disable sysctl (and tunable), and the
+status can be checked via the hw.ibrs_active sysctl. IBRS may be enabled or
+disabled at runtime. Additional detail on microcode updates will follow.
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path Revision
+- -------------------------------------------------------------------------
+stable/11/ r329462
+releng/11.1/ r330908
+- -------------------------------------------------------------------------
+
+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://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715>
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5754>
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-18:03.speculative_execution.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlqon0RfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cKORw/+Lc5lxLhDgU1rQ0JF6sb2b80Ly5k+rJLXFWBvmEQt0uVyVkF4TMJ99M04
+bcmrLbT4Pl0Csh/iEYvZQ4el12KvPDApHszsLTBgChD+KfCLvCZvBZzasgDWGD0E
+JhL4eIX0wjJ4oGGsT+TAqkmwXyAMJgWW/ZgZPFVXocylZTL3fV4g52VdG1Jnd2yu
+hnkViH2kVlVJqXX9AHlenIUfEmUiRUGrMh5oPPpFYDDmfJ+enZ8QLxfZtOKIliD7
+u+2GP8V/bvaErkxqF5wwobybrBOMXpq9Y/fWw0EH/om7myevj/oORqK+ZmGZ17bl
+IRbdWxgjc1hN2TIMVn9q9xX6i0I0wSPwbpLYagKnSnE8WNVUTZUteaj1GKGTG1rj
+DFH2zOLlbRr/IXUFldM9b6VbZX6G5Ijxwy1DJzB/0KL5ZTbAReUR0pqHR7xpulbJ
+eDv8SKCwYiUpMuwPOXNdVlVLZSsH5/9A0cyjH3+E+eIhM8qyxw7iRFwA0DxnGVkr
+tkMo51Vl3Gl7JFFimGKljsE9mBh00m8B0WYJwknvfhdehO4WripcwI7/V5zL6cwj
+s018kaW4Xm77LOz6P1iN8nbcjZ9gN2AsPYUYYZqJxjCcZ7r489Hg9BhbDf0QtC0R
+gnwZWiZ/KuAy0C6vaHljsm0xPEM5nBz/yScFXDbuhEdmEgBBD6w=
+=fqrI
+-----END PGP SIGNATURE-----
Added: head/share/security/patches/SA-18:03/speculative_execution-amd64-11.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/share/security/patches/SA-18:03/speculative_execution-amd64-11.patch Wed Mar 14 04:14:13 2018 (r51482)
@@ -0,0 +1,4618 @@
+--- sys/amd64/amd64/apic_vector.S.orig
++++ sys/amd64/amd64/apic_vector.S
+@@ -2,7 +2,13 @@
+ * Copyright (c) 1989, 1990 William F. Jolitz.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
++ * Copyright (c) 2014-2018 The FreeBSD Foundation
++ * All rights reserved.
+ *
++ * Portions of this software were developed by
++ * Konstantin Belousov <kib at FreeBSD.org> under sponsorship from
++ * the FreeBSD Foundation.
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+@@ -38,12 +44,12 @@
+
+ #include "opt_smp.h"
+
++#include "assym.s"
++
+ #include <machine/asmacros.h>
+ #include <machine/specialreg.h>
+ #include <x86/apicreg.h>
+
+-#include "assym.s"
+-
+ #ifdef SMP
+ #define LK lock ;
+ #else
+@@ -73,30 +79,28 @@
+ * translates that into a vector, and passes the vector to the
+ * lapic_handle_intr() function.
+ */
+-#define ISR_VEC(index, vec_name) \
+- .text ; \
+- SUPERALIGN_TEXT ; \
+-IDTVEC(vec_name) ; \
+- PUSH_FRAME ; \
+- FAKE_MCOUNT(TF_RIP(%rsp)) ; \
+- cmpl $0,x2apic_mode ; \
+- je 1f ; \
+- movl $(MSR_APIC_ISR0 + index),%ecx ; \
+- rdmsr ; \
+- jmp 2f ; \
+-1: ; \
+- movq lapic_map, %rdx ; /* pointer to local APIC */ \
+- movl LA_ISR + 16 * (index)(%rdx), %eax ; /* load ISR */ \
+-2: ; \
+- bsrl %eax, %eax ; /* index of highest set bit in ISR */ \
+- jz 3f ; \
+- addl $(32 * index),%eax ; \
+- movq %rsp, %rsi ; \
+- movl %eax, %edi ; /* pass the IRQ */ \
+- call lapic_handle_intr ; \
+-3: ; \
+- MEXITCOUNT ; \
++ .macro ISR_VEC index, vec_name
++ INTR_HANDLER \vec_name
++ FAKE_MCOUNT(TF_RIP(%rsp))
++ cmpl $0,x2apic_mode
++ je 1f
++ movl $(MSR_APIC_ISR0 + \index),%ecx
++ rdmsr
++ jmp 2f
++1:
++ movq lapic_map, %rdx /* pointer to local APIC */
++ movl LA_ISR + 16 * (\index)(%rdx), %eax /* load ISR */
++2:
++ bsrl %eax, %eax /* index of highest set bit in ISR */
++ jz 3f
++ addl $(32 * \index),%eax
++ movq %rsp, %rsi
++ movl %eax, %edi /* pass the IRQ */
++ call lapic_handle_intr
++3:
++ MEXITCOUNT
+ jmp doreti
++ .endm
+
+ /*
+ * Handle "spurious INTerrupts".
+@@ -108,26 +112,21 @@
+ .text
+ SUPERALIGN_TEXT
+ IDTVEC(spuriousint)
+-
+ /* No EOI cycle used here */
+-
+ jmp doreti_iret
+
+- ISR_VEC(1, apic_isr1)
+- ISR_VEC(2, apic_isr2)
+- ISR_VEC(3, apic_isr3)
+- ISR_VEC(4, apic_isr4)
+- ISR_VEC(5, apic_isr5)
+- ISR_VEC(6, apic_isr6)
+- ISR_VEC(7, apic_isr7)
++ ISR_VEC 1, apic_isr1
++ ISR_VEC 2, apic_isr2
++ ISR_VEC 3, apic_isr3
++ ISR_VEC 4, apic_isr4
++ ISR_VEC 5, apic_isr5
++ ISR_VEC 6, apic_isr6
++ ISR_VEC 7, apic_isr7
+
+ /*
+ * Local APIC periodic timer handler.
+ */
+- .text
+- SUPERALIGN_TEXT
+-IDTVEC(timerint)
+- PUSH_FRAME
++ INTR_HANDLER timerint
+ FAKE_MCOUNT(TF_RIP(%rsp))
+ movq %rsp, %rdi
+ call lapic_handle_timer
+@@ -137,10 +136,7 @@
+ /*
+ * Local APIC CMCI handler.
+ */
+- .text
+- SUPERALIGN_TEXT
+-IDTVEC(cmcint)
+- PUSH_FRAME
++ INTR_HANDLER cmcint
+ FAKE_MCOUNT(TF_RIP(%rsp))
+ call lapic_handle_cmc
+ MEXITCOUNT
+@@ -149,10 +145,7 @@
+ /*
+ * Local APIC error interrupt handler.
+ */
+- .text
+- SUPERALIGN_TEXT
+-IDTVEC(errorint)
+- PUSH_FRAME
++ INTR_HANDLER errorint
+ FAKE_MCOUNT(TF_RIP(%rsp))
+ call lapic_handle_error
+ MEXITCOUNT
+@@ -163,10 +156,7 @@
+ * Xen event channel upcall interrupt handler.
+ * Only used when the hypervisor supports direct vector callbacks.
+ */
+- .text
+- SUPERALIGN_TEXT
+-IDTVEC(xen_intr_upcall)
+- PUSH_FRAME
++ INTR_HANDLER xen_intr_upcall
+ FAKE_MCOUNT(TF_RIP(%rsp))
+ movq %rsp, %rdi
+ call xen_intr_handle_upcall
+@@ -183,59 +173,59 @@
+ SUPERALIGN_TEXT
+ invltlb_ret:
+ call as_lapic_eoi
+- POP_FRAME
+- jmp doreti_iret
++ jmp ld_regs
+
+ SUPERALIGN_TEXT
+-IDTVEC(invltlb)
+- PUSH_FRAME
+-
++ INTR_HANDLER invltlb
+ call invltlb_handler
+ jmp invltlb_ret
+
+-IDTVEC(invltlb_pcid)
+- PUSH_FRAME
+-
++ INTR_HANDLER invltlb_pcid
+ call invltlb_pcid_handler
+ jmp invltlb_ret
+
+-IDTVEC(invltlb_invpcid)
+- PUSH_FRAME
+-
++ INTR_HANDLER invltlb_invpcid_nopti
+ call invltlb_invpcid_handler
+ jmp invltlb_ret
+
++ INTR_HANDLER invltlb_invpcid_pti
++ call invltlb_invpcid_pti_handler
++ jmp invltlb_ret
++
+ /*
+ * Single page TLB shootdown
+ */
+- .text
++ INTR_HANDLER invlpg
++ call invlpg_handler
++ jmp invltlb_ret
+
+- SUPERALIGN_TEXT
+-IDTVEC(invlpg)
+- PUSH_FRAME
++ INTR_HANDLER invlpg_invpcid
++ call invlpg_invpcid_handler
++ jmp invltlb_ret
+
+- call invlpg_handler
++ INTR_HANDLER invlpg_pcid
++ call invlpg_pcid_handler
+ jmp invltlb_ret
+
+ /*
+ * Page range TLB shootdown.
+ */
+- .text
+- SUPERALIGN_TEXT
+-IDTVEC(invlrng)
+- PUSH_FRAME
+-
++ INTR_HANDLER invlrng
+ call invlrng_handler
+ jmp invltlb_ret
+
++ INTR_HANDLER invlrng_invpcid
++ call invlrng_invpcid_handler
++ jmp invltlb_ret
++
++ INTR_HANDLER invlrng_pcid
++ call invlrng_pcid_handler
++ jmp invltlb_ret
++
+ /*
+ * Invalidate cache.
+ */
+- .text
+- SUPERALIGN_TEXT
+-IDTVEC(invlcache)
+- PUSH_FRAME
+-
++ INTR_HANDLER invlcache
+ call invlcache_handler
+ jmp invltlb_ret
+
+@@ -242,15 +232,9 @@
+ /*
+ * Handler for IPIs sent via the per-cpu IPI bitmap.
+ */
+- .text
+- SUPERALIGN_TEXT
+-IDTVEC(ipi_intr_bitmap_handler)
+- PUSH_FRAME
+-
++ INTR_HANDLER ipi_intr_bitmap_handler
+ call as_lapic_eoi
+-
+ FAKE_MCOUNT(TF_RIP(%rsp))
+-
+ call ipi_bitmap_handler
+ MEXITCOUNT
+ jmp doreti
+@@ -258,13 +242,8 @@
+ /*
+ * Executed by a CPU when it receives an IPI_STOP from another CPU.
+ */
+- .text
+- SUPERALIGN_TEXT
+-IDTVEC(cpustop)
+- PUSH_FRAME
+-
++ INTR_HANDLER cpustop
+ call as_lapic_eoi
+-
+ call cpustop_handler
+ jmp doreti
+
+@@ -271,11 +250,7 @@
+ /*
+ * Executed by a CPU when it receives an IPI_SUSPEND from another CPU.
+ */
+- .text
+- SUPERALIGN_TEXT
+-IDTVEC(cpususpend)
+- PUSH_FRAME
+-
++ INTR_HANDLER cpususpend
+ call cpususpend_handler
+ call as_lapic_eoi
+ jmp doreti
+@@ -285,10 +260,7 @@
+ *
+ * - Calls the generic rendezvous action function.
+ */
+- .text
+- SUPERALIGN_TEXT
+-IDTVEC(rendezvous)
+- PUSH_FRAME
++ INTR_HANDLER rendezvous
+ #ifdef COUNT_IPIS
+ movl PCPU(CPUID), %eax
+ movq ipi_rendezvous_counts(,%rax,8), %rax
+@@ -328,4 +300,8 @@
+ popq %rax
+ jmp doreti_iret
+
++ INTR_HANDLER justreturn1
++ call as_lapic_eoi
++ jmp doreti
++
+ #endif /* SMP */
+--- sys/amd64/amd64/atpic_vector.S.orig
++++ sys/amd64/amd64/atpic_vector.S
+@@ -36,38 +36,35 @@
+ * master and slave interrupt controllers.
+ */
+
++#include "assym.s"
+ #include <machine/asmacros.h>
+
+-#include "assym.s"
+-
+ /*
+ * Macros for interrupt entry, call to handler, and exit.
+ */
+-#define INTR(irq_num, vec_name) \
+- .text ; \
+- SUPERALIGN_TEXT ; \
+-IDTVEC(vec_name) ; \
+- PUSH_FRAME ; \
+- FAKE_MCOUNT(TF_RIP(%rsp)) ; \
+- movq %rsp, %rsi ; \
+- movl $irq_num, %edi; /* pass the IRQ */ \
+- call atpic_handle_intr ; \
+- MEXITCOUNT ; \
++ .macro INTR irq_num, vec_name
++ INTR_HANDLER \vec_name
++ FAKE_MCOUNT(TF_RIP(%rsp))
++ movq %rsp, %rsi
++ movl $\irq_num, %edi /* pass the IRQ */
++ call atpic_handle_intr
++ MEXITCOUNT
+ jmp doreti
++ .endm
+
+- INTR(0, atpic_intr0)
+- INTR(1, atpic_intr1)
+- INTR(2, atpic_intr2)
+- INTR(3, atpic_intr3)
+- INTR(4, atpic_intr4)
+- INTR(5, atpic_intr5)
+- INTR(6, atpic_intr6)
+- INTR(7, atpic_intr7)
+- INTR(8, atpic_intr8)
+- INTR(9, atpic_intr9)
+- INTR(10, atpic_intr10)
+- INTR(11, atpic_intr11)
+- INTR(12, atpic_intr12)
+- INTR(13, atpic_intr13)
+- INTR(14, atpic_intr14)
+- INTR(15, atpic_intr15)
++ INTR 0, atpic_intr0
++ INTR 1, atpic_intr1
++ INTR 2, atpic_intr2
++ INTR 3, atpic_intr3
++ INTR 4, atpic_intr4
++ INTR 5, atpic_intr5
++ INTR 6, atpic_intr6
++ INTR 7, atpic_intr7
++ INTR 8, atpic_intr8
++ INTR 9, atpic_intr9
++ INTR 10, atpic_intr10
++ INTR 11, atpic_intr11
++ INTR 12, atpic_intr12
++ INTR 13, atpic_intr13
++ INTR 14, atpic_intr14
++ INTR 15, atpic_intr15
+--- sys/amd64/amd64/cpu_switch.S.orig
++++ sys/amd64/amd64/cpu_switch.S
+@@ -191,9 +191,11 @@
+ done_tss:
+ movq %r8,PCPU(RSP0)
+ movq %r8,PCPU(CURPCB)
+- /* Update the TSS_RSP0 pointer for the next interrupt */
++ /* Update the COMMON_TSS_RSP0 pointer for the next interrupt */
++ cmpb $0,pti(%rip)
++ jne 1f
+ movq %r8,COMMON_TSS_RSP0(%rdx)
+- movq %r12,PCPU(CURTHREAD) /* into next thread */
++1: movq %r12,PCPU(CURTHREAD) /* into next thread */
+
+ /* Test if debug registers should be restored. */
+ testl $PCB_DBREGS,PCB_FLAGS(%r8)
+@@ -270,7 +272,12 @@
+ shrq $8,%rcx
+ movl %ecx,8(%rax)
+ movb $0x89,5(%rax) /* unset busy */
+- movl $TSSSEL,%eax
++ cmpb $0,pti(%rip)
++ je 1f
++ movq PCPU(PRVSPACE),%rax
++ addq $PC_PTI_STACK+PC_PTI_STACK_SZ*8,%rax
++ movq %rax,COMMON_TSS_RSP0(%rdx)
++1: movl $TSSSEL,%eax
+ ltr %ax
+ jmp done_tss
+
+--- sys/amd64/amd64/db_trace.c.orig
++++ sys/amd64/amd64/db_trace.c
+@@ -200,6 +200,7 @@
+ if (name != NULL) {
+ if (strcmp(name, "calltrap") == 0 ||
+ strcmp(name, "fork_trampoline") == 0 ||
++ strcmp(name, "mchk_calltrap") == 0 ||
+ strcmp(name, "nmi_calltrap") == 0 ||
+ strcmp(name, "Xdblfault") == 0)
+ frame_type = TRAP;
+--- sys/amd64/amd64/exception.S.orig
++++ sys/amd64/amd64/exception.S
+@@ -1,12 +1,16 @@
+ /*-
+ * Copyright (c) 1989, 1990 William F. Jolitz.
+ * Copyright (c) 1990 The Regents of the University of California.
+- * Copyright (c) 2007 The FreeBSD Foundation
++ * Copyright (c) 2007-2018 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by A. Joseph Koshy under
+ * sponsorship from the FreeBSD Foundation and Google, Inc.
+ *
++ * Portions of this software were developed by
++ * Konstantin Belousov <kib at FreeBSD.org> under sponsorship from
++ * the FreeBSD Foundation.
++ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+@@ -38,13 +42,13 @@
+ #include "opt_compat.h"
+ #include "opt_hwpmc_hooks.h"
+
++#include "assym.s"
++
+ #include <machine/asmacros.h>
+ #include <machine/psl.h>
+ #include <machine/trap.h>
+ #include <machine/specialreg.h>
+
+-#include "assym.s"
+-
+ #ifdef KDTRACE_HOOKS
+ .bss
+ .globl dtrace_invop_jump_addr
+@@ -100,69 +104,62 @@
+ MCOUNT_LABEL(user)
+ MCOUNT_LABEL(btrap)
+
+-/* Traps that we leave interrupts disabled for.. */
+-#define TRAP_NOEN(a) \
+- subq $TF_RIP,%rsp; \
+- movl $(a),TF_TRAPNO(%rsp) ; \
+- movq $0,TF_ADDR(%rsp) ; \
+- movq $0,TF_ERR(%rsp) ; \
++/* Traps that we leave interrupts disabled for. */
++ .macro TRAP_NOEN l, trapno
++ PTI_ENTRY \l,X\l
++ .globl X\l
++ .type X\l, at function
++X\l: subq $TF_RIP,%rsp
++ movl $\trapno,TF_TRAPNO(%rsp)
++ movq $0,TF_ADDR(%rsp)
++ movq $0,TF_ERR(%rsp)
+ jmp alltraps_noen
+-IDTVEC(dbg)
+- TRAP_NOEN(T_TRCTRAP)
+-IDTVEC(bpt)
+- TRAP_NOEN(T_BPTFLT)
++ .endm
++
++ TRAP_NOEN dbg, T_TRCTRAP
++ TRAP_NOEN bpt, T_BPTFLT
+ #ifdef KDTRACE_HOOKS
+-IDTVEC(dtrace_ret)
+- TRAP_NOEN(T_DTRACE_RET)
++ TRAP_NOEN dtrace_ret, T_DTRACE_RET
+ #endif
+
+ /* Regular traps; The cpu does not supply tf_err for these. */
+-#define TRAP(a) \
+- subq $TF_RIP,%rsp; \
+- movl $(a),TF_TRAPNO(%rsp) ; \
+- movq $0,TF_ADDR(%rsp) ; \
+- movq $0,TF_ERR(%rsp) ; \
++ .macro TRAP l, trapno
++ PTI_ENTRY \l,X\l
++ .globl X\l
++ .type X\l, at function
++X\l:
++ subq $TF_RIP,%rsp
++ movl $\trapno,TF_TRAPNO(%rsp)
++ movq $0,TF_ADDR(%rsp)
++ movq $0,TF_ERR(%rsp)
+ jmp alltraps
+-IDTVEC(div)
+- TRAP(T_DIVIDE)
+-IDTVEC(ofl)
+- TRAP(T_OFLOW)
+-IDTVEC(bnd)
+- TRAP(T_BOUND)
+-IDTVEC(ill)
+- TRAP(T_PRIVINFLT)
+-IDTVEC(dna)
+- TRAP(T_DNA)
+-IDTVEC(fpusegm)
+- TRAP(T_FPOPFLT)
+-IDTVEC(mchk)
+- TRAP(T_MCHK)
+-IDTVEC(rsvd)
+- TRAP(T_RESERVED)
+-IDTVEC(fpu)
+- TRAP(T_ARITHTRAP)
+-IDTVEC(xmm)
+- TRAP(T_XMMFLT)
++ .endm
+
+-/* This group of traps have tf_err already pushed by the cpu */
+-#define TRAP_ERR(a) \
+- subq $TF_ERR,%rsp; \
+- movl $(a),TF_TRAPNO(%rsp) ; \
+- movq $0,TF_ADDR(%rsp) ; \
++ TRAP div, T_DIVIDE
++ TRAP ofl, T_OFLOW
++ TRAP bnd, T_BOUND
++ TRAP ill, T_PRIVINFLT
++ TRAP dna, T_DNA
++ TRAP fpusegm, T_FPOPFLT
++ TRAP rsvd, T_RESERVED
++ TRAP fpu, T_ARITHTRAP
++ TRAP xmm, T_XMMFLT
++
++/* This group of traps have tf_err already pushed by the cpu. */
++ .macro TRAP_ERR l, trapno
++ PTI_ENTRY \l,X\l,has_err=1
++ .globl X\l
++ .type X\l, at function
++X\l:
++ subq $TF_ERR,%rsp
++ movl $\trapno,TF_TRAPNO(%rsp)
++ movq $0,TF_ADDR(%rsp)
+ jmp alltraps
+-IDTVEC(tss)
+- TRAP_ERR(T_TSSFLT)
+-IDTVEC(missing)
+- subq $TF_ERR,%rsp
+- movl $T_SEGNPFLT,TF_TRAPNO(%rsp)
+- jmp prot_addrf
+-IDTVEC(stk)
+- subq $TF_ERR,%rsp
+- movl $T_STKFLT,TF_TRAPNO(%rsp)
+- jmp prot_addrf
+-IDTVEC(align)
+- TRAP_ERR(T_ALIGNFLT)
++ .endm
+
++ TRAP_ERR tss, T_TSSFLT
++ TRAP_ERR align, T_ALIGNFLT
++
+ /*
+ * alltraps entry point. Use swapgs if this is the first time in the
+ * kernel from userland. Reenable interrupts if they were enabled
+@@ -174,25 +171,24 @@
+ alltraps:
+ movq %rdi,TF_RDI(%rsp)
+ testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
+- jz alltraps_testi /* already running with kernel GS.base */
++ jz 1f /* already running with kernel GS.base */
+ swapgs
+ movq PCPU(CURPCB),%rdi
+ andl $~PCB_FULL_IRET,PCB_FLAGS(%rdi)
+- movw %fs,TF_FS(%rsp)
+- movw %gs,TF_GS(%rsp)
+- movw %es,TF_ES(%rsp)
+- movw %ds,TF_DS(%rsp)
+-alltraps_testi:
+- testl $PSL_I,TF_RFLAGS(%rsp)
+- jz alltraps_pushregs_no_rdi
++1: SAVE_SEGS
++ movq %rdx,TF_RDX(%rsp)
++ movq %rax,TF_RAX(%rsp)
++ movq %rcx,TF_RCX(%rsp)
++ testb $SEL_RPL_MASK,TF_CS(%rsp)
++ jz 2f
++ call handle_ibrs_entry
++2: testl $PSL_I,TF_RFLAGS(%rsp)
++ jz alltraps_pushregs_no_rax
+ sti
+-alltraps_pushregs_no_rdi:
++alltraps_pushregs_no_rax:
+ movq %rsi,TF_RSI(%rsp)
+- movq %rdx,TF_RDX(%rsp)
+- movq %rcx,TF_RCX(%rsp)
+ movq %r8,TF_R8(%rsp)
+ movq %r9,TF_R9(%rsp)
+- movq %rax,TF_RAX(%rsp)
+ movq %rbx,TF_RBX(%rsp)
+ movq %rbp,TF_RBP(%rsp)
+ movq %r10,TF_R10(%rsp)
+@@ -248,15 +244,18 @@
+ alltraps_noen:
+ movq %rdi,TF_RDI(%rsp)
+ testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
+- jz 1f /* already running with kernel GS.base */
++ jz 1f /* already running with kernel GS.base */
+ swapgs
+ movq PCPU(CURPCB),%rdi
+ andl $~PCB_FULL_IRET,PCB_FLAGS(%rdi)
+-1: movw %fs,TF_FS(%rsp)
+- movw %gs,TF_GS(%rsp)
+- movw %es,TF_ES(%rsp)
+- movw %ds,TF_DS(%rsp)
+- jmp alltraps_pushregs_no_rdi
++1: SAVE_SEGS
++ movq %rdx,TF_RDX(%rsp)
++ movq %rax,TF_RAX(%rsp)
++ movq %rcx,TF_RCX(%rsp)
++ testb $SEL_RPL_MASK,TF_CS(%rsp)
++ jz alltraps_pushregs_no_rax
++ call handle_ibrs_entry
++ jmp alltraps_pushregs_no_rax
+
+ IDTVEC(dblfault)
+ subq $TF_ERR,%rsp
+@@ -278,10 +277,7 @@
+ movq %r13,TF_R13(%rsp)
+ movq %r14,TF_R14(%rsp)
+ movq %r15,TF_R15(%rsp)
+- movw %fs,TF_FS(%rsp)
+- movw %gs,TF_GS(%rsp)
+- movw %es,TF_ES(%rsp)
+- movw %ds,TF_DS(%rsp)
++ SAVE_SEGS
+ movl $TF_HASSEGS,TF_FLAGS(%rsp)
+ cld
+ testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
+@@ -288,31 +284,54 @@
+ jz 1f /* already running with kernel GS.base */
+ swapgs
+ 1:
+- movq %rsp,%rdi
++ movq PCPU(KCR3),%rax
++ cmpq $~0,%rax
++ je 2f
++ movq %rax,%cr3
++2: movq %rsp,%rdi
+ call dblfault_handler
+-2:
+- hlt
+- jmp 2b
++3: hlt
++ jmp 3b
+
++ ALIGN_TEXT
++IDTVEC(page_pti)
++ testb $SEL_RPL_MASK,PTI_CS-2*8(%rsp)
++ jz Xpage
++ swapgs
++ pushq %rax
++ pushq %rdx
++ movq %cr3,%rax
++ movq %rax,PCPU(SAVED_UCR3)
++ PTI_UUENTRY has_err=1
++ subq $TF_ERR,%rsp
++ movq %rdi,TF_RDI(%rsp)
++ movq %rax,TF_RAX(%rsp)
++ movq %rdx,TF_RDX(%rsp)
++ movq %rcx,TF_RCX(%rsp)
++ jmp page_u
+ IDTVEC(page)
+ subq $TF_ERR,%rsp
+- movl $T_PAGEFLT,TF_TRAPNO(%rsp)
+- movq %rdi,TF_RDI(%rsp) /* free up a GP register */
++ movq %rdi,TF_RDI(%rsp) /* free up GP registers */
++ movq %rax,TF_RAX(%rsp)
++ movq %rdx,TF_RDX(%rsp)
++ movq %rcx,TF_RCX(%rsp)
+ testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
+- jz 1f /* already running with kernel GS.base */
++ jz page_cr2 /* already running with kernel GS.base */
+ swapgs
+- movq PCPU(CURPCB),%rdi
++page_u: movq PCPU(CURPCB),%rdi
+ andl $~PCB_FULL_IRET,PCB_FLAGS(%rdi)
+-1: movq %cr2,%rdi /* preserve %cr2 before .. */
++ movq PCPU(SAVED_UCR3),%rax
++ movq %rax,PCB_SAVED_UCR3(%rdi)
++ call handle_ibrs_entry
++page_cr2:
++ movq %cr2,%rdi /* preserve %cr2 before .. */
+ movq %rdi,TF_ADDR(%rsp) /* enabling interrupts. */
+- movw %fs,TF_FS(%rsp)
+- movw %gs,TF_GS(%rsp)
+- movw %es,TF_ES(%rsp)
+- movw %ds,TF_DS(%rsp)
++ SAVE_SEGS
++ movl $T_PAGEFLT,TF_TRAPNO(%rsp)
+ testl $PSL_I,TF_RFLAGS(%rsp)
+- jz alltraps_pushregs_no_rdi
++ jz alltraps_pushregs_no_rax
+ sti
+- jmp alltraps_pushregs_no_rdi
++ jmp alltraps_pushregs_no_rax
+
+ /*
+ * We have to special-case this one. If we get a trap in doreti() at
+@@ -319,30 +338,71 @@
+ * the iretq stage, we'll reenter with the wrong gs state. We'll have
+ * to do a special the swapgs in this case even coming from the kernel.
+ * XXX linux has a trap handler for their equivalent of load_gs().
++ *
++ * On the stack, we have the hardware interrupt frame to return
++ * to usermode (faulted) and another frame with error code, for
++ * fault. For PTI, copy both frames to the main thread stack.
+ */
+-IDTVEC(prot)
++ .macro PROTF_ENTRY name,trapno
++\name\()_pti_doreti:
++ pushq %rax
++ pushq %rdx
++ swapgs
++ movq PCPU(KCR3),%rax
++ movq %rax,%cr3
++ movq PCPU(RSP0),%rax
++ subq $2*PTI_SIZE-3*8,%rax /* no err, %rax, %rdx in faulted frame */
++ MOVE_STACKS (PTI_SIZE / 4 - 3)
++ movq %rax,%rsp
++ popq %rdx
++ popq %rax
++ swapgs
++ jmp X\name
++IDTVEC(\name\()_pti)
++ cmpq $doreti_iret,PTI_RIP-2*8(%rsp)
++ je \name\()_pti_doreti
++ testb $SEL_RPL_MASK,PTI_CS-2*8(%rsp) /* %rax, %rdx not yet pushed */
++ jz X\name
++ PTI_UENTRY has_err=1
++ swapgs
++IDTVEC(\name)
+ subq $TF_ERR,%rsp
+- movl $T_PROTFLT,TF_TRAPNO(%rsp)
++ movl $\trapno,TF_TRAPNO(%rsp)
++ jmp prot_addrf
++ .endm
++
++ PROTF_ENTRY missing, T_SEGNPFLT
++ PROTF_ENTRY stk, T_STKFLT
++ PROTF_ENTRY prot, T_PROTFLT
++
+ prot_addrf:
+ movq $0,TF_ADDR(%rsp)
+ movq %rdi,TF_RDI(%rsp) /* free up a GP register */
++ movq %rax,TF_RAX(%rsp)
++ movq %rdx,TF_RDX(%rsp)
++ movq %rcx,TF_RCX(%rsp)
++ movw %fs,TF_FS(%rsp)
++ movw %gs,TF_GS(%rsp)
+ leaq doreti_iret(%rip),%rdi
+ cmpq %rdi,TF_RIP(%rsp)
+- je 1f /* kernel but with user gsbase!! */
++ je 5f /* kernel but with user gsbase!! */
+ testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
+- jz 2f /* already running with kernel GS.base */
+-1: swapgs
+-2: movq PCPU(CURPCB),%rdi
++ jz 6f /* already running with kernel GS.base */
++ swapgs
++ movq PCPU(CURPCB),%rdi
++4: call handle_ibrs_entry
+ orl $PCB_FULL_IRET,PCB_FLAGS(%rdi) /* always full iret from GPF */
+- movw %fs,TF_FS(%rsp)
+- movw %gs,TF_GS(%rsp)
+ movw %es,TF_ES(%rsp)
+ movw %ds,TF_DS(%rsp)
+ testl $PSL_I,TF_RFLAGS(%rsp)
+- jz alltraps_pushregs_no_rdi
++ jz alltraps_pushregs_no_rax
+ sti
+- jmp alltraps_pushregs_no_rdi
++ jmp alltraps_pushregs_no_rax
+
++5: swapgs
++6: movq PCPU(CURPCB),%rdi
++ jmp 4b
++
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-doc-head
mailing list