Fixes assembly input clobbers (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Sat, 27 Jul 2013 05:21:57 +0000 (22:21 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sat, 27 Jul 2013 05:21:57 +0000 (22:21 -0700)
You can't list an input as a clobber, so to actually clobber it, you
need to use it as an output.  So we use a dummy variable, and hopefully
the compiler does the right thing.

Note we can't (or at least shouldn't) output to the same input variable
(using "+D"(a0), for instance).  We aren't actually outputting a valid
value for any variable; it's usually gibberish or 0, and we don't want
the compiler to *not* save and restore any input args that it may need in
the future.

Also note that these issues are just with the software contexts, where I
was trying to use the asm clobbers to mimic the amd64 calling
convention, so none of the HW TFs were affected.

Reinstall your cross compiler.

kern/arch/x86/ros/syscall64.h
kern/arch/x86/trap32.h
kern/arch/x86/trap64.h
user/parlib/include/x86/vcore32.h
user/parlib/include/x86/vcore64.h

index 9353f58..cb4ef1d 100644 (file)
@@ -18,6 +18,7 @@
 static inline intreg_t __syscall_sysenter(uintreg_t a0, uintreg_t a1)
 {
        intreg_t ret = 0;
+       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
@@ -28,9 +29,8 @@ static inline intreg_t __syscall_sysenter(uintreg_t a0, uintreg_t a1)
         * The kernel will restore it for us. */
        asm volatile ("movq %%rsp, %%rdx;       "
                      "syscall;                 "
-                     : "=a" (ret)
-                     : "D" (a0),
-                       "S" (a1)
+                     : "=a"(ret), "=D"(dummy), "=S"(dummy) /* force D, S clobber */
+                     : "D"(a0), "S"(a1)
                      : "cc", "memory", "rcx", "rdx", "r8", "r9", "r10", "r11");
        return ret;
 }
@@ -53,7 +53,9 @@ static inline intreg_t __syscall_trap(uintreg_t a0, uintreg_t a1)
  * non-canonical address, which should never be a legitamate syscall. */
 static inline void __fastcall_setfsbase(uintptr_t fsbase)
 {
-       asm volatile ("syscall" : : "D"(FASTCALL_SETFSBASE), "S"(fsbase)
+       long dummy;
+       asm volatile ("syscall" : "=D"(dummy), "=S"(dummy) /* force D, S clobber */
+                               : "D"(FASTCALL_SETFSBASE), "S"(fsbase)
                                : "rax", "r11", "rcx", "rdx", "memory");
 }
 
index 918d4c3..e994cb9 100644 (file)
@@ -27,6 +27,7 @@ static inline bool in_kernel(struct hw_trapframe *hw_tf)
 static inline void save_kernel_ctx(struct kernel_ctx *ctx)
 {
        /* Save the regs and the future esp. */
+       /* Careful when updating; %0, %1, and %2 are not listed as clobbers */
        asm volatile("movl %%esp,(%0);       " /* save esp in it's slot*/
                     "pushl %%eax;           " /* temp save eax */
                     "leal 1f,%%eax;         " /* get future eip */
index 9506727..a581ce5 100644 (file)
@@ -29,6 +29,7 @@ static inline bool in_kernel(struct hw_trapframe *hw_tf)
 /* Using SW contexts for now, for x86_64 */
 static inline void save_kernel_ctx(struct kernel_ctx *ctx)
 {
+       long dummy;
        /* not bothering with the FP fields */
        asm volatile("mov %%rsp, 0x48(%0);   " /* save rsp in its slot*/
                     "leaq 1f, %%rax;        " /* get future rip */
@@ -40,7 +41,7 @@ static inline void save_kernel_ctx(struct kernel_ctx *ctx)
                     "mov %%rbp, 0x18(%0);   "
                     "mov %%rbx, 0x10(%0);   "
                     "1:                     " /* where this tf will restart */
-                    : 
+                                : "=D"(dummy) /* force rdi clobber */
                                 : "D"(&ctx->sw_tf)
                     : "rax", "rcx", "rdx", "rsi", "r8", "r9", "r10", "r11",
                       "memory", "cc");
index ddbd794..434a845 100644 (file)
@@ -256,6 +256,7 @@ static inline void pop_user_ctx_raw(struct user_context *ctx, uint32_t vcoreid)
 static inline void save_user_ctx(struct user_context *ctx)
 {
        struct sw_trapframe *sw_tf = &ctx->tf.sw_tf;
+       long dummy;
        ctx->type = ROS_SW_CTX;
        asm volatile ("stmxcsr %0" : "=m"(sw_tf->tf_mxcsr));
        asm volatile ("fnstcw %0" : "=m"(sw_tf->tf_fpucw));
@@ -268,7 +269,7 @@ static inline void save_user_ctx(struct user_context *ctx)
                      "leal 1f,%%eax;         " /* get future eip */
                      "movl %%eax,0x14(%0);   "
                      "1:                     " /* where this tf will restart */
-                     :
+                     : "=c"(dummy)     /* force clobber for ecx */
                      : "c"(sw_tf)
                      : "eax", "edx", "memory", "cc");
 }
index ee6f327..32f71fb 100644 (file)
@@ -274,6 +274,7 @@ static inline void pop_user_ctx_raw(struct user_context *ctx, uint32_t vcoreid)
 static inline void save_user_ctx(struct user_context *ctx)
 {
        struct sw_trapframe *sw_tf = &ctx->tf.sw_tf;
+       long dummy;
        ctx->type = ROS_SW_CTX;
        asm volatile ("stmxcsr %0" : "=m"(sw_tf->tf_mxcsr));
        asm volatile ("fnstcw %0" : "=m"(sw_tf->tf_fpucw));
@@ -288,7 +289,7 @@ static inline void save_user_ctx(struct user_context *ctx)
                     "mov %%rbp, 0x18(%0);   "
                     "mov %%rbx, 0x10(%0);   "
                     "1:                     " /* where this tf will restart */
-                    : 
+                    : "=D"(dummy) /* force clobber for rdi */
                                 : "D"(sw_tf)
                     : "rax", "rcx", "rdx", "rsi", "r8", "r9", "r10", "r11",
                       "memory", "cc");