--- old/usr/src/cmd/mdb/i86pc/modules/unix/unix.c	Fri Aug 10 16:06:33 2018
+++ new/usr/src/cmd/mdb/i86pc/modules/unix/unix.c	Fri Aug 10 16:06:33 2018
@@ -904,9 +904,11 @@
 #ifdef _KMDB
 /* ARGSUSED */
 static int
-crregs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+sysregs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 {
 	ulong_t cr0, cr2, cr3, cr4;
+	desctbr_t gdtr;
+
 	static const mdb_bitmask_t cr0_flag_bits[] = {
 		{ "PE",		CR0_PE,		CR0_PE },
 		{ "MP",		CR0_MP,		CR0_MP },
@@ -953,6 +955,9 @@
 	cr2 = kmdb_unix_getcr2();
 	cr3 = kmdb_unix_getcr3();
 	cr4 = kmdb_unix_getcr4();
+
+	kmdb_unix_getgdtr(&gdtr);
+
 	mdb_printf("%%cr0 = 0x%lx <%b>\n", cr0, cr0, cr0_flag_bits);
 	mdb_printf("%%cr2 = 0x%lx <%a>\n", cr2, cr2);
 
@@ -966,6 +971,9 @@
 
 	mdb_printf("%%cr4 = 0x%lx <%b>\n", cr4, cr4, cr4_flag_bits);
 
+	mdb_printf("%%gdtr.base = 0x%lx, %%gdtr.limit = 0x%hx\n",
+	    gdtr.dtr_base, gdtr.dtr_limit);
+
 	return (DCMD_OK);
 }
 #endif
@@ -997,7 +1005,7 @@
 	{ "x86_featureset", NULL, "dump the x86_featureset vector",
 		x86_featureset_cmd },
 #ifdef _KMDB
-	{ "crregs", NULL, "dump control registers", crregs_dcmd },
+	{ "sysregs", NULL, "dump system registers", sysregs_dcmd },
 #endif
 	{ NULL }
 };
--- old/usr/src/cmd/mdb/i86pc/modules/unix/unix_sup.h	Fri Aug 10 16:06:33 2018
+++ new/usr/src/cmd/mdb/i86pc/modules/unix/unix_sup.h	Fri Aug 10 16:06:33 2018
@@ -21,6 +21,7 @@
  */
 
 #include <sys/types.h>
+#include <sys/segments.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -30,6 +31,7 @@
 extern ulong_t kmdb_unix_getcr2(void);
 extern ulong_t kmdb_unix_getcr3(void);
 extern ulong_t kmdb_unix_getcr4(void);
+extern void kmdb_unix_getgdtr(desctbr_t *);
 
 #ifdef __cplusplus
 }
--- old/usr/src/cmd/mdb/i86pc/modules/unix/unix_sup.s	Fri Aug 10 16:06:33 2018
+++ new/usr/src/cmd/mdb/i86pc/modules/unix/unix_sup.s	Fri Aug 10 16:06:33 2018
@@ -13,35 +13,20 @@
  * Copyright 2018 Joyent, Inc.
  */
 
-#if !defined(__lint)
-	.file	"unix_sup.s"
-#endif /* __lint */
-
 /*
  * Support routines for the unix kmdb module
  */
 
-#include <sys/asm_linkage.h>
-
 #if defined(__lint)
 
 #include <sys/types.h>
 
-ulong_t
-kmdb_unix_getcr0(void)
-{ return (0); }
+#else
 
-ulong_t
-kmdb_unix_getcr3(void)
-{ return (0); }
+#include <sys/asm_linkage.h>
 
-ulong_t
-kmdb_unix_getcr4(void)
-{ return (0); }
+	.file	"unix_sup.s"
 
-#else	/* __lint */
-
-#if defined(__amd64)
 	ENTRY(kmdb_unix_getcr0)
 	movq %cr0, %rax
 	ret
@@ -62,27 +47,9 @@
 	ret
 	SET_SIZE(kmdb_unix_getcr4)
 
