diff mbox

[v3,17/31] arm64: System calls handling

Message ID 20120910095619.GA27042@arm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Catalin Marinas Sept. 10, 2012, 9:56 a.m. UTC
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):

Comments

Arnd Bergmann Sept. 10, 2012, 1:51 p.m. UTC | #1
On Monday 10 September 2012, Catalin Marinas wrote:
> 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):

Hmm, I thought one of the reasons for Al to do his series was to discourage
people from doing syscalls from kernel space, but I may be misremembering
things. Al?

	Arnd
Catalin Marinas Sept. 10, 2012, 2:01 p.m. UTC | #2
On Mon, Sep 10, 2012 at 02:51:52PM +0100, Arnd Bergmann wrote:
> On Monday 10 September 2012, Catalin Marinas wrote:
> > 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):
> 
> Hmm, I thought one of the reasons for Al to do his series was to discourage
> people from doing syscalls from kernel space, but I may be misremembering
> things. Al?

If that was the aim, I'm happy to change the code similar to the
arch/arm one. But as I said I would wait until Al's patches get into
mainline.
Arnd Bergmann Sept. 10, 2012, 2:24 p.m. UTC | #3
On Monday 10 September 2012, Catalin Marinas wrote:
> 
> On Mon, Sep 10, 2012 at 02:51:52PM +0100, Arnd Bergmann wrote:
> > On Monday 10 September 2012, Catalin Marinas wrote:
> > > 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):
> > 
> > Hmm, I thought one of the reasons for Al to do his series was to discourage
> > people from doing syscalls from kernel space, but I may be misremembering
> > things. Al?
> 
> If that was the aim, I'm happy to change the code similar to the
> arch/arm one. But as I said I would wait until Al's patches get into
> mainline.

Ok. Another point: I wouldn't be too worried about dependencies for new
code, because it's not possible to bisect through your series anyway
(one needs all the patches before anything starts working really),
so from my point of view you could also write your code in a way that
expects Al's patches to get merged first.

	Arnd
diff mbox

Patch

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)