aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-10-17 06:10:13 -0400
committerPaul Mackerras <paulus@samba.org>2005-10-17 06:10:13 -0400
commit30286ef6e044bc3d9019c3d8b900572e3fa05e65 (patch)
tree4d73bf0eb0da75d3c52613325d4085f139efdd39
parent30cd4a4e9c25e154ba087848a839bd0c6d024092 (diff)
powerpc: Merge syscalls.c and sys_ppc32.c.
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/Makefile6
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c (renamed from arch/ppc64/kernel/sys_ppc32.c)48
-rw-r--r--arch/powerpc/kernel/syscalls.c (renamed from arch/ppc64/kernel/syscalls.c)180
-rw-r--r--arch/powerpc/kernel/systbl.S6
-rw-r--r--arch/ppc/kernel/Makefile3
-rw-r--r--arch/ppc/kernel/syscalls.c268
-rw-r--r--arch/ppc64/kernel/Makefile4
-rw-r--r--arch/ppc64/kernel/misc.S8
8 files changed, 147 insertions, 376 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index ae97295f270d..1ca740bc5b47 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -11,7 +11,7 @@ CFLAGS_btext.o += -fPIC
11endif 11endif
12 12
13obj-y := semaphore.o cputable.o ptrace.o 13obj-y := semaphore.o cputable.o ptrace.o
14obj-$(CONFIG_PPC64) += binfmt_elf32.o 14obj-$(CONFIG_PPC64) += binfmt_elf32.o sys_ppc32.o
15obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 15obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
16obj-$(CONFIG_POWER4) += idle_power4.o 16obj-$(CONFIG_POWER4) += idle_power4.o
17obj-$(CONFIG_PPC_OF) += of_device.o 17obj-$(CONFIG_PPC_OF) += of_device.o
@@ -30,7 +30,7 @@ extra-$(CONFIG_PPC_FPU) += fpu.o
30extra-y += vmlinux.lds 30extra-y += vmlinux.lds
31 31
32obj-y += process.o init_task.o \ 32obj-y += process.o init_task.o \
33 prom.o systbl.o traps.o 33 prom.o systbl.o traps.o syscalls.o
34obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o 34obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o
35obj-$(CONFIG_PPC64) += setup_64.o misc_64.o 35obj-$(CONFIG_PPC64) += setup_64.o misc_64.o
36obj-$(CONFIG_PPC_OF) += prom_init.o 36obj-$(CONFIG_PPC_OF) += prom_init.o
@@ -44,7 +44,7 @@ endif
44 44
45else 45else
46# stuff used from here for ARCH=ppc or ARCH=ppc64 46# stuff used from here for ARCH=ppc or ARCH=ppc64
47obj-$(CONFIG_PPC64) += traps.o process.o init_task.o 47obj-$(CONFIG_PPC64) += traps.o process.o init_task.o syscalls.o
48 48
49fpux-$(CONFIG_PPC32) += fpu.o 49fpux-$(CONFIG_PPC32) += fpu.o
50extra-$(CONFIG_PPC_FPU) += $(fpux-y) 50extra-$(CONFIG_PPC_FPU) += $(fpux-y)
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index b53f565ee443..9babe055356e 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -985,54 +985,6 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
985} 985}
986#endif 986#endif
987 987
988asmlinkage int sys32_uname(struct old_utsname __user * name)
989{
990 int err = 0;
991
992 down_read(&uts_sem);
993 if (copy_to_user(name, &system_utsname, sizeof(*name)))
994 err = -EFAULT;
995 up_read(&uts_sem);
996 if (!err && personality(current->personality) == PER_LINUX32) {
997 /* change "ppc64" to "ppc" */
998 if (__put_user(0, name->machine + 3)
999 || __put_user(0, name->machine + 4))
1000 err = -EFAULT;
1001 }
1002 return err;
1003}
1004
1005asmlinkage int sys32_olduname(struct oldold_utsname __user * name)
1006{
1007 int error;
1008
1009 if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
1010 return -EFAULT;
1011
1012 down_read(&uts_sem);
1013 error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
1014 error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
1015 error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
1016 error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
1017 error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
1018 error |= __put_user(0,name->release+__OLD_UTS_LEN);
1019 error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
1020 error |= __put_user(0,name->version+__OLD_UTS_LEN);
1021 error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
1022 error |= __put_user(0,name->machine+__OLD_UTS_LEN);
1023 if (personality(current->personality) == PER_LINUX32) {
1024 /* change "ppc64" to "ppc" */
1025 error |= __put_user(0, name->machine + 3);
1026 error |= __put_user(0, name->machine + 4);
1027 }
1028
1029 up_read(&uts_sem);
1030
1031 error = error ? -EFAULT : 0;
1032
1033 return error;
1034}
1035
1036unsigned long sys32_mmap2(unsigned long addr, size_t len, 988unsigned long sys32_mmap2(unsigned long addr, size_t len,
1037 unsigned long prot, unsigned long flags, 989 unsigned long prot, unsigned long flags,
1038 unsigned long fd, unsigned long pgoff) 990 unsigned long fd, unsigned long pgoff)
diff --git a/arch/ppc64/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index 05f16633bd2c..3e3a4f67de96 100644
--- a/arch/ppc64/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -1,7 +1,6 @@
1/* 1/*
2 * linux/arch/ppc64/kernel/sys_ppc.c 2 * Implementation of various system calls for Linux/PowerPC
3 * 3 *
4 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 4 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 * 5 *
7 * Derived from "arch/i386/kernel/sys_i386.c" 6 * Derived from "arch/i386/kernel/sys_i386.c"
@@ -52,9 +51,8 @@ extern unsigned long wall_jiffies;
52 * 51 *
53 * This is really horribly ugly. 52 * This is really horribly ugly.
54 */ 53 */
55asmlinkage int 54int sys_ipc(uint call, int first, unsigned long second, long third,
56sys_ipc (uint call, int first, unsigned long second, long third, 55 void __user *ptr, long fifth)
57 void __user *ptr, long fifth)
58{ 56{
59 int version, ret; 57 int version, ret;
60 58
@@ -88,7 +86,7 @@ sys_ipc (uint call, int first, unsigned long second, long third,
88 } 86 }
89 case MSGSND: 87 case MSGSND:
90 ret = sys_msgsnd(first, (struct msgbuf __user *)ptr, 88 ret = sys_msgsnd(first, (struct msgbuf __user *)ptr,
91 (size_t)second, third); 89 (size_t)second, third);
92 break; 90 break;
93 case MSGRCV: 91 case MSGRCV:
94 switch (version) { 92 switch (version) {
@@ -113,41 +111,29 @@ sys_ipc (uint call, int first, unsigned long second, long third,
113 } 111 }
114 break; 112 break;
115 case MSGGET: 113 case MSGGET:
116 ret = sys_msgget ((key_t)first, (int)second); 114 ret = sys_msgget((key_t)first, (int)second);
117 break; 115 break;
118 case MSGCTL: 116 case MSGCTL:
119 ret = sys_msgctl(first, (int)second, 117 ret = sys_msgctl(first, (int)second,
120 (struct msqid_ds __user *)ptr); 118 (struct msqid_ds __user *)ptr);
121 break; 119 break;
122 case SHMAT: 120 case SHMAT: {
123 switch (version) { 121 ulong raddr;
124 default: { 122 ret = do_shmat(first, (char __user *)ptr, (int)second, &raddr);
125 ulong raddr; 123 if (ret)
126 ret = do_shmat(first, (char __user *) ptr,
127 (int)second, &raddr);
128 if (ret)
129 break;
130 ret = put_user (raddr, (ulong __user *) third);
131 break;
132 }
133 case 1: /* iBCS2 emulator entry point */
134 ret = -EINVAL;
135 if (!segment_eq(get_fs(), get_ds()))
136 break;
137 ret = do_shmat(first, (char __user *)ptr,
138 (int)second, (ulong *)third);
139 break; 124 break;
140 } 125 ret = put_user(raddr, (ulong __user *) third);
141 break; 126 break;
142 case SHMDT: 127 }
143 ret = sys_shmdt ((char __user *)ptr); 128 case SHMDT:
129 ret = sys_shmdt((char __user *)ptr);
144 break; 130 break;
145 case SHMGET: 131 case SHMGET:
146 ret = sys_shmget (first, (size_t)second, third); 132 ret = sys_shmget(first, (size_t)second, third);
147 break; 133 break;
148 case SHMCTL: 134 case SHMCTL:
149 ret = sys_shmctl(first, (int)second, 135 ret = sys_shmctl(first, (int)second,
150 (struct shmid_ds __user *)ptr); 136 (struct shmid_ds __user *)ptr);
151 break; 137 break;
152 } 138 }
153 139
@@ -158,43 +144,89 @@ sys_ipc (uint call, int first, unsigned long second, long third,
158 * sys_pipe() is the normal C calling standard for creating 144 * sys_pipe() is the normal C calling standard for creating
159 * a pipe. It's not the way unix traditionally does this, though. 145 * a pipe. It's not the way unix traditionally does this, though.
160 */ 146 */
161asmlinkage int sys_pipe(int __user *fildes) 147int sys_pipe(int __user *fildes)
162{ 148{
163 int fd[2]; 149 int fd[2];
164 int error; 150 int error;
165 151
166 error = do_pipe(fd); 152 error = do_pipe(fd);
167 if (!error) { 153 if (!error) {
168 if (copy_to_user(fildes, fd, 2*sizeof(int))) 154 if (copy_to_user(fildes, fd, 2*sizeof(int)))
169 error = -EFAULT; 155 error = -EFAULT;
170 } 156 }
171
172 return error; 157 return error;
173} 158}
174 159
175unsigned long sys_mmap(unsigned long addr, size_t len, 160static inline unsigned long do_mmap2(unsigned long addr, size_t len,
176 unsigned long prot, unsigned long flags, 161 unsigned long prot, unsigned long flags,
177 unsigned long fd, off_t offset) 162 unsigned long fd, unsigned long off, int shift)
178{ 163{
179 struct file * file = NULL; 164 struct file * file = NULL;
180 unsigned long ret = -EBADF; 165 int ret = -EINVAL;
181 166
167 if (shift) {
168 if (off & ((1 << shift) - 1))
169 goto out;
170 off >>= shift;
171 }
172
173 ret = -EBADF;
182 if (!(flags & MAP_ANONYMOUS)) { 174 if (!(flags & MAP_ANONYMOUS)) {
183 if (!(file = fget(fd))) 175 if (!(file = fget(fd)))
184 goto out; 176 goto out;
185 } 177 }
186 178
187 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); 179 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
180
188 down_write(&current->mm->mmap_sem); 181 down_write(&current->mm->mmap_sem);
189 ret = do_mmap(file, addr, len, prot, flags, offset); 182 ret = do_mmap_pgoff(file, addr, len, prot, flags, off);
190 up_write(&current->mm->mmap_sem); 183 up_write(&current->mm->mmap_sem);
191 if (file) 184 if (file)
192 fput(file); 185 fput(file);
193
194out: 186out:
195 return ret; 187 return ret;
196} 188}
197 189
190unsigned long sys_mmap2(unsigned long addr, size_t len,
191 unsigned long prot, unsigned long flags,
192 unsigned long fd, unsigned long pgoff)
193{
194 return do_mmap2(addr, len, prot, flags, fd, pgoff, PAGE_SHIFT-12);
195}
196
197unsigned long sys_mmap(unsigned long addr, size_t len,
198 unsigned long prot, unsigned long flags,
199 unsigned long fd, off_t offset)
200{
201 return do_mmap2(addr, len, prot, flags, fd, offset, PAGE_SHIFT);
202}
203
204#ifdef CONFIG_PPC32
205/*
206 * Due to some executables calling the wrong select we sometimes
207 * get wrong args. This determines how the args are being passed
208 * (a single ptr to them all args passed) then calls
209 * sys_select() with the appropriate args. -- Cort
210 */
211int
212ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp)
213{
214 if ( (unsigned long)n >= 4096 )
215 {
216 unsigned long __user *buffer = (unsigned long __user *)n;
217 if (!access_ok(VERIFY_READ, buffer, 5*sizeof(unsigned long))
218 || __get_user(n, buffer)
219 || __get_user(inp, ((fd_set __user * __user *)(buffer+1)))
220 || __get_user(outp, ((fd_set __user * __user *)(buffer+2)))
221 || __get_user(exp, ((fd_set __user * __user *)(buffer+3)))
222 || __get_user(tvp, ((struct timeval __user * __user *)(buffer+4))))
223 return -EFAULT;
224 }
225 return sys_select(n, inp, outp, exp, tvp);
226}
227#endif
228
229#ifdef CONFIG_PPC64
198long ppc64_personality(unsigned long personality) 230long ppc64_personality(unsigned long personality)
199{ 231{
200 long ret; 232 long ret;
@@ -207,8 +239,25 @@ long ppc64_personality(unsigned long personality)
207 ret = PER_LINUX; 239 ret = PER_LINUX;
208 return ret; 240 return ret;
209} 241}
242#endif
243
244#ifdef CONFIG_PPC64
245#define OVERRIDE_MACHINE (personality(current->personality) == PER_LINUX32)
246#else
247#define OVERRIDE_MACHINE 0
248#endif
210 249
211long ppc64_newuname(struct new_utsname __user * name) 250static inline int override_machine(char *mach)
251{
252 if (OVERRIDE_MACHINE) {
253 /* change ppc64 to ppc */
254 if (__put_user(0, mach+3) || __put_user(0, mach+4))
255 return -EFAULT;
256 }
257 return 0;
258}
259
260long ppc_newuname(struct new_utsname __user * name)
212{ 261{
213 int err = 0; 262 int err = 0;
214 263
@@ -216,16 +265,54 @@ long ppc64_newuname(struct new_utsname __user * name)
216 if (copy_to_user(name, &system_utsname, sizeof(*name))) 265 if (copy_to_user(name, &system_utsname, sizeof(*name)))
217 err = -EFAULT; 266 err = -EFAULT;
218 up_read(&uts_sem); 267 up_read(&uts_sem);
219 if (!err && personality(current->personality) == PER_LINUX32) { 268 if (!err)
220 /* change ppc64 to ppc */ 269 err = override_machine(name->machine);
221 if (__put_user(0, name->machine + 3)
222 || __put_user(0, name->machine + 4))
223 err = -EFAULT;
224 }
225 return err; 270 return err;
226} 271}
227 272
228asmlinkage time_t sys64_time(time_t __user * tloc) 273int sys_uname(struct old_utsname __user *name)
274{
275 int err = 0;
276
277 down_read(&uts_sem);
278 if (copy_to_user(name, &system_utsname, sizeof(*name)))
279 err = -EFAULT;
280 up_read(&uts_sem);
281 if (!err)
282 err = override_machine(name->machine);
283 return err;
284}
285
286int sys_olduname(struct oldold_utsname __user *name)
287{
288 int error;
289
290 if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
291 return -EFAULT;
292
293 down_read(&uts_sem);
294 error = __copy_to_user(&name->sysname, &system_utsname.sysname,
295 __OLD_UTS_LEN);
296 error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
297 error |= __copy_to_user(&name->nodename, &system_utsname.nodename,
298 __OLD_UTS_LEN);
299 error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
300 error |= __copy_to_user(&name->release, &system_utsname.release,
301 __OLD_UTS_LEN);
302 error |= __put_user(0, name->release + __OLD_UTS_LEN);
303 error |= __copy_to_user(&name->version, &system_utsname.version,
304 __OLD_UTS_LEN);
305 error |= __put_user(0, name->version + __OLD_UTS_LEN);
306 error |= __copy_to_user(&name->machine, &system_utsname.machine,
307 __OLD_UTS_LEN);
308 error |= override_machine(name->machine);
309 up_read(&uts_sem);
310
311 return error? -EFAULT: 0;
312}
313
314#ifdef CONFIG_PPC64
315time_t sys64_time(time_t __user * tloc)
229{ 316{
230 time_t secs; 317 time_t secs;
231 time_t usecs; 318 time_t usecs;
@@ -247,6 +334,7 @@ asmlinkage time_t sys64_time(time_t __user * tloc)
247 334
248 return secs; 335 return secs;
249} 336}
337#endif
250 338
251void do_show_syscall(unsigned long r3, unsigned long r4, unsigned long r5, 339void do_show_syscall(unsigned long r3, unsigned long r4, unsigned long r5,
252 unsigned long r6, unsigned long r7, unsigned long r8, 340 unsigned long r6, unsigned long r7, unsigned long r8,
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 82d1fedb441c..b364141ec01c 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -102,7 +102,7 @@ COMPAT_SYS(fcntl)
102SYSCALL(ni_syscall) 102SYSCALL(ni_syscall)
103SYSCALL32(setpgid) 103SYSCALL32(setpgid)
104SYSCALL(ni_syscall) 104SYSCALL(ni_syscall)
105SYS32ONLY(olduname) 105SYSX(sys_ni_syscall,sys_olduname, sys_olduname)
106SYSCALL32(umask) 106SYSCALL32(umask)
107SYSCALL(chroot) 107SYSCALL(chroot)
108SYSCALL(ustat) 108SYSCALL(ustat)
@@ -152,7 +152,7 @@ COMPAT_SYS(getitimer)
152COMPAT_SYS(newstat) 152COMPAT_SYS(newstat)
153COMPAT_SYS(newlstat) 153COMPAT_SYS(newlstat)
154COMPAT_SYS(newfstat) 154COMPAT_SYS(newfstat)
155SYSX(sys_ni_syscall,sys32_uname,sys_uname) 155SYSX(sys_ni_syscall,sys_uname,sys_uname)
156SYSCALL(ni_syscall) 156SYSCALL(ni_syscall)
157SYSCALL(vhangup) 157SYSCALL(vhangup)
158SYSCALL(ni_syscall) 158SYSCALL(ni_syscall)
@@ -165,7 +165,7 @@ SYSCALL(fsync)
165SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn) 165SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn)
166PPC_SYS(clone) 166PPC_SYS(clone)
167SYSCALL32(setdomainname) 167SYSCALL32(setdomainname)
168SYSX(ppc64_newuname,ppc64_newuname,sys_newuname) 168PPC_SYS(newuname)
169SYSCALL(ni_syscall) 169SYSCALL(ni_syscall)
170SYSCALL32(adjtimex) 170SYSCALL32(adjtimex)
171SYSCALL(mprotect) 171SYSCALL(mprotect)
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 7d16b1f7cd31..87d3be4af820 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -38,8 +38,7 @@ endif
38 38
39else 39else
40obj-y := irq.o idle.o time.o \ 40obj-y := irq.o idle.o time.o \
41 signal.o align.o \ 41 signal.o align.o perfmon.o
42 syscalls.o perfmon.o
43obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o 42obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
44obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o 43obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
45obj-$(CONFIG_MODULES) += module.o 44obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c
deleted file mode 100644
index 127f040de9de..000000000000
--- a/arch/ppc/kernel/syscalls.c
+++ /dev/null
@@ -1,268 +0,0 @@
1/*
2 * arch/ppc/kernel/sys_ppc.c
3 *
4 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 *
7 * Derived from "arch/i386/kernel/sys_i386.c"
8 * Adapted from the i386 version by Gary Thomas
9 * Modified by Cort Dougan (cort@cs.nmt.edu)
10 * and Paul Mackerras (paulus@cs.anu.edu.au).
11 *
12 * This file contains various random system calls that
13 * have a non-standard calling sequence on the Linux/PPC
14 * platform.
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version
19 * 2 of the License, or (at your option) any later version.
20 *
21 */
22
23#include <linux/errno.h>
24#include <linux/sched.h>
25#include <linux/mm.h>
26#include <linux/smp.h>
27#include <linux/smp_lock.h>
28#include <linux/sem.h>
29#include <linux/msg.h>
30#include <linux/shm.h>
31#include <linux/stat.h>
32#include <linux/syscalls.h>
33#include <linux/mman.h>
34#include <linux/sys.h>
35#include <linux/ipc.h>
36#include <linux/utsname.h>
37#include <linux/file.h>
38#include <linux/unistd.h>
39
40#include <asm/uaccess.h>
41#include <asm/ipc.h>
42#include <asm/semaphore.h>
43
44
45/*
46 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
47 *
48 * This is really horribly ugly.
49 */
50int
51sys_ipc (uint call, int first, int second, int third, void __user *ptr, long fifth)
52{
53 int version, ret;
54
55 version = call >> 16; /* hack for backward compatibility */
56 call &= 0xffff;
57
58 ret = -ENOSYS;
59 switch (call) {
60 case SEMOP:
61 ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
62 second, NULL);
63 break;
64 case SEMTIMEDOP:
65 ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
66 second, (const struct timespec __user *) fifth);
67 break;
68 case SEMGET:
69 ret = sys_semget (first, second, third);
70 break;
71 case SEMCTL: {
72 union semun fourth;
73
74 if (!ptr)
75 break;
76 if ((ret = access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT)
77 || (ret = get_user(fourth.__pad, (void __user *__user *)ptr)))
78 break;
79 ret = sys_semctl (first, second, third, fourth);
80 break;
81 }
82 case MSGSND:
83 ret = sys_msgsnd (first, (struct msgbuf __user *) ptr, second, third);
84 break;
85 case MSGRCV:
86 switch (version) {
87 case 0: {
88 struct ipc_kludge tmp;
89
90 if (!ptr)
91 break;
92 if ((ret = access_ok(VERIFY_READ, ptr, sizeof(tmp)) ? 0 : -EFAULT)
93 || (ret = copy_from_user(&tmp,
94 (struct ipc_kludge __user *) ptr,
95 sizeof (tmp)) ? -EFAULT : 0))
96 break;
97 ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp,
98 third);
99 break;
100 }
101 default:
102 ret = sys_msgrcv (first, (struct msgbuf __user *) ptr,
103 second, fifth, third);
104 break;
105 }
106 break;
107 case MSGGET:
108 ret = sys_msgget ((key_t) first, second);
109 break;
110 case MSGCTL:
111 ret = sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
112 break;
113 case SHMAT: {
114 ulong raddr;
115
116 if ((ret = access_ok(VERIFY_WRITE, (ulong __user *) third,
117 sizeof(ulong)) ? 0 : -EFAULT))
118 break;
119 ret = do_shmat (first, (char __user *) ptr, second, &raddr);
120 if (ret)
121 break;
122 ret = put_user (raddr, (ulong __user *) third);
123 break;
124 }
125 case SHMDT:
126 ret = sys_shmdt ((char __user *)ptr);
127 break;
128 case SHMGET:
129 ret = sys_shmget (first, second, third);
130 break;
131 case SHMCTL:
132 ret = sys_shmctl (first, second, (struct shmid_ds __user *) ptr);
133 break;
134 }
135
136 return ret;
137}
138
139/*
140 * sys_pipe() is the normal C calling standard for creating
141 * a pipe. It's not the way unix traditionally does this, though.
142 */
143int sys_pipe(int __user *fildes)
144{
145 int fd[2];
146 int error;
147
148 error = do_pipe(fd);
149 if (!error) {
150 if (copy_to_user(fildes, fd, 2*sizeof(int)))
151 error = -EFAULT;
152 }
153 return error;
154}
155
156static inline unsigned long
157do_mmap2(unsigned long addr, size_t len,
158 unsigned long prot, unsigned long flags,
159 unsigned long fd, unsigned long pgoff)
160{
161 struct file * file = NULL;
162 int ret = -EBADF;
163
164 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
165 if (!(flags & MAP_ANONYMOUS)) {
166 if (!(file = fget(fd)))
167 goto out;
168 }
169
170 down_write(&current->mm->mmap_sem);
171 ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
172 up_write(&current->mm->mmap_sem);
173 if (file)
174 fput(file);
175out:
176 return ret;
177}
178
179unsigned long sys_mmap2(unsigned long addr, size_t len,
180 unsigned long prot, unsigned long flags,
181 unsigned long fd, unsigned long pgoff)
182{
183 return do_mmap2(addr, len, prot, flags, fd, pgoff);
184}
185
186unsigned long sys_mmap(unsigned long addr, size_t len,
187 unsigned long prot, unsigned long flags,
188 unsigned long fd, off_t offset)
189{
190 int err = -EINVAL;
191
192 if (offset & ~PAGE_MASK)
193 goto out;
194
195 err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
196out:
197 return err;
198}
199
200/*
201 * Due to some executables calling the wrong select we sometimes
202 * get wrong args. This determines how the args are being passed
203 * (a single ptr to them all args passed) then calls
204 * sys_select() with the appropriate args. -- Cort
205 */
206int
207ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp)
208{
209 if ( (unsigned long)n >= 4096 )
210 {
211 unsigned long __user *buffer = (unsigned long __user *)n;
212 if (!access_ok(VERIFY_READ, buffer, 5*sizeof(unsigned long))
213 || __get_user(n, buffer)
214 || __get_user(inp, ((fd_set __user * __user *)(buffer+1)))
215 || __get_user(outp, ((fd_set __user * __user *)(buffer+2)))
216 || __get_user(exp, ((fd_set __user * __user *)(buffer+3)))
217 || __get_user(tvp, ((struct timeval __user * __user *)(buffer+4))))
218 return -EFAULT;
219 }
220 return sys_select(n, inp, outp, exp, tvp);
221}
222
223int sys_uname(struct old_utsname __user * name)
224{
225 int err = -EFAULT;
226
227 down_read(&uts_sem);
228 if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
229 err = 0;
230 up_read(&uts_sem);
231 return err;
232}
233
234int sys_olduname(struct oldold_utsname __user * name)
235{
236 int error;
237
238 if (!name)
239 return -EFAULT;
240 if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
241 return -EFAULT;
242
243 down_read(&uts_sem);
244 error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
245 error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
246 error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
247 error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
248 error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
249 error -= __put_user(0,name->release+__OLD_UTS_LEN);
250 error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
251 error -= __put_user(0,name->version+__OLD_UTS_LEN);
252 error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
253 error = __put_user(0,name->machine+__OLD_UTS_LEN);
254 up_read(&uts_sem);
255
256 error = error ? -EFAULT : 0;
257 return error;
258}
259
260/*
261 * We put the arguments in a different order so we only use 6
262 * registers for arguments, rather than 7 as sys_fadvise64_64 needs
263 * (because `offset' goes in r5/r6).
264 */
265long ppc_fadvise64_64(int fd, int advice, loff_t offset, loff_t len)
266{
267 return sys_fadvise64_64(fd, offset, len, advice);
268}
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
index b1203b79edf0..0be7c7ecefdf 100644
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -12,9 +12,9 @@ obj-y := setup.o entry.o misc.o prom.o
12endif 12endif
13 13
14obj-y += irq.o idle.o dma.o \ 14obj-y += irq.o idle.o dma.o \
15 time.o signal.o syscalls.o \ 15 time.o signal.o \
16 align.o bitops.o pacaData.o \ 16 align.o bitops.o pacaData.o \
17 udbg.o sys_ppc32.o ioctl32.o \ 17 udbg.o ioctl32.o \
18 ptrace32.o signal32.o rtc.o \ 18 ptrace32.o signal32.o rtc.o \
19 cpu_setup_power4.o \ 19 cpu_setup_power4.o \
20 iommu.o sysfs.o vdso.o pmc.o firmware.o 20 iommu.o sysfs.o vdso.o pmc.o firmware.o
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index f9f2131d2fb5..eb407c429bb0 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -980,7 +980,7 @@ _GLOBAL(sys_call_table32)
980 .llong .sys_ni_syscall /* old mpx syscall */ 980 .llong .sys_ni_syscall /* old mpx syscall */
981 .llong .sys32_setpgid 981 .llong .sys32_setpgid
982 .llong .sys_ni_syscall /* old ulimit syscall */ 982 .llong .sys_ni_syscall /* old ulimit syscall */
983 .llong .sys32_olduname 983 .llong .sys_olduname
984 .llong .sys32_umask /* 60 */ 984 .llong .sys32_umask /* 60 */
985 .llong .sys_chroot 985 .llong .sys_chroot
986 .llong .sys_ustat 986 .llong .sys_ustat
@@ -1030,7 +1030,7 @@ _GLOBAL(sys_call_table32)
1030 .llong .compat_sys_newstat 1030 .llong .compat_sys_newstat
1031 .llong .compat_sys_newlstat 1031 .llong .compat_sys_newlstat
1032 .llong .compat_sys_newfstat 1032 .llong .compat_sys_newfstat
1033 .llong .sys32_uname 1033 .llong .sys_uname
1034 .llong .sys_ni_syscall /* 110 old iopl syscall */ 1034 .llong .sys_ni_syscall /* 110 old iopl syscall */
1035 .llong .sys_vhangup 1035 .llong .sys_vhangup
1036 .llong .sys_ni_syscall /* old idle syscall */ 1036 .llong .sys_ni_syscall /* old idle syscall */
@@ -1043,7 +1043,7 @@ _GLOBAL(sys_call_table32)
1043 .llong .ppc32_sigreturn 1043 .llong .ppc32_sigreturn
1044 .llong .ppc_clone /* 120 */ 1044 .llong .ppc_clone /* 120 */
1045 .llong .sys32_setdomainname 1045 .llong .sys32_setdomainname
1046 .llong .ppc64_newuname 1046 .llong .ppc_newuname
1047 .llong .sys_ni_syscall /* old modify_ldt syscall */ 1047 .llong .sys_ni_syscall /* old modify_ldt syscall */
1048 .llong .sys32_adjtimex 1048 .llong .sys32_adjtimex
1049 .llong .sys_mprotect /* 125 */ 1049 .llong .sys_mprotect /* 125 */
@@ -1324,7 +1324,7 @@ _GLOBAL(sys_call_table)
1324 .llong .sys_ni_syscall 1324 .llong .sys_ni_syscall
1325 .llong .ppc_clone /* 120 */ 1325 .llong .ppc_clone /* 120 */
1326 .llong .sys_setdomainname 1326 .llong .sys_setdomainname
1327 .llong .ppc64_newuname 1327 .llong .ppc_newuname
1328 .llong .sys_ni_syscall /* old modify_ldt syscall */ 1328 .llong .sys_ni_syscall /* old modify_ldt syscall */
1329 .llong .sys_adjtimex 1329 .llong .sys_adjtimex
1330 .llong .sys_mprotect /* 125 */ 1330 .llong .sys_mprotect /* 125 */