More debugging for VMs.
[akaros.git] / kern / arch / x86 / ros / syscall64.h
index 60c5dfe..cb4ef1d 100644 (file)
 #include <sys/types.h>
 #include <stdint.h>
 #include <ros/common.h>
+#include <ros/arch/mmu.h>
 #include <assert.h>
 
 static inline intreg_t __syscall_sysenter(uintreg_t a0, uintreg_t a1)
 {
-       /* The kernel clobbers ecx, so we save it manually. */
        intreg_t ret = 0;
-       #if 0
-       asm volatile ("  pushl %%ecx;        "
-                     "  pushl %%edx;        "
-                     "  pushl %%ebp;        "
-                     "  movl %%esp, %%ebp;  "
-                     "  leal 1f, %%edx;     "
-                     "  sysenter;           "
-                     "1:                    "
-                     "  popl %%ebp;         "
-                     "  popl %%edx;         "
-                     "  popl %%ecx;         "
-                     : "=a" (ret)
-                     : "a" (a0),
-                       "S" (a1)
-                     : "cc", "memory");
-       #endif
+       long dummy;
+       /* we're calling using the amd function call abi.  this asm and the kernel
+        * will save the callee-saved state.  We'll use the clobber list to force
+        * the compiler to save caller-saved state.  As with uthread code, you need
+        * to make sure you have one ABI-compliant, non-inlined function call
+        * between any floating point ops and this.
+        *
+        * Note that syscall doesn't save the stack pointer - using rdx for that.
+        * The kernel will restore it for us. */
+       asm volatile ("movq %%rsp, %%rdx;       "
+                     "syscall;                 "
+                     : "=a"(ret), "=D"(dummy), "=S"(dummy) /* force D, S clobber */
+                     : "D"(a0), "S"(a1)
+                     : "cc", "memory", "rcx", "rdx", "r8", "r9", "r10", "r11");
        return ret;
 }
 
 static inline intreg_t __syscall_trap(uintreg_t a0, uintreg_t a1)
 {
        intreg_t ret;
-
-       #if 0
        /* If you change this, change pop_user_ctx() */
        asm volatile("int %1"
                     : "=a" (ret)
                     : "i" (T_SYSCALL),
-                      "a" (a0),
-                      "d" (a1)
+                      "D" (a0),
+                      "S" (a1)
                     : "cc", "memory");
-       #endif
        return ret;
 }
 
+/* The kernel has a fast path for setting the fs base, used for TLS changes on
+ * machines that can't do it from user space.  The magic value for rdi (D) is a
+ * non-canonical address, which should never be a legitamate syscall. */
+static inline void __fastcall_setfsbase(uintptr_t fsbase)
+{
+       long dummy;
+       asm volatile ("syscall" : "=D"(dummy), "=S"(dummy) /* force D, S clobber */
+                               : "D"(FASTCALL_SETFSBASE), "S"(fsbase)
+                               : "rax", "r11", "rcx", "rdx", "memory");
+}
+
 #endif
 
 #endif /* ROS_INC_ARCH_SYSCALL64_H */