summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/ia32/os/sundep.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/intel/ia32/os/sundep.c')
-rw-r--r--usr/src/uts/intel/ia32/os/sundep.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/usr/src/uts/intel/ia32/os/sundep.c b/usr/src/uts/intel/ia32/os/sundep.c
index cfb4552287..34e0a03d68 100644
--- a/usr/src/uts/intel/ia32/os/sundep.c
+++ b/usr/src/uts/intel/ia32/os/sundep.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2018 Joyent, Inc.
+ * Copyright 2019 Joyent, Inc.
*/
/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
@@ -551,16 +551,19 @@ update_sregs(struct regs *rp, klwp_t *lwp)
*
* We've just mucked up the kernel's gsbase. Oops. In
* particular we can't take any traps at all. Make the newly
- * computed gsbase be the hidden gs via __swapgs, and fix
+ * computed gsbase be the hidden gs via swapgs, and fix
* the kernel's gsbase back again. Later, when we return to
* userland we'll swapgs again restoring gsbase just loaded
* above.
*/
- __swapgs();
+ __asm__ __volatile__("mfence; swapgs");
+
rp->r_gs = pcb->pcb_gs;
/*
- * restore kernel's gsbase
+ * Restore kernel's gsbase. Note that this also serializes any
+ * attempted speculation from loading the user-controlled
+ * %gsbase.
*/
wrmsr(MSR_AMD_GSBASE, kgsbase);