-#elif defined (__i386)
-	ENTRY(kmdb_unix_getcr0)
-	movl %cr0, %eax
+	ENTRY(kmdb_unix_getgdtr)
+	sgdt (%rdi)
 	ret
-	SET_SIZE(kmdb_unix_getcr0)
+	SET_SIZE(kmdb_unix_getgdtr)
 
-	ENTRY(kmdb_unix_getcr2)
-	movl %cr2, %eax
-	ret
-	SET_SIZE(kmdb_unix_getcr2)
-
-	ENTRY(kmdb_unix_getcr3)
-	movl %cr3, %eax
-	ret
-	SET_SIZE(kmdb_unix_getcr3)
-
-	ENTRY(kmdb_unix_getcr4)
-	movl %cr4, %eax
-	ret
-	SET_SIZE(kmdb_unix_getcr4)
-
-#endif	/* __i386 */
-
-#endif /* __lint */
+#endif /* !__lint */
--- old/usr/src/pkg/manifests/system-test-ostest.mf	Fri Aug 10 16:06:33 2018
+++ new/usr/src/pkg/manifests/system-test-ostest.mf	Fri Aug 10 16:06:33 2018
@@ -41,6 +41,7 @@
 file path=opt/os-tests/tests/file-locking/acquire-lock.64 mode=0555
 file path=opt/os-tests/tests/file-locking/runtests.32 mode=0555
 file path=opt/os-tests/tests/file-locking/runtests.64 mode=0555
+$(i386_ONLY)file path=opt/os-tests/tests/i386/badseg mode=0555
 $(i386_ONLY)file path=opt/os-tests/tests/i386/ldt mode=0555
 file path=opt/os-tests/tests/pf_key/acquire-compare mode=0555
 file path=opt/os-tests/tests/pf_key/acquire-spray mode=0555
--- old/usr/src/test/os-tests/runfiles/default.run	Fri Aug 10 16:06:33 2018
+++ new/usr/src/test/os-tests/runfiles/default.run	Fri Aug 10 16:06:33 2018
@@ -66,4 +66,4 @@
 [/opt/os-tests/tests/i386]
 user = root
 arch = i86pc
-tests = ['ldt']
+tests = ['ldt', 'badseg']
--- old/usr/src/test/os-tests/tests/i386/Makefile	Fri Aug 10 16:06:33 2018
+++ new/usr/src/test/os-tests/tests/i386/Makefile	Fri Aug 10 16:06:33 2018
@@ -16,28 +16,29 @@
 include $(SRC)/cmd/Makefile.cmd
 include $(SRC)/test/Makefile.com
 
-PROG +=	ldt
+PROGS += ldt badseg
 
 ROOTOPTPKG = $(ROOT)/opt/os-tests
 TESTDIR = $(ROOTOPTPKG)/tests/i386
+ROOTOPTPROGS = $(PROGS:%=$(TESTDIR)/%)
 
 CSTD = $(CSTD_GNU99)
 
-CMDS = $(PROG:%=$(TESTDIR)/%)
-$(CMDS) := FILEMODE = 0555
+# for badseg
+COPTFLAG =
 
-all: $(PROG)
+all: $(PROGS)
 
-install: all $(CMDS)
+install: all $(ROOTOPTPROGS)
 
 lint:
 
 clobber: clean
-	-$(RM) $(PROG)
+	-$(RM) $(PROGS)
 
 clean:
 
-$(CMDS): $(TESTDIR) $(PROG)
+$(ROOTOPTPROGS): $(TESTDIR) $(PROGS)
 
 $(TESTDIR):
 	$(INS.dir)
