x86: Add support for partial contexts [1/2]
[akaros.git] / kern / arch / x86 / process64.c
index bb15ae5..0397091 100644 (file)
@@ -15,8 +15,13 @@ void proc_pop_ctx(struct user_context *ctx)
         * gs bases */
        if (ctx->type == ROS_HW_CTX) {
                struct hw_trapframe *tf = &ctx->tf.hw_tf;
-               write_msr(MSR_GS_BASE, (uint64_t)tf->tf_gsbase);
-               write_msr(MSR_FS_BASE, (uint64_t)tf->tf_fsbase);
+
+               if (x86_hwtf_is_partial(tf)) {
+                       swap_gs();
+               } else {
+                       write_msr(MSR_GS_BASE, (uint64_t)tf->tf_gsbase);
+                       write_msr(MSR_FS_BASE, (uint64_t)tf->tf_fsbase);
+               }
                asm volatile ("movq %0, %%rsp;          "
                              "popq %%rax;              "
                              "popq %%rbx;              "
@@ -39,8 +44,13 @@ void proc_pop_ctx(struct user_context *ctx)
                panic("iretq failed");
        } else {
                struct sw_trapframe *tf = &ctx->tf.sw_tf;
-               write_msr(MSR_GS_BASE, (uint64_t)tf->tf_gsbase);
-               write_msr(MSR_FS_BASE, (uint64_t)tf->tf_fsbase);
+
+               if (x86_swtf_is_partial(tf)) {
+                       swap_gs();
+               } else {
+                       write_msr(MSR_GS_BASE, (uint64_t)tf->tf_gsbase);
+                       write_msr(MSR_FS_BASE, (uint64_t)tf->tf_fsbase);
+               }
                /* We need to 0 out any registers that aren't part of the sw_tf and that
                 * we won't use/clobber on the out-path.  While these aren't part of the
                 * sw_tf, we also don't want to leak any kernel register content. */
@@ -111,6 +121,7 @@ void proc_secure_ctx(struct user_context *ctx)
                enforce_user_canon(&tf->tf_gsbase);
                enforce_user_canon(&tf->tf_fsbase);
                enforce_user_canon(&tf->tf_rip);
+               x86_swtf_clear_partial(tf);
        } else {
                /* If we aren't SW, we're assuming (and forcing) a HW ctx.  If this is
                 * somehow fucked up, userspace should die rather quickly. */
@@ -125,6 +136,7 @@ void proc_secure_ctx(struct user_context *ctx)
                tf->tf_ss = GD_UD | 3;
                tf->tf_cs = GD_UT | 3;
                tf->tf_rflags |= FL_IF;
+               x86_hwtf_clear_partial(tf);
        }
 }