Print this page
8956 Implement KPTI
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>

@@ -19,11 +19,11 @@
  * CDDL HEADER END
  */
 
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, Joyent, Inc.  All rights reserverd.
+ * Copyright (c) 2018 Joyent, Inc.  All rights reserverd.
  */
 
 /*
  * To understand the present state of interrupt handling on i86pc, we must
  * first consider the history of interrupt controllers and our way of handling

@@ -469,10 +469,25 @@
 #include <vm/hat_i86.h>
 #if defined(__xpv)
 #include <sys/hypervisor.h>
 #endif
 
+#if defined(__amd64) && !defined(__xpv)
+/* If this fails, then the padding numbers in machcpuvar.h are wrong. */
+CTASSERT((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_pad))
+    < MMU_PAGESIZE);
+CTASSERT((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_kpti))
+    >= MMU_PAGESIZE);
+CTASSERT((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_kpti_dbg))
+    < 2 * MMU_PAGESIZE);
+CTASSERT((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_pad2))
+    < 2 * MMU_PAGESIZE);
+CTASSERT(((sizeof (struct kpti_frame)) & 0xF) == 0);
+CTASSERT(((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_kpti_dbg))
+    & 0xF) == 0);
+CTASSERT((offsetof(struct kpti_frame, kf_tr_rsp) & 0xF) == 0);
+#endif
 
 #if defined(__xpv) && defined(DEBUG)
 
 /*
  * This panic message is intended as an aid to interrupt debugging.

@@ -1471,11 +1486,26 @@
 
 #endif  /* __amd64 */
                 return (1);
         }
 
+#if !defined(__xpv)
         /*
+         * Assert that we're not trying to return into the syscall return
+         * trampolines. Things will go baaaaad if we try to do that.
+         *
+         * Note that none of these run with interrupts on, so this should
+         * never happen (even in the sysexit case the STI doesn't take effect
+         * until after sysexit finishes).
+         */
+        extern void tr_sysc_ret_start();
+        extern void tr_sysc_ret_end();
+        ASSERT(!(rp->r_pc >= (uintptr_t)tr_sysc_ret_start &&
+            rp->r_pc <= (uintptr_t)tr_sysc_ret_end));
+#endif
+
+        /*
          * Here if we are returning to supervisor mode.
          * Check for a kernel preemption request.
          */
         if (CPU->cpu_kprunrun && (rp->r_ps & PS_IE)) {