Date: Wed, 14 Mar 2018 04:14:14 +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: r51482 - in head/share: security/advisories security/patches/SA-18:03 xml Message-ID: <201803140414.w2E4EEd4066873@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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@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@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,@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,@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,@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 ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803140414.w2E4EEd4066873>