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/smp_lock.h>
22 #include <linux/syscalls.h>
23 #include <linux/sem.h>
24 #include <linux/msg.h>
25 #include <linux/shm.h>
26 #include <linux/stat.h>
27 #include <linux/mman.h>
28 #include <linux/sys.h>
29 #include <linux/ipc.h>
30 #include <linux/utsname.h>
31 #include <linux/file.h>
33 #include <asm/uaccess.h>
35 #include <asm/semaphore.h>
36 #include <asm/unistd.h>
39 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
41 * This is really horribly ugly.
44 sys_ipc (uint call
, int first
, int second
, int third
, void *ptr
, long fifth
)
48 version
= call
>> 16; /* hack for backward compatibility */
54 ret
= sys_semop (first
, (struct sembuf
*)ptr
, second
);
57 ret
= sys_semget (first
, second
, third
);
65 if ((ret
= access_ok(VERIFY_READ
, ptr
, sizeof(long)) ? 0 : -EFAULT
)
66 || (ret
= get_user(fourth
.__pad
, (void **)ptr
)))
68 ret
= sys_semctl (first
, second
, third
, fourth
);
72 ret
= sys_msgsnd (first
, (struct msgbuf
*) ptr
, second
, third
);
77 struct ipc_kludge tmp
;
81 if ((ret
= access_ok(VERIFY_READ
, ptr
, sizeof(tmp
)) ? 0 : -EFAULT
)
82 || (ret
= copy_from_user(&tmp
,
83 (struct ipc_kludge
*) ptr
,
86 ret
= sys_msgrcv (first
, tmp
.msgp
, second
, tmp
.msgtyp
,
91 ret
= sys_msgrcv (first
, (struct msgbuf
*) ptr
,
92 second
, fifth
, third
);
97 ret
= sys_msgget ((key_t
) first
, second
);
100 ret
= sys_msgctl (first
, second
, (struct msqid_ds
*) ptr
);
107 if ((ret
= access_ok(VERIFY_WRITE
, (ulong
*) third
,
108 sizeof(ulong
)) ? 0 : -EFAULT
))
110 ret
= do_shmat (first
, (char *) ptr
, second
, &raddr
);
113 ret
= put_user (raddr
, (ulong
*) third
);
116 case 1: /* iBCS2 emulator entry point */
117 if (!segment_eq(get_fs(), get_ds()))
119 ret
= do_shmat (first
, (char *) ptr
, second
,
125 ret
= sys_shmdt ((char *)ptr
);
128 ret
= sys_shmget (first
, second
, third
);
131 ret
= sys_shmctl (first
, second
, (struct shmid_ds
*) ptr
);
139 * sys_pipe() is the normal C calling standard for creating
140 * a pipe. It's not the way unix traditionally does this, though.
142 int sys_pipe (int *fildes
)
147 error
= do_pipe (fd
);
149 if (copy_to_user (fildes
, fd
, 2*sizeof (int)))
155 static inline unsigned long
156 do_mmap2 (unsigned long addr
, size_t len
,
157 unsigned long prot
, unsigned long flags
,
158 unsigned long fd
, unsigned long pgoff
)
160 struct file
* file
= NULL
;
163 flags
&= ~(MAP_EXECUTABLE
| MAP_DENYWRITE
);
164 if (! (flags
& MAP_ANONYMOUS
)) {
165 if (!(file
= fget (fd
)))
169 down_write (¤t
->mm
->mmap_sem
);
170 ret
= do_mmap_pgoff (file
, addr
, len
, prot
, flags
, pgoff
);
171 up_write (¤t
->mm
->mmap_sem
);
178 unsigned long sys_mmap2 (unsigned long addr
, size_t len
,
179 unsigned long prot
, unsigned long flags
,
180 unsigned long fd
, unsigned long pgoff
)
182 return do_mmap2 (addr
, len
, prot
, flags
, fd
, pgoff
);
185 unsigned long sys_mmap (unsigned long addr
, size_t len
,
186 unsigned long prot
, unsigned long flags
,
187 unsigned long fd
, off_t offset
)
191 if (offset
& ~PAGE_MASK
)
194 err
= do_mmap2 (addr
, len
, prot
, flags
, fd
, offset
>> PAGE_SHIFT
);
200 * Do a system call from kernel instead of calling sys_execve so we
201 * end up with proper pt_regs.
203 int kernel_execve(const char *filename
, char *const argv
[], char *const envp
[])
205 register char *__a
__asm__ ("r6") = filename
;
206 register void *__b
__asm__ ("r7") = argv
;
207 register void *__c
__asm__ ("r8") = envp
;
208 register unsigned long __syscall
__asm__ ("r12") = __NR_execve
;
209 register unsigned long __ret
__asm__ ("r10");
210 __asm__
__volatile__ ("trap 0"
211 : "=r" (__ret
), "=r" (__syscall
)
212 : "1" (__syscall
), "r" (__a
), "r" (__b
), "r" (__c
)
213 : "r1", "r5", "r11", "r13", "r14",
214 "r15", "r16", "r17", "r18", "r19");