Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
arm64
kernel
sys.c
Go to the documentation of this file.
1
/*
2
* AArch64-specific system calls implementation
3
*
4
* Copyright (C) 2012 ARM Ltd.
5
* Author: Catalin Marinas <
[email protected]
>
6
*
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.
10
*
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.
15
*
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/>.
18
*/
19
20
#include <linux/compiler.h>
21
#include <linux/errno.h>
22
#include <linux/fs.h>
23
#include <
linux/mm.h
>
24
#include <linux/export.h>
25
#include <linux/sched.h>
26
#include <linux/slab.h>
27
#include <
linux/syscalls.h
>
28
29
/*
30
* Clone a task - this clones the calling program thread.
31
*/
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
)
35
{
36
if
(!newsp)
37
newsp = regs->
sp
;
38
/* 16-byte aligned stack mandatory on AArch64 */
39
if
(newsp & 15)
40
return
-
EINVAL
;
41
return
do_fork
(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
42
}
43
44
/*
45
* sys_execve() executes a new program.
46
*/
47
asmlinkage
long
sys_execve
(
const
char
__user *filenamei,
48
const
char
__user *
const
__user *argv,
49
const
char
__user *
const
__user *envp,
50
struct
pt_regs
*
regs
)
51
{
52
long
error
;
53
struct
filename
*
filename
;
54
55
filename =
getname
(filenamei);
56
error = PTR_ERR(filename);
57
if
(IS_ERR(filename))
58
goto
out
;
59
error =
do_execve
(filename->
name
, argv, envp, regs);
60
putname
(filename);
61
out
:
62
return
error
;
63
}
64
65
int
kernel_execve
(
const
char
*
filename
,
66
const
char
*
const
argv[],
67
const
char
*
const
envp[])
68
{
69
struct
pt_regs
regs;
70
int
ret
;
71
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);
76
if
(ret < 0)
77
goto
out
;
78
79
/*
80
* Save argc to the register structure for userspace.
81
*/
82
regs.
regs
[0] =
ret
;
83
84
/*
85
* We were successful. We won't be returning to our caller, but
86
* instead to user space by manipulating the kernel stack.
87
*/
88
asm
(
"add x0, %0, %1\n\t"
89
"mov x1, %2\n\t"
90
"mov x2, %3\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 */
95
"b ret_to_user"
96
:
97
:
"r"
(
current_thread_info
()),
98
"Ir"
(THREAD_START_SP -
sizeof
(regs)),
99
"r"
(®s),
100
"Ir"
(
sizeof
(
regs
))
101
:
"x0"
,
"x1"
,
"x2"
,
"x27"
,
"x28"
,
"x30"
,
"memory"
);
102
103
out
:
104
return
ret
;
105
}
106
EXPORT_SYMBOL
(
kernel_execve
);
107
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)
111
{
112
if
(
offset_in_page
(off) != 0)
113
return
-
EINVAL
;
114
115
return
sys_mmap_pgoff
(addr, len, prot, flags, fd, off >>
PAGE_SHIFT
);
116
}
117
118
/*
119
* Wrappers to pass the pt_regs argument.
120
*/
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
125
126
#include <asm/syscalls.h>
127
128
#undef __SYSCALL
129
#define __SYSCALL(nr, sym) [nr] = sym,
130
131
/*
132
* The sys_call_table array must be 4K aligned to be accessible from
133
* kernel/entry.S.
134
*/
135
void
*
sys_call_table
[
__NR_syscalls
]
__aligned
(4096) = {
136
[0 ...
__NR_syscalls
- 1] =
sys_ni_syscall
,
137
#include <asm/unistd.h>
138
};
Generated on Thu Jan 10 2013 13:03:42 for Linux Kernel by
1.8.2