On Fri, Sep 07, 2012 at 08:43:36PM +0100, Arnd Bergmann wrote: > On Friday 07 September 2012, Catalin Marinas wrote: > > +/* > > + * sys_execve() executes a new program. > > + */ > > +asmlinkage long sys_execve(const char __user *filenamei, > > + const char __user *const __user *argv, > > + const char __user *const __user *envp, > > + struct pt_regs *regs) ... > > +int kernel_execve(const char *filename, > > + const char *const argv[], > > + const char *const envp[]) ... > Al Viro is currently reworking this code across all architectures, please have a look > at https://git.kernel.org/?p=linux/kernel/git/viro/signal.git;a=shortlog;h=refs/heads/execve2 Yes, I've seen these but since Al's patches are not in mainline, I don't want to add additional dependencies to the arm64 patches (currently based on 3.6-rc4). Once they get into mainline, I'll add a patch that converts arm64 to the generic functions above. For kernel_execve(), I think I can simplify it further and not rely on Al's patches (similar to other architectures doing an SVC from kernel): diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index ed2e58f..e712abe 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -241,10 +241,12 @@ ENDPROC(el1_error_invalid) .align 6 el1_sync: kernel_entry 1 - mrs x1, esr_el1 // read the syndrome register - lsr x24, x1, #26 // exception class + mrs x25, esr_el1 // read the syndrome register + lsr x24, x25, #26 // exception class cmp x24, #0x25 // data abort in EL1 b.eq el1_da + cmp x24, #0x15 // SVC in 64-bit state + b.eq el0_svc cmp x24, #0x18 // configurable trap b.eq el1_undef cmp x24, #0x26 // stack alignment exception @@ -266,6 +268,7 @@ el1_da: tbnz x23, #7, 1f // PSR_I_BIT enable_irq 1: + mov x1, x25 mov x2, sp // struct pt_regs bl do_mem_abort @@ -592,7 +595,7 @@ work_resched: /* * "slow" syscall return path. */ -ENTRY(ret_to_user) +ret_to_user: disable_irq // disable interrupts ldr x1, [tsk, #TI_FLAGS] and x2, x1, #_TIF_WORK_MASK @@ -605,6 +608,15 @@ no_work_pending: ENDPROC(ret_to_user) /* + * kernel_execve() - just issue a __NR_execve syscall + */ +ENTRY(kernel_execve) + mov x8, #__NR_execve + svc #0 + ret +ENDPROC(kernel_execve) + +/* * This is how we return from a fork. */ ENTRY(ret_from_fork) diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c index 905fcfb..dfad7b1 100644 --- a/arch/arm64/kernel/sys.c +++ b/arch/arm64/kernel/sys.c @@ -62,49 +62,6 @@ out: return error; } -int kernel_execve(const char *filename, - const char *const argv[], - const char *const envp[]) -{ - struct pt_regs regs; - int ret; - - memset(®s, 0, sizeof(struct pt_regs)); - ret = do_execve(filename, - (const char __user *const __user *)argv, - (const char __user *const __user *)envp, ®s); - if (ret < 0) - goto out; - - /* - * Save argc to the register structure for userspace. - */ - regs.regs[0] = ret; - - /* - * We were successful. We won't be returning to our caller, but - * instead to user space by manipulating the kernel stack. - */ - asm( "add x0, %0, %1\n\t" - "mov x1, %2\n\t" - "mov x2, %3\n\t" - "bl memmove\n\t" /* copy regs to top of stack */ - "mov x27, #0\n\t" /* not a syscall */ - "mov x28, %0\n\t" /* thread structure */ - "mov sp, x0\n\t" /* reposition stack pointer */ - "b ret_to_user" - : - : "r" (current_thread_info()), - "Ir" (THREAD_START_SP - sizeof(regs)), - "r" (®s), - "Ir" (sizeof(regs)) - : "x0", "x1", "x2", "x27", "x28", "x30", "memory"); - - out: - return ret; -} -EXPORT_SYMBOL(kernel_execve); - asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, off_t off) -- Catalin -- To unsubscribe from this list: send the line "unsubscribe linux-arch" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html