strace: Qstrace controls whether tracing is on
[akaros.git] / kern / arch / x86 / trap64.h
index bda6ad8..b3165d5 100644 (file)
 #error "Do not include arch/trap64.h directly."
 #endif
 
-void print_swtrapframe(struct sw_trapframe *sw_tf);
+#include <arch/fsgsbase.h>
 
 static inline bool in_kernel(struct hw_trapframe *hw_tf)
 {
        return (hw_tf->tf_cs & ~3) == GD_KT;
 }
 
-static inline uintptr_t get_hwtf_pc(struct hw_trapframe *hw_tf)
-{
-       return hw_tf->tf_rip;
-}
-
-static inline uintptr_t get_hwtf_fp(struct hw_trapframe *hw_tf)
-{
-       return hw_tf->tf_rbp;
-}
-
-static inline uintptr_t get_swtf_pc(struct sw_trapframe *sw_tf)
-{
-       return sw_tf->tf_rip;
-}
-
-static inline uintptr_t get_swtf_fp(struct sw_trapframe *sw_tf)
-{
-       return sw_tf->tf_rbp;
-}
-
-static inline uintptr_t x86_get_ip_hw(struct hw_trapframe *hw_tf)
-{
-       return hw_tf->tf_rip;
-}
-
 static inline void x86_advance_ip(struct hw_trapframe *hw_tf, size_t bytes)
 {
        hw_tf->tf_rip += bytes;
@@ -59,17 +34,20 @@ static inline void x86_fake_rdtscp(struct hw_trapframe *hw_tf)
        hw_tf->tf_rcx = core_id();
 }
 
-static inline void x86_sysenter_init(uintptr_t stacktop)
+#define AKAROS_MSR_STAR (((((uint64_t)GD_UD - 8) | 0x3) << 48) |             \
+                            ((uint64_t)GD_KT << 32))
+#define AKAROS_MSR_LSTAR ((uintptr_t)&sysenter_handler)
+/* Masking all flags.  when we syscall, we'll get rflags = 0 */
+#define AKAROS_MSR_SFMASK (FL_AC | FL_NT | FL_IOPL_MASK | FL_DF | FL_IF | FL_TF)
+
+static inline void x86_sysenter_init(void)
 {
        /* check amd 2:6.1.1 for details.  they have some expectations about the GDT
         * layout. */
-       write_msr(MSR_STAR, ((((uint64_t)GD_UD - 8) | 0x3) << 48) |
-                           ((uint64_t)GD_KT << 32));
-       write_msr(MSR_LSTAR, (uintptr_t)&sysenter_handler);
-       /* Masking all flags.  when we syscall, we'll get rflags = 0 */
-       write_msr(MSR_SFMASK, 0xffffffff);
+       write_msr(MSR_STAR, AKAROS_MSR_STAR);
+       write_msr(MSR_LSTAR, AKAROS_MSR_LSTAR);
+       write_msr(MSR_SFMASK, AKAROS_MSR_SFMASK);
        write_msr(IA32_EFER_MSR, read_msr(IA32_EFER_MSR) | IA32_EFER_SYSCALL);
-       asm volatile ("movq %0, %%gs:0" : : "r"(stacktop));
 }
 
 /* these are used for both sysenter and traps on 32 bit */
@@ -119,6 +97,11 @@ static inline bool x86_swtf_is_partial(struct sw_trapframe *tf)
        return tf->tf_padding0 == 1;
 }
 
+static inline bool x86_vmtf_is_partial(struct vm_trapframe *tf)
+{
+       return tf->tf_flags & VMCTX_FL_PARTIAL ? TRUE : FALSE;
+}
+
 static inline void x86_hwtf_clear_partial(struct hw_trapframe *tf)
 {
        tf->tf_padding0 = 0;
@@ -129,50 +112,20 @@ static inline void x86_swtf_clear_partial(struct sw_trapframe *tf)
        tf->tf_padding0 = 0;
 }
 
+static inline void x86_vmtf_clear_partial(struct vm_trapframe *tf)
+{
+       tf->tf_flags &= ~VMCTX_FL_PARTIAL;
+}
+
 static inline bool arch_ctx_is_partial(struct user_context *ctx)
 {
        switch (ctx->type) {
-       case (ROS_HW_CTX):
+       case ROS_HW_CTX:
                return x86_hwtf_is_partial(&ctx->tf.hw_tf);
-       case (ROS_SW_CTX):
+       case ROS_SW_CTX:
                return x86_swtf_is_partial(&ctx->tf.sw_tf);
+       case ROS_VM_CTX:
+               return x86_vmtf_is_partial(&ctx->tf.vm_tf);
        }
        return FALSE;
 }
-
-/* Partial contexts for HW and SW TFs have the user's gs in MSR_KERNEL_GS_BASE.
- * The kernel's gs is loaded into gs.  We need to put the kernel's gs into
- * KERNEL_GS_BASE so the core is ready to run another full context, save the
- * user's {GS,FS}_BASE into their TF so it can run on another core, and keep GS
- * loaded with the current GS (the kernel's). */
-static inline void x86_finalize_hwtf(struct hw_trapframe *tf)
-{
-       tf->tf_gsbase = read_msr(MSR_KERNEL_GS_BASE);
-       write_msr(MSR_KERNEL_GS_BASE, read_msr(MSR_GS_BASE));
-       tf->tf_fsbase = read_msr(MSR_FS_BASE);
-       x86_hwtf_clear_partial(tf);
-}
-
-static inline void x86_finalize_swtf(struct sw_trapframe *tf)
-{
-       tf->tf_gsbase = read_msr(MSR_KERNEL_GS_BASE);
-       write_msr(MSR_KERNEL_GS_BASE, read_msr(MSR_GS_BASE));
-       tf->tf_fsbase = read_msr(MSR_FS_BASE);
-       x86_swtf_clear_partial(tf);
-}
-
-/* Makes sure that the user context is fully saved into ctx and not split across
- * the struct and HW, meaning it is not a "partial context". */
-static inline void arch_finalize_ctx(struct user_context *ctx)
-{
-       if (!arch_ctx_is_partial(ctx))
-               return;
-       switch (ctx->type) {
-       case (ROS_HW_CTX):
-               x86_finalize_hwtf(&ctx->tf.hw_tf);
-               break;
-       case (ROS_SW_CTX):
-               x86_finalize_swtf(&ctx->tf.sw_tf);
-               break;
-       }
-}