aboutsummaryrefslogtreecommitdiffstats
path: root/arch/v850/kernel/syscalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/v850/kernel/syscalls.c')
-rw-r--r--arch/v850/kernel/syscalls.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/arch/v850/kernel/syscalls.c b/arch/v850/kernel/syscalls.c
new file mode 100644
index 000000000000..9224cb65f6ec
--- /dev/null
+++ b/arch/v850/kernel/syscalls.c
@@ -0,0 +1,197 @@
1/*
2 * arch/v850/kernel/syscalls.c -- Various system-call definitions not
3 * defined in machine-independent code
4 *
5 * Copyright (C) 2001,02 NEC Corporation
6 * Copyright (C) 2001,02 Miles Bader <miles@gnu.org>
7 *
8 * This file is subject to the terms and conditions of the GNU General
9 * Public License. See the file COPYING in the main directory of this
10 * archive for more details.
11 *
12 * This file was derived the ppc version, arch/ppc/kernel/syscalls.c
13 * ... which was derived from "arch/i386/kernel/sys_i386.c" by Gary Thomas;
14 * modified by Cort Dougan (cort@cs.nmt.edu)
15 * and Paul Mackerras (paulus@cs.anu.edu.au).
16 */
17
18#include <linux/config.h>
19#include <linux/errno.h>
20#include <linux/mm.h>
21#include <linux/smp.h>
22#include <linux/smp_lock.h>
23#include <linux/syscalls.h>
24#include <linux/sem.h>
25#include <linux/msg.h>
26#include <linux/shm.h>
27#include <linux/stat.h>
28#include <linux/mman.h>
29#include <linux/sys.h>
30#include <linux/ipc.h>
31#include <linux/utsname.h>
32#include <linux/file.h>
33
34#include <asm/uaccess.h>
35#include <asm/ipc.h>
36#include <asm/semaphore.h>
37
38/*
39 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
40 *
41 * This is really horribly ugly.
42 */
43int
44sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
45{
46 int version, ret;
47
48 version = call >> 16; /* hack for backward compatibility */
49 call &= 0xffff;
50
51 ret = -EINVAL;
52 switch (call) {
53 case SEMOP:
54 ret = sys_semop (first, (struct sembuf *)ptr, second);
55 break;
56 case SEMGET:
57 ret = sys_semget (first, second, third);
58 break;
59 case SEMCTL:
60 {
61 union semun fourth;
62
63 if (!ptr)
64 break;
65 if ((ret = access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT)
66 || (ret = get_user(fourth.__pad, (void **)ptr)))
67 break;
68 ret = sys_semctl (first, second, third, fourth);
69 break;
70 }
71 case MSGSND:
72 ret = sys_msgsnd (first, (struct msgbuf *) ptr, second, third);
73 break;
74 case MSGRCV:
75 switch (version) {
76 case 0: {
77 struct ipc_kludge tmp;
78
79 if (!ptr)
80 break;
81 if ((ret = access_ok(VERIFY_READ, ptr, sizeof(tmp)) ? 0 : -EFAULT)
82 || (ret = copy_from_user(&tmp,
83 (struct ipc_kludge *) ptr,
84 sizeof (tmp))))
85 break;
86 ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp,
87 third);
88 break;
89 }
90 default:
91 ret = sys_msgrcv (first, (struct msgbuf *) ptr,
92 second, fifth, third);
93 break;
94 }
95 break;
96 case MSGGET:
97 ret = sys_msgget ((key_t) first, second);
98 break;
99 case MSGCTL:
100 ret = sys_msgctl (first, second, (struct msqid_ds *) ptr);
101 break;
102 case SHMAT:
103 switch (version) {
104 default: {
105 ulong raddr;
106
107 if ((ret = access_ok(VERIFY_WRITE, (ulong*) third,
108 sizeof(ulong)) ? 0 : -EFAULT))
109 break;
110 ret = do_shmat (first, (char *) ptr, second, &raddr);
111 if (ret)
112 break;
113 ret = put_user (raddr, (ulong *) third);
114 break;
115 }
116 case 1: /* iBCS2 emulator entry point */
117 if (!segment_eq(get_fs(), get_ds()))
118 break;
119 ret = do_shmat (first, (char *) ptr, second,
120 (ulong *) third);
121 break;
122 }
123 break;
124 case SHMDT:
125 ret = sys_shmdt ((char *)ptr);
126 break;
127 case SHMGET:
128 ret = sys_shmget (first, second, third);
129 break;
130 case SHMCTL:
131 ret = sys_shmctl (first, second, (struct shmid_ds *) ptr);
132 break;
133 }
134
135 return ret;
136}
137
138/*
139 * sys_pipe() is the normal C calling standard for creating
140 * a pipe. It's not the way unix traditionally does this, though.
141 */
142int sys_pipe (int *fildes)
143{
144 int fd[2];
145 int error;
146
147 error = do_pipe (fd);
148 if (!error) {
149 if (copy_to_user (fildes, fd, 2*sizeof (int)))
150 error = -EFAULT;
151 }
152 return error;
153}
154
155static inline unsigned long
156do_mmap2 (unsigned long addr, size_t len,
157 unsigned long prot, unsigned long flags,
158 unsigned long fd, unsigned long pgoff)
159{
160 struct file * file = NULL;
161 int ret = -EBADF;
162
163 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
164 if (! (flags & MAP_ANONYMOUS)) {
165 if (!(file = fget (fd)))
166 goto out;
167 }
168
169 down_write (&current->mm->mmap_sem);
170 ret = do_mmap_pgoff (file, addr, len, prot, flags, pgoff);
171 up_write (&current->mm->mmap_sem);
172 if (file)
173 fput (file);
174out:
175 return ret;
176}
177
178unsigned long sys_mmap2 (unsigned long addr, size_t len,
179 unsigned long prot, unsigned long flags,
180 unsigned long fd, unsigned long pgoff)
181{
182 return do_mmap2 (addr, len, prot, flags, fd, pgoff);
183}
184
185unsigned long sys_mmap (unsigned long addr, size_t len,
186 unsigned long prot, unsigned long flags,
187 unsigned long fd, off_t offset)
188{
189 int err = -EINVAL;
190
191 if (offset & ~PAGE_MASK)
192 goto out;
193
194 err = do_mmap2 (addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
195out:
196 return err;
197}