--- /dev/null	Fri Aug 10 16:06:34 2018
+++ new/usr/src/test/os-tests/tests/i386/badseg.c	Fri Aug 10 16:06:34 2018
@@ -0,0 +1,146 @@
+/*
+ * 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 2018 Joyent, Inc.
+ */
+
+#include <stdlib.h>
+#include <ucontext.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <sys/regset.h>
+
+/*
+ * Load a bunch of bad selectors into the seg regs: this will typically cause
+ * the child process to core dump, but it shouldn't panic the kernel...
+ *
+ * It's especially interesting to run this on CPU0.
+ */
+
+unsigned short selector;
+
+static void badds(void)
+{
+	__asm__ volatile("movw %0, %%ds" : : "r" (selector));
+}
+
+static void bades(void)
+{
+	__asm__ volatile("movw %0, %%es" : : "r" (selector));
+}
+
+static void badfs(void)
+{
+	__asm__ volatile("movw %0, %%fs" : : "r" (selector));
+}
+
+static void badgs(void)
+{
+	__asm__ volatile("movw %0, %%gs" : : "r" (selector));
+}
+
+static void badss(void)
+{
+	__asm__ volatile("movw %0, %%ss" : : "r" (selector));
+}
+
+static void
+resetseg(uint_t seg)
+{
+	ucontext_t ucp;
+	int done = 0;
+
+	int rc = getcontext(&ucp);
+	if (done) {
+		rc = getcontext(&ucp);
+		return;
+	}
+
+	done = 1;
+	ucp.uc_mcontext.gregs[seg] = selector;
+	setcontext(&ucp);
+	abort();
+}
+
+static void
+resetcs(void)
+{
+	return (resetseg(CS));
+}
+
+static void
+resetds(void)
+{
+	return (resetseg(DS));
+}
+
+static void
+resetes(void)
+{
+	return (resetseg(ES));
+}
+
+static void
+resetfs(void)
+{
+	return (resetseg(FS));
+}
+
+static void
+resetgs(void)
+{
+	return (resetseg(GS));
+}
+
+static void
+resetss(void)
+{
+	return (resetseg(SS));
+}
+
+static void
+inchild(void (*func)())
+{
+	pid_t pid;
+
+	switch ((pid = fork())) {
+	case 0:
+		func();
+		exit(0);
+	case -1:
+		exit(1);
+	default:
+		(void) waitpid(pid, NULL, 0);
+		return;
+	}
+
+}
+
+int
+main(int argc, char *argv[])
+{
+	for (selector = 0; selector < 8194; selector++) {
+		inchild(resetcs);
+		inchild(resetds);
+		inchild(resetes);
+		inchild(resetfs);
+		inchild(resetgs);
+		inchild(resetss);
+		inchild(badds);
+		inchild(bades);
+		inchild(badfs);
+		inchild(badgs);
+		inchild(badss);
+	}
+
+	exit(0);
+}
--- old/usr/src/uts/intel/ia32/os/desctbls.c	Fri Aug 10 16:06:34 2018
+++ new/usr/src/uts/intel/ia32/os/desctbls.c	Fri Aug 10 16:06:34 2018
@@ -1290,7 +1290,29 @@
 
 #endif	/* __xpv */
 
+#ifndef __xpv
 /*
+ * As per Intel Vol 3 27.5.2, the GDTR limit is reset to 64Kb on a VM exit, so
+ * we have to manually fix it up ourselves.
+ *
+ * The caller may still need to make sure that it can't go off-CPU with the
+ * incorrect limit, before calling this (such as disabling pre-emption).
+ */
+void
+reset_gdtr_limit(void)
+{
+	ulong_t flags = intr_clear();
+	desctbr_t gdtr;
+
+	rd_gdtr(&gdtr);
+	gdtr.dtr_limit = (sizeof (user_desc_t) * NGDT) - 1;
+	wr_gdtr(&gdtr);
+
+	intr_restore(flags);
+}
+#endif /* __xpv */
+
+/*
  * In the early kernel, we need to set up a simple GDT to run on.
  *
  * XXPV	Can dboot use this too?  See dboot_gdt.s
--- old/usr/src/uts/intel/sys/x86_archext.h	Fri Aug 10 16:06:34 2018
+++ new/usr/src/uts/intel/sys/x86_archext.h	Fri Aug 10 16:06:34 2018
@@ -891,6 +891,10 @@
 
 extern void xsave_setup_msr(struct cpu *);
 
+#if !defined(__xpv)
+extern void reset_gdtr_limit(void);
+#endif
+
 /*
  * Hypervisor signatures
  */
