From: Al Viro Date: Fri, 1 Jun 2012 02:22:52 +0000 (-0400) Subject: alpha: rewrite kernel_execve in C X-Git-Tag: next-20120724~4^2~9 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=68f596a7a0452ed96f65fecff1f714c3741e0662;p=karo-tx-linux.git alpha: rewrite kernel_execve in C Signed-off-by: Al Viro --- diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index d96e742d4dc2..b77b81389932 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -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); diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 22b0c4d414a7..ec0da0567ab5 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -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 - /* * Special system calls. Most of these are special in that they either diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 153d3fce3e8e..6251146f7fb5 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -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, ®s); + 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);