2 * arch/v850/kernel/syscalls.c -- Various system-call definitions not
3 * defined in machine-independent code
5 * Copyright (C) 2001,02 NEC Corporation
6 * Copyright (C) 2001,02 Miles Bader <miles@gnu.org>
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.
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).
18 #include <linux/errno.h>
20 #include <linux/smp.h>
21 #include <linux/syscalls.h>
22 #include <linux/sem.h>
23 #include <linux/msg.h>
24 #include <linux/shm.h>
25 #include <linux/stat.h>
26 #include <linux/mman.h>
27 #include <linux/sys.h>
28 #include <linux/ipc.h>
29 #include <linux/utsname.h>
30 #include <linux/file.h>
32 #include <asm/uaccess.h>
33 #include <asm/semaphore.h>
34 #include <asm/unistd.h>
37 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
39 * This is really horribly ugly.
42 sys_ipc (uint call
, int first
, int second
, int third
, void *ptr
, long fifth
)
46 version
= call
>> 16; /* hack for backward compatibility */
52 ret
= sys_semop (first
, (struct sembuf
*)ptr
, second
);
55 ret
= sys_semget (first
, second
, third
);
63 if ((ret
= access_ok(VERIFY_READ
, ptr
, sizeof(long)) ? 0 : -EFAULT
)
64 || (ret
= get_user(fourth
.__pad
, (void **)ptr
)))
66 ret
= sys_semctl (first
, second
, third
, fourth
);
70 ret
= sys_msgsnd (first
, (struct msgbuf
*) ptr
, second
, third
);
75 struct ipc_kludge tmp
;
79 if ((ret
= access_ok(VERIFY_READ
, ptr
, sizeof(tmp
)) ? 0 : -EFAULT
)
80 || (ret
= copy_from_user(&tmp
,
81 (struct ipc_kludge
*) ptr
,
84 ret
= sys_msgrcv (first
, tmp
.msgp
, second
, tmp
.msgtyp
,
89 ret
= sys_msgrcv (first
, (struct msgbuf
*) ptr
,
90 second
, fifth
, third
);
95 ret
= sys_msgget ((key_t
) first
, second
);
98 ret
= sys_msgctl (first
, second
, (struct msqid_ds
*) ptr
);
105 if ((ret
= access_ok(VERIFY_WRITE
, (ulong
*) third
,
106 sizeof(ulong
)) ? 0 : -EFAULT
))
108 ret
= do_shmat (first
, (char *) ptr
, second
, &raddr
);
111 ret
= put_user (raddr
, (ulong
*) third
);
114 case 1: /* iBCS2 emulator entry point */
115 if (!segment_eq(get_fs(), get_ds()))
117 ret
= do_shmat (first
, (char *) ptr
, second
,
123 ret
= sys_shmdt ((char *)ptr
);
126 ret
= sys_shmget (first
, second
, third
);
129 ret
= sys_shmctl (first
, second
, (struct shmid_ds
*) ptr
);
137 * sys_pipe() is the normal C calling standard for creating
138 * a pipe. It's not the way unix traditionally does this, though.
140 int sys_pipe (int *fildes
)
145 error
= do_pipe (fd
);
147 if (copy_to_user (fildes
, fd
, 2*sizeof (int)))
153 static inline unsigned long
154 do_mmap2 (unsigned long addr
, size_t len
,
155 unsigned long prot
, unsigned long flags
,
156 unsigned long fd
, unsigned long pgoff
)
158 struct file
* file
= NULL
;
161 flags
&= ~(MAP_EXECUTABLE
| MAP_DENYWRITE
);
162 if (! (flags
& MAP_ANONYMOUS
)) {
163 if (!(file
= fget (fd
)))
167 down_write (¤t
->mm
->mmap_sem
);
168 ret
= do_mmap_pgoff (file
, addr
, len
, prot
, flags
, pgoff
);
169 up_write (¤t
->mm
->mmap_sem
);
176 unsigned long sys_mmap2 (unsigned long addr
, size_t len
,
177 unsigned long prot
, unsigned long flags
,
178 unsigned long fd
, unsigned long pgoff
)
180 return do_mmap2 (addr
, len
, prot
, flags
, fd
, pgoff
);
183 unsigned long sys_mmap (unsigned long addr
, size_t len
,
184 unsigned long prot
, unsigned long flags
,
185 unsigned long fd
, off_t offset
)
189 if (offset
& ~PAGE_MASK
)
192 err
= do_mmap2 (addr
, len
, prot
, flags
, fd
, offset
>> PAGE_SHIFT
);
198 * Do a system call from kernel instead of calling sys_execve so we
199 * end up with proper pt_regs.
201 int kernel_execve(const char *filename
, char *const argv
[], char *const envp
[])
203 register char *__a
__asm__ ("r6") = filename
;
204 register void *__b
__asm__ ("r7") = argv
;
205 register void *__c
__asm__ ("r8") = envp
;
206 register unsigned long __syscall
__asm__ ("r12") = __NR_execve
;
207 register unsigned long __ret
__asm__ ("r10");
208 __asm__
__volatile__ ("trap 0"
209 : "=r" (__ret
), "=r" (__syscall
)
210 : "1" (__syscall
), "r" (__a
), "r" (__b
), "r" (__c
)
211 : "r1", "r5", "r11", "r13", "r14",
212 "r15", "r16", "r17", "r18", "r19");