freebsd-skq/sys
Konstantin Belousov bd50262f70 PTI for amd64.
The implementation of the Kernel Page Table Isolation (KPTI) for
amd64, first version. It provides a workaround for the 'meltdown'
vulnerability.  PTI is turned off by default for now, enable with the
loader tunable vm.pmap.pti=1.

The pmap page table is split into kernel-mode table and user-mode
table. Kernel-mode table is identical to the non-PTI table, while
usermode table is obtained from kernel table by leaving userspace
mappings intact, but only leaving the following parts of the kernel
mapped:

    kernel text (but not modules text)
    PCPU
    GDT/IDT/user LDT/task structures
    IST stacks for NMI and doublefault handlers.

Kernel switches to user page table before returning to usermode, and
restores full kernel page table on the entry. Initial kernel-mode
stack for PTI trampoline is allocated in PCPU, it is only 16
qwords.  Kernel entry trampoline switches page tables. then the
hardware trap frame is copied to the normal kstack, and execution
continues.

IST stacks are kept mapped and no trampoline is needed for
NMI/doublefault, but of course page table switch is performed.

On return to usermode, the trampoline is used again, iret frame is
copied to the trampoline stack, page tables are switched and iretq is
executed.  The case of iretq faulting due to the invalid usermode
context is tricky, since the frame for fault is appended to the
trampoline frame.  Besides copying the fault frame and original
(corrupted) frame to kstack, the fault frame must be patched to make
it look as if the fault occured on the kstack, see the comment in
doret_iret detection code in trap().

Currently kernel pages which are mapped during trampoline operation
are identical for all pmaps.  They are registered using
pmap_pti_add_kva().  Besides initial registrations done during boot,
LDT and non-common TSS segments are registered if user requested their
use.  In principle, they can be installed into kernel page table per
pmap with some work.  Similarly, PCPU can be hidden from userspace
mapping using trampoline PCPU page, but again I do not see much
benefits besides complexity.

PDPE pages for the kernel half of the user page tables are
pre-allocated during boot because we need to know pml4 entries which
are copied to the top-level paging structure page, in advance on a new
pmap creation.  I enforce this to avoid iterating over the all
existing pmaps if a new PDPE page is needed for PTI kernel mappings.
The iteration is a known problematic operation on i386.

The need to flush hidden kernel translations on the switch to user
mode make global tables (PG_G) meaningless and even harming, so PG_G
use is disabled for PTI case.  Our existing use of PCID is
incompatible with PTI and is automatically disabled if PTI is
enabled.  PCID can be forced on only for developer's benefit.

MCE is known to be broken, it requires IST stack to operate completely
correctly even for non-PTI case, and absolutely needs dedicated IST
stack because MCE delivery while trampoline did not switched from PTI
stack is fatal.  The fix is pending.

Reviewed by:	markj (partially)
Tested by:	pho (previous version)
Discussed with:	jeff, jhb
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
2018-01-17 11:44:21 +00:00
..
amd64 PTI for amd64. 2018-01-17 11:44:21 +00:00
arm arm: make some use of mallocarray(9). 2018-01-15 21:09:58 +00:00
arm64 arm: make some use of mallocarray(9). 2018-01-15 21:09:58 +00:00
bsm sys: further adoption of SPDX licensing ID tags. 2017-11-20 19:43:44 +00:00
cam SPDX: finish tagging sys/cam. 2018-01-16 23:19:57 +00:00
cddl Use the thread's ucred struct when fetching jid or jailname. 2018-01-14 17:55:40 +00:00
compat ndis: make some use of mallocarray(9). 2018-01-15 21:11:38 +00:00
conf Use ln -n instead of -h to allow building the kernel on Linux 2018-01-16 21:43:57 +00:00
contrib zstd: Use mallocarray(9) for calloc macro. 2018-01-13 19:02:51 +00:00
crypto Merge ^/head r327624 through r327885. 2018-01-12 18:23:35 +00:00
ddb Implement 'domainset', a cpuset based NUMA policy mechanism. This allows 2018-01-12 22:48:23 +00:00
dev PTI for amd64. 2018-01-17 11:44:21 +00:00
dts Add a rudimentary PWM driver for the RaspberryPi. 2018-01-14 20:36:21 +00:00
fs ext2fs: use mallocarray(9). 2018-01-16 19:29:32 +00:00
gdb sys/gdb: further adoption of SPDX licensing ID tags. 2017-11-27 15:16:59 +00:00
geom misc geom and gnu: make some use of mallocarray(9). 2018-01-15 21:23:16 +00:00
gnu misc geom and gnu: make some use of mallocarray(9). 2018-01-15 21:23:16 +00:00
i386 PTI for amd64. 2018-01-17 11:44:21 +00:00
isa On further testing on actual machines with this hardware, we should 2017-12-30 08:16:31 +00:00
kern kern: make some use of mallocarray(9). 2018-01-15 21:18:04 +00:00
kgssapi sys/kgssapi: general adoption of SPDX licensing ID tags. 2017-11-27 15:49:00 +00:00
libkern SPDX: fix wrong license ID tag in libkern. 2017-12-28 01:20:30 +00:00
mips Fix build after r328020. 2018-01-16 06:04:39 +00:00
modules Add a rudimentary PWM driver for the RaspberryPi. 2018-01-14 20:36:21 +00:00
net net*: make some use of mallocarray(9). 2018-01-15 21:21:51 +00:00
net80211 net80211: sanitize input for ieee80211_output() 2017-12-30 00:40:34 +00:00
netgraph netgraph: make some use of mallocarray(9). 2018-01-15 21:19:21 +00:00
netinet Fix a bug related to fast retransmissions. 2018-01-16 21:58:38 +00:00
netinet6 net*: make some use of mallocarray(9). 2018-01-15 21:21:51 +00:00
netipsec Do pass removing some write-only variables from the kernel. 2017-12-25 04:48:39 +00:00
netpfil Implement 'domainset', a cpuset based NUMA policy mechanism. This allows 2018-01-12 22:48:23 +00:00
netsmb sys: general adoption of SPDX licensing ID tags. 2017-11-27 15:23:17 +00:00
nfs Do pass removing some write-only variables from the kernel. 2017-12-25 04:48:39 +00:00
nfsclient sys: general adoption of SPDX licensing ID tags. 2017-11-27 15:23:17 +00:00
nfsserver sys: general adoption of SPDX licensing ID tags. 2017-11-27 15:23:17 +00:00
nlm Do pass removing some write-only variables from the kernel. 2017-12-25 04:48:39 +00:00
ofed sys: general adoption of SPDX licensing ID tags. 2017-11-27 15:23:17 +00:00
opencrypto Split crp_buf into a union. 2018-01-16 19:41:18 +00:00
powerpc PPC64: implement missing busdma ops 2018-01-17 09:45:18 +00:00
riscv Implement NUMA support in uma(9) and malloc(9). Allocations from specific 2018-01-12 23:25:05 +00:00
rpc Do pass removing some write-only variables from the kernel. 2017-12-25 04:48:39 +00:00
security Do pass removing some write-only variables from the kernel. 2017-12-25 04:48:39 +00:00
sparc64 Implement NUMA support in uma(9) and malloc(9). Allocations from specific 2018-01-12 23:25:05 +00:00
sys random(4): Add CCP random source definitions 2018-01-16 02:56:27 +00:00
teken sys: general adoption of SPDX licensing ID tags. 2017-11-27 15:23:17 +00:00
tests
tools embed_mfs: correctly test grep return value 2018-01-03 19:22:10 +00:00
ufs Softlink inodes can own buffers with dependencies. 2018-01-11 13:37:45 +00:00
vm Move VM_NUMA_ALLOC and DEVICE_NUMA under the single global config option NUMA. 2018-01-14 03:36:03 +00:00
x86 PTI for amd64. 2018-01-17 11:44:21 +00:00
xdr sys: general adoption of SPDX licensing ID tags. 2017-11-27 15:23:17 +00:00
xen sys: general adoption of SPDX licensing ID tags. 2017-11-27 15:23:17 +00:00
Makefile Move sys/boot to stand. Fix all references to new location 2017-11-14 23:02:19 +00:00