2 * AArch64-specific system calls implementation
4 * Copyright (C) 2012 ARM Ltd.
5 * Author: Catalin Marinas <catalin.marinas@arm.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <linux/compiler.h>
21 #include <linux/errno.h>
24 #include <linux/export.h>
25 #include <linux/sched.h>
26 #include <linux/slab.h>
27 #include <linux/syscalls.h>
30 * Clone a task - this clones the calling program thread.
32 asmlinkage
long sys_clone(unsigned long clone_flags
, unsigned long newsp
,
33 int __user
*parent_tidptr
, unsigned long tls_val
,
34 int __user
*child_tidptr
, struct pt_regs
*regs
)
38 /* 16-byte aligned stack mandatory on AArch64 */
41 return do_fork(clone_flags
, newsp
, regs
, 0, parent_tidptr
, child_tidptr
);
45 * sys_execve() executes a new program.
47 asmlinkage
long sys_execve(const char __user
*filenamei
,
48 const char __user
*const __user
*argv
,
49 const char __user
*const __user
*envp
,
53 struct filename
*filename
;
55 filename
= getname(filenamei
);
56 error
= PTR_ERR(filename
);
59 error
= do_execve(filename
->name
, argv
, envp
, regs
);
65 int kernel_execve(const char *filename
,
66 const char *const argv
[],
67 const char *const envp
[])
72 memset(®s
, 0, sizeof(struct pt_regs
));
73 ret
= do_execve(filename
,
74 (const char __user
*const __user
*)argv
,
75 (const char __user
*const __user
*)envp
, ®s
);
80 * Save argc to the register structure for userspace.
85 * We were successful. We won't be returning to our caller, but
86 * instead to user space by manipulating the kernel stack.
88 asm( "add x0, %0, %1\n\t"
91 "bl memmove\n\t" /* copy regs to top of stack */
92 "mov x27, #0\n\t" /* not a syscall */
93 "mov x28, %0\n\t" /* thread structure */
94 "mov sp, x0\n\t" /* reposition stack pointer */
97 : "r" (current_thread_info()),
98 "Ir" (THREAD_START_SP
- sizeof(regs
)),
101 : "x0", "x1", "x2", "x27", "x28", "x30", "memory");
106 EXPORT_SYMBOL(kernel_execve
);
108 asmlinkage
long sys_mmap(unsigned long addr
, unsigned long len
,
109 unsigned long prot
, unsigned long flags
,
110 unsigned long fd
, off_t off
)
112 if (offset_in_page(off
) != 0)
115 return sys_mmap_pgoff(addr
, len
, prot
, flags
, fd
, off
>> PAGE_SHIFT
);
119 * Wrappers to pass the pt_regs argument.
121 #define sys_execve sys_execve_wrapper
122 #define sys_clone sys_clone_wrapper
123 #define sys_rt_sigreturn sys_rt_sigreturn_wrapper
124 #define sys_sigaltstack sys_sigaltstack_wrapper
126 #include <asm/syscalls.h>
129 #define __SYSCALL(nr, sym) [nr] = sym,
132 * The sys_call_table array must be 4K aligned to be accessible from
135 void *sys_call_table
[__NR_syscalls
] __aligned(4096) = {
136 [0 ... __NR_syscalls
- 1] = sys_ni_syscall
,
137 #include <asm/unistd.h>