blob: 8a22868f6b07fa58b73f7363473cee8298af27bf [file] [log] [blame]
Nicholas Flintham1e3d3112013-04-10 10:48:38 +01001/*
2 * linux/arch/arm/kernel/sys_arm.c
3 *
4 * Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c
5 * Copyright (C) 1995, 1996 Russell King.
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 file contains various random system calls that
12 * have a non-standard calling sequence on the Linux/arm
13 * platform.
14 */
15#include <linux/export.h>
16#include <linux/errno.h>
17#include <linux/sched.h>
18#include <linux/mm.h>
19#include <linux/sem.h>
20#include <linux/msg.h>
21#include <linux/shm.h>
22#include <linux/stat.h>
23#include <linux/syscalls.h>
24#include <linux/mman.h>
25#include <linux/fs.h>
26#include <linux/file.h>
27#include <linux/ipc.h>
28#include <linux/uaccess.h>
29#include <linux/slab.h>
30
31asmlinkage int sys_fork(struct pt_regs *regs)
32{
33#ifdef CONFIG_MMU
34 return do_fork(SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
35#else
36
37 return(-EINVAL);
38#endif
39}
40
41asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
42 int __user *parent_tidptr, int tls_val,
43 int __user *child_tidptr, struct pt_regs *regs)
44{
45 if (!newsp)
46 newsp = regs->ARM_sp;
47
48 return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
49}
50
51asmlinkage int sys_vfork(struct pt_regs *regs)
52{
53 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
54}
55
56asmlinkage int sys_execve(const char __user *filenamei,
57 const char __user *const __user *argv,
58 const char __user *const __user *envp, struct pt_regs *regs)
59{
60 int error;
61 char * filename;
62
63 filename = getname(filenamei);
64 error = PTR_ERR(filename);
65 if (IS_ERR(filename))
66 goto out;
67 error = do_execve(filename, argv, envp, regs);
68 putname(filename);
69out:
70 return error;
71}
72
73int kernel_execve(const char *filename,
74 const char *const argv[],
75 const char *const envp[])
76{
77 struct pt_regs regs;
78 int ret;
79
80 memset(&regs, 0, sizeof(struct pt_regs));
81 ret = do_execve(filename,
82 (const char __user *const __user *)argv,
83 (const char __user *const __user *)envp, &regs);
84 if (ret < 0)
85 goto out;
86
87 regs.ARM_r0 = ret;
88
89 asm( "add r0, %0, %1\n\t"
90 "mov r1, %2\n\t"
91 "mov r2, %3\n\t"
92 "bl memmove\n\t"
93 "mov r8, #0\n\t"
94 "mov r9, %0\n\t"
95 "mov sp, r0\n\t"
96 "b ret_to_user"
97 :
98 : "r" (current_thread_info()),
99 "Ir" (THREAD_START_SP - sizeof(regs)),
100 "r" (&regs),
101 "Ir" (sizeof(regs))
102 : "r0", "r1", "r2", "r3", "r8", "r9", "ip", "lr", "memory");
103
104 out:
105 return ret;
106}
107EXPORT_SYMBOL(kernel_execve);
108
109asmlinkage long sys_arm_fadvise64_64(int fd, int advice,
110 loff_t offset, loff_t len)
111{
112 return sys_fadvise64_64(fd, offset, len, advice);
113}