summaryrefslogtreecommitdiff
path: root/usr/src/uts/i86pc/ml
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@joyent.com>2019-05-01 05:01:35 +0000
committerRobert Mustacchi <rm@joyent.com>2019-05-14 17:39:44 +0000
commita129b6ac948a795e06506944867eb18a238526d1 (patch)
tree28d30f368372affc8cac1253effc101439a2c802 /usr/src/uts/i86pc/ml
parent5ee58e69654ffd86bb4f050263de0c9da75fa28f (diff)
downloadillumos-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.s5
-rw-r--r--usr/src/uts/i86pc/ml/md_clear.s61
-rw-r--r--usr/src/uts/i86pc/ml/syscall_asm_amd64.s24
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*/