Re: [PATCH v3 17/31] arm64: System calls handling

From: Catalin Marinas
Date: Mon Sep 10 2012 - 05:57:04 EST


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(&regs, 0, sizeof(struct pt_regs));
- ret = do_execve(filename,
- (const char __user *const __user *)argv,
- (const char __user *const __user *)envp, &regs);
- 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" (&regs),
- "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-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/