]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
alpha: rewrite kernel_execve in C
authorAl Viro <viro@zeniv.linux.org.uk>
Fri, 1 Jun 2012 02:22:52 +0000 (22:22 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 21 Jun 2012 04:02:51 +0000 (08:02 +0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/kernel/entry.S
arch/alpha/kernel/process.c

index d96e742d4dc2c9d139e021ee34aae81eeabdda55..b77b81389932aa244e86ecf89addde5f1cda1adb 100644 (file)
@@ -52,7 +52,6 @@ EXPORT_SYMBOL(alpha_write_fp_reg_s);
 
 /* entry.S */
 EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(kernel_execve);
 
 /* Networking helper routines. */
 EXPORT_SYMBOL(csum_tcpudp_magic);
index 22b0c4d414a7cec4413d78be35482e91f6c4a2f2..ec0da0567ab515e6203d2310a9d960be7d4fc0e7 100644 (file)
@@ -663,58 +663,6 @@ kernel_thread:
        br      ret_to_kernel
 .end kernel_thread
 
-/*
- * kernel_execve(path, argv, envp)
- */
-       .align  4
-       .globl  kernel_execve
-       .ent    kernel_execve
-kernel_execve:
-       /* We can be called from a module.  */
-       ldgp    $gp, 0($27)
-       lda     $sp, -(32+SIZEOF_PT_REGS+8)($sp)
-       .frame  $sp, 32+SIZEOF_PT_REGS+8, $26, 0
-       stq     $26, 0($sp)
-       stq     $16, 8($sp)
-       stq     $17, 16($sp)
-       stq     $18, 24($sp)
-       .prologue 1
-
-       lda     $16, 32($sp)
-       lda     $17, 0
-       lda     $18, SIZEOF_PT_REGS
-       bsr     $26, memset             !samegp
-
-       /* Avoid the HAE being gratuitously wrong, which would cause us
-          to do the whole turn off interrupts thing and restore it.  */
-       ldq     $2, alpha_mv+HAE_CACHE
-       stq     $2, 152+32($sp)
-
-       ldq     $16, 8($sp)
-       ldq     $17, 16($sp)
-       ldq     $18, 24($sp)
-       lda     $19, 32($sp)
-       bsr     $26, do_execve          !samegp
-
-       ldq     $26, 0($sp)
-       bne     $0, 1f                  /* error! */
-
-       /* Move the temporary pt_regs struct from its current location
-          to the top of the kernel stack frame.  See copy_thread for
-          details for a normal process.  */
-       lda     $16, 0x4000 - SIZEOF_PT_REGS($8)
-       lda     $17, 32($sp)
-       lda     $18, SIZEOF_PT_REGS
-       bsr     $26, memmove            !samegp
-
-       /* Take that over as our new stack frame and visit userland!  */
-       lda     $sp, 0x4000 - SIZEOF_PT_REGS($8)
-       br      $31, ret_from_sys_call
-
-1:     lda     $sp, 32+SIZEOF_PT_REGS+8($sp)
-       ret
-.end kernel_execve
-
 \f
 /*
  * Special system calls.  Most of these are special in that they either
index 153d3fce3e8e9b4adc84c64fe63483d815a1ec59..6251146f7fb56866a9dea224aade54e4544c3764 100644 (file)
@@ -455,3 +455,32 @@ get_wchan(struct task_struct *p)
        }
        return pc;
 }
+
+int kernel_execve(const char *path, const char *const argv[], const char *const envp[])
+{
+       /* Avoid the HAE being gratuitously wrong, which would cause us
+          to do the whole turn off interrupts thing and restore it.  */
+       struct pt_regs regs = {.hae = alpha_mv.hae_cache};
+       int err = do_execve(path, argv, envp, &regs);
+       if (!err) {
+               /*
+                * copy regs to normal position and off to userland we go...
+                * note that we are not guaranteed that we are deep enough
+                * in stack for current_pt_regs() not to overlap our stack
+                * frame; memcpy() would not be safe and we _must_ do
+                * everything starting from that memmove() in assembler.
+                * And we can't mangle $sp until after the call of memmove()
+                * either...
+                */
+               __asm__ __volatile__ (
+                       "lda    $16, %0\n"
+                       "lda    $17, %1\n"
+                       "lda    $18, %2\n"
+                       "bsr    $26, memmove\n"
+                       "lda    $sp, %0\n"
+                       "jsr    $31, ret_from_sys_call\n"
+                       : : "m"(*current_pt_regs()), "m"(regs), "Ir"(sizeof(struct pt_regs)));
+       }
+       return err;
+}
+EXPORT_SYMBOL(kernel_execve);