diff options
| author | Robert Mustacchi <rm@joyent.com> | 2019-05-01 05:01:35 +0000 |
|---|---|---|
| committer | Robert Mustacchi <rm@joyent.com> | 2019-05-14 17:39:44 +0000 |
| commit | a129b6ac948a795e06506944867eb18a238526d1 (patch) | |
| tree | 28d30f368372affc8cac1253effc101439a2c802 /usr/src/uts/i86pc/ml | |
| parent | 5ee58e69654ffd86bb4f050263de0c9da75fa28f (diff) | |
| download | illumos-joyent-a129b6ac948a795e06506944867eb18a238526d1.tar.gz | |
OS-7793 Need mitigation for MDS
Reviewed by: John Levon <john.levon@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Approved by: Jerry Jelinek <jerry.jelinek@joyent.com>
Diffstat (limited to 'usr/src/uts/i86pc/ml')
| -rw-r--r-- | usr/src/uts/i86pc/ml/locore.s | 5 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/ml/md_clear.s | 61 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/ml/syscall_asm_amd64.s | 24 |
3 files changed, 88 insertions, 2 deletions
diff --git a/usr/src/uts/i86pc/ml/locore.s b/usr/src/uts/i86pc/ml/locore.s index 10db95ab51..236f03b4ea 100644 --- a/usr/src/uts/i86pc/ml/locore.s +++ b/usr/src/uts/i86pc/ml/locore.s @@ -23,7 +23,7 @@ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright (c) 2018 Joyent, Inc. + * Copyright 2019 Joyent, Inc. */ /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ @@ -1191,6 +1191,7 @@ cmntrap() addq %rax, %r12 movq %r12, REGOFF_RIP(%rbp) INTR_POP + call *x86_md_clear jmp tr_iret_auto /*NOTREACHED*/ 3: @@ -1596,6 +1597,7 @@ _lwp_rtt: */ ALTENTRY(sys_rtt_syscall32) USER32_POP + call *x86_md_clear jmp tr_iret_user /*NOTREACHED*/ @@ -1605,6 +1607,7 @@ _lwp_rtt: */ USER_POP ALTENTRY(nopop_sys_rtt_syscall) + call *x86_md_clear jmp tr_iret_user /*NOTREACHED*/ SET_SIZE(nopop_sys_rtt_syscall) diff --git a/usr/src/uts/i86pc/ml/md_clear.s b/usr/src/uts/i86pc/ml/md_clear.s new file mode 100644 index 0000000000..50302b43c7 --- /dev/null +++ b/usr/src/uts/i86pc/ml/md_clear.s @@ -0,0 +1,61 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019 Joyent, Inc. + */ + +#include <sys/asm_linkage.h> + +/* + * This ASM file contains various routines that are designed to flush + * microarchitectural buffer state as part of dealing with the + * microarchitectural data sampling (MDS) vulnerabilities. + * + * These are called from various points in the system ranging from interrupts, + * before going idle, to returning from system calls. This means the following + * is true about the state of the system: + * + * o All register state is precious, we must not change register state upon + * entry or return from these functions. + * + * o %ds is valid. + * + * o %gs is arbitrary, it may be kernel or user. You cannot rely on it. + * + * o Interrupts should be disabled by the caller. + * + * o %cr3 is on the kernel-side and therefore we still have access to kernel + * text. In other words, we haven't switched back to the user page table. + * + * o It is up to the caller to insure that a sufficient serializing instruction + * has been executed after this to make sure any pending speculations are + * captured. In general, this should be handled by the fact that callers of + * this are either going to change privilege levels or halt, which makes + * these operations safer. + */ + ENTRY_NP(x86_md_clear_noop) + ret + SET_SIZE(x86_md_clear_noop) + + /* + * This uses the microcode based means of flushing state. VERW will + * clobber flags. + */ + ENTRY_NP(x86_md_clear_verw) + pushfq + subq $8, %rsp + mov %ds, (%rsp) + verw (%rsp) + addq $8, %rsp + popfq + ret + SET_SIZE(x86_md_clear_verw) diff --git a/usr/src/uts/i86pc/ml/syscall_asm_amd64.s b/usr/src/uts/i86pc/ml/syscall_asm_amd64.s index 9727110109..9bf9db47bf 100644 --- a/usr/src/uts/i86pc/ml/syscall_asm_amd64.s +++ b/usr/src/uts/i86pc/ml/syscall_asm_amd64.s @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2018 Joyent, Inc. + * Copyright 2019 Joyent, Inc. * Copyright (c) 2016 by Delphix. All rights reserved. */ @@ -678,6 +678,16 @@ _syscall_after_brand: ASSERT_CR0TS_ZERO(%r11) /* + * Unlike other cases, because we need to restore the user stack pointer + * before exiting the kernel we must clear the microarch state before + * getting here. This should be safe because it means that the only + * values on the bus after this are based on the user's registers and + * potentially the addresses where we stored them. Given the constraints + * of sysret, that's how it has to be. + */ + call *x86_md_clear + + /* * To get back to userland, we need the return %rip in %rcx and * the return %rfl in %r11d. The sysretq instruction also arranges * to fix up %cs and %ss; everything else is our responsibility. @@ -1007,6 +1017,16 @@ _syscall32_after_brand: ASSERT_CR0TS_ZERO(%r11) /* + * Unlike other cases, because we need to restore the user stack pointer + * before exiting the kernel we must clear the microarch state before + * getting here. This should be safe because it means that the only + * values on the bus after this are based on the user's registers and + * potentially the addresses where we stored them. Given the constraints + * of sysret, that's how it has to be. + */ + call *x86_md_clear + + /* * To get back to userland, we need to put the return %rip in %rcx and * the return %rfl in %r11d. The sysret instruction also arranges * to fix up %cs and %ss; everything else is our responsibility. @@ -1317,6 +1337,7 @@ sys_sysenter() popfq movl REGOFF_RSP(%rsp), %ecx /* sysexit: %ecx -> %esp */ ALTENTRY(sys_sysenter_swapgs_sysexit) + call *x86_md_clear jmp tr_sysexit SET_SIZE(sys_sysenter_swapgs_sysexit) SET_SIZE(sys_sysenter) @@ -1441,6 +1462,7 @@ nopop_syscall_int: * tr_iret_user are done on the user gsbase. */ ALTENTRY(sys_sysint_swapgs_iret) + call *x86_md_clear SWAPGS jmp tr_iret_user /*NOTREACHED*/ |
