diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/Makefile | 6 | ||||
-rw-r--r-- | arch/powerpc/kernel/sys_ppc32.c | 1127 | ||||
-rw-r--r-- | arch/powerpc/kernel/syscalls.c | 351 | ||||
-rw-r--r-- | arch/powerpc/kernel/systbl.S | 6 |
4 files changed, 1484 insertions, 6 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 | |||
11 | endif | 11 | endif |
12 | 12 | ||
13 | obj-y := semaphore.o cputable.o ptrace.o | 13 | obj-y := semaphore.o cputable.o ptrace.o |
14 | obj-$(CONFIG_PPC64) += binfmt_elf32.o | 14 | obj-$(CONFIG_PPC64) += binfmt_elf32.o sys_ppc32.o |
15 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o | 15 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o |
16 | obj-$(CONFIG_POWER4) += idle_power4.o | 16 | obj-$(CONFIG_POWER4) += idle_power4.o |
17 | obj-$(CONFIG_PPC_OF) += of_device.o | 17 | obj-$(CONFIG_PPC_OF) += of_device.o |
@@ -30,7 +30,7 @@ extra-$(CONFIG_PPC_FPU) += fpu.o | |||
30 | extra-y += vmlinux.lds | 30 | extra-y += vmlinux.lds |
31 | 31 | ||
32 | obj-y += process.o init_task.o \ | 32 | obj-y += process.o init_task.o \ |
33 | prom.o systbl.o traps.o | 33 | prom.o systbl.o traps.o syscalls.o |
34 | obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o | 34 | obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o |
35 | obj-$(CONFIG_PPC64) += setup_64.o misc_64.o | 35 | obj-$(CONFIG_PPC64) += setup_64.o misc_64.o |
36 | obj-$(CONFIG_PPC_OF) += prom_init.o | 36 | obj-$(CONFIG_PPC_OF) += prom_init.o |
@@ -44,7 +44,7 @@ endif | |||
44 | 44 | ||
45 | else | 45 | else |
46 | # stuff used from here for ARCH=ppc or ARCH=ppc64 | 46 | # stuff used from here for ARCH=ppc or ARCH=ppc64 |
47 | obj-$(CONFIG_PPC64) += traps.o process.o init_task.o | 47 | obj-$(CONFIG_PPC64) += traps.o process.o init_task.o syscalls.o |
48 | 48 | ||
49 | fpux-$(CONFIG_PPC32) += fpu.o | 49 | fpux-$(CONFIG_PPC32) += fpu.o |
50 | extra-$(CONFIG_PPC_FPU) += $(fpux-y) | 50 | extra-$(CONFIG_PPC_FPU) += $(fpux-y) |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c new file mode 100644 index 000000000000..9babe055356e --- /dev/null +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
@@ -0,0 +1,1127 @@ | |||
1 | /* | ||
2 | * sys_ppc32.c: Conversion between 32bit and 64bit native syscalls. | ||
3 | * | ||
4 | * Copyright (C) 2001 IBM | ||
5 | * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
6 | * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) | ||
7 | * | ||
8 | * These routines maintain argument size conversion between 32bit and 64bit | ||
9 | * environment. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version | ||
14 | * 2 of the License, or (at your option) any later version. | ||
15 | */ | ||
16 | |||
17 | #include <linux/config.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/fs.h> | ||
21 | #include <linux/mm.h> | ||
22 | #include <linux/file.h> | ||
23 | #include <linux/signal.h> | ||
24 | #include <linux/resource.h> | ||
25 | #include <linux/times.h> | ||
26 | #include <linux/utsname.h> | ||
27 | #include <linux/timex.h> | ||
28 | #include <linux/smp.h> | ||
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/sem.h> | ||
31 | #include <linux/msg.h> | ||
32 | #include <linux/shm.h> | ||
33 | #include <linux/poll.h> | ||
34 | #include <linux/personality.h> | ||
35 | #include <linux/stat.h> | ||
36 | #include <linux/mman.h> | ||
37 | #include <linux/in.h> | ||
38 | #include <linux/syscalls.h> | ||
39 | #include <linux/unistd.h> | ||
40 | #include <linux/sysctl.h> | ||
41 | #include <linux/binfmts.h> | ||
42 | #include <linux/security.h> | ||
43 | #include <linux/compat.h> | ||
44 | #include <linux/ptrace.h> | ||
45 | #include <linux/elf.h> | ||
46 | |||
47 | #include <asm/ptrace.h> | ||
48 | #include <asm/types.h> | ||
49 | #include <asm/ipc.h> | ||
50 | #include <asm/uaccess.h> | ||
51 | #include <asm/unistd.h> | ||
52 | #include <asm/semaphore.h> | ||
53 | #include <asm/time.h> | ||
54 | #include <asm/mmu_context.h> | ||
55 | #include <asm/systemcfg.h> | ||
56 | #include <asm/ppc-pci.h> | ||
57 | |||
58 | /* readdir & getdents */ | ||
59 | #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) | ||
60 | #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1)) | ||
61 | |||
62 | struct old_linux_dirent32 { | ||
63 | u32 d_ino; | ||
64 | u32 d_offset; | ||
65 | unsigned short d_namlen; | ||
66 | char d_name[1]; | ||
67 | }; | ||
68 | |||
69 | struct readdir_callback32 { | ||
70 | struct old_linux_dirent32 __user * dirent; | ||
71 | int count; | ||
72 | }; | ||
73 | |||
74 | static int fillonedir(void * __buf, const char * name, int namlen, | ||
75 | off_t offset, ino_t ino, unsigned int d_type) | ||
76 | { | ||
77 | struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf; | ||
78 | struct old_linux_dirent32 __user * dirent; | ||
79 | |||
80 | if (buf->count) | ||
81 | return -EINVAL; | ||
82 | buf->count++; | ||
83 | dirent = buf->dirent; | ||
84 | put_user(ino, &dirent->d_ino); | ||
85 | put_user(offset, &dirent->d_offset); | ||
86 | put_user(namlen, &dirent->d_namlen); | ||
87 | copy_to_user(dirent->d_name, name, namlen); | ||
88 | put_user(0, dirent->d_name + namlen); | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 __user *dirent, unsigned int count) | ||
93 | { | ||
94 | int error = -EBADF; | ||
95 | struct file * file; | ||
96 | struct readdir_callback32 buf; | ||
97 | |||
98 | file = fget(fd); | ||
99 | if (!file) | ||
100 | goto out; | ||
101 | |||
102 | buf.count = 0; | ||
103 | buf.dirent = dirent; | ||
104 | |||
105 | error = vfs_readdir(file, (filldir_t)fillonedir, &buf); | ||
106 | if (error < 0) | ||
107 | goto out_putf; | ||
108 | error = buf.count; | ||
109 | |||
110 | out_putf: | ||
111 | fput(file); | ||
112 | out: | ||
113 | return error; | ||
114 | } | ||
115 | |||
116 | struct linux_dirent32 { | ||
117 | u32 d_ino; | ||
118 | u32 d_off; | ||
119 | unsigned short d_reclen; | ||
120 | char d_name[1]; | ||
121 | }; | ||
122 | |||
123 | struct getdents_callback32 { | ||
124 | struct linux_dirent32 __user * current_dir; | ||
125 | struct linux_dirent32 __user * previous; | ||
126 | int count; | ||
127 | int error; | ||
128 | }; | ||
129 | |||
130 | static int filldir(void * __buf, const char * name, int namlen, off_t offset, | ||
131 | ino_t ino, unsigned int d_type) | ||
132 | { | ||
133 | struct linux_dirent32 __user * dirent; | ||
134 | struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf; | ||
135 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); | ||
136 | |||
137 | buf->error = -EINVAL; /* only used if we fail.. */ | ||
138 | if (reclen > buf->count) | ||
139 | return -EINVAL; | ||
140 | dirent = buf->previous; | ||
141 | if (dirent) { | ||
142 | if (__put_user(offset, &dirent->d_off)) | ||
143 | goto efault; | ||
144 | } | ||
145 | dirent = buf->current_dir; | ||
146 | if (__put_user(ino, &dirent->d_ino)) | ||
147 | goto efault; | ||
148 | if (__put_user(reclen, &dirent->d_reclen)) | ||
149 | goto efault; | ||
150 | if (copy_to_user(dirent->d_name, name, namlen)) | ||
151 | goto efault; | ||
152 | if (__put_user(0, dirent->d_name + namlen)) | ||
153 | goto efault; | ||
154 | if (__put_user(d_type, (char __user *) dirent + reclen - 1)) | ||
155 | goto efault; | ||
156 | buf->previous = dirent; | ||
157 | dirent = (void __user *)dirent + reclen; | ||
158 | buf->current_dir = dirent; | ||
159 | buf->count -= reclen; | ||
160 | return 0; | ||
161 | efault: | ||
162 | buf->error = -EFAULT; | ||
163 | return -EFAULT; | ||
164 | } | ||
165 | |||
166 | asmlinkage long sys32_getdents(unsigned int fd, struct linux_dirent32 __user *dirent, | ||
167 | unsigned int count) | ||
168 | { | ||
169 | struct file * file; | ||
170 | struct linux_dirent32 __user * lastdirent; | ||
171 | struct getdents_callback32 buf; | ||
172 | int error; | ||
173 | |||
174 | error = -EFAULT; | ||
175 | if (!access_ok(VERIFY_WRITE, dirent, count)) | ||
176 | goto out; | ||
177 | |||
178 | error = -EBADF; | ||
179 | file = fget(fd); | ||
180 | if (!file) | ||
181 | goto out; | ||
182 | |||
183 | buf.current_dir = dirent; | ||
184 | buf.previous = NULL; | ||
185 | buf.count = count; | ||
186 | buf.error = 0; | ||
187 | |||
188 | error = vfs_readdir(file, (filldir_t)filldir, &buf); | ||
189 | if (error < 0) | ||
190 | goto out_putf; | ||
191 | error = buf.error; | ||
192 | lastdirent = buf.previous; | ||
193 | if (lastdirent) { | ||
194 | if (put_user(file->f_pos, &lastdirent->d_off)) | ||
195 | error = -EFAULT; | ||
196 | else | ||
197 | error = count - buf.count; | ||
198 | } | ||
199 | |||
200 | out_putf: | ||
201 | fput(file); | ||
202 | out: | ||
203 | return error; | ||
204 | } | ||
205 | |||
206 | asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp, | ||
207 | compat_ulong_t __user *outp, compat_ulong_t __user *exp, | ||
208 | compat_uptr_t tvp_x) | ||
209 | { | ||
210 | /* sign extend n */ | ||
211 | return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x)); | ||
212 | } | ||
213 | |||
214 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | ||
215 | { | ||
216 | long err; | ||
217 | |||
218 | if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || | ||
219 | !new_valid_dev(stat->rdev)) | ||
220 | return -EOVERFLOW; | ||
221 | |||
222 | err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT; | ||
223 | err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev); | ||
224 | err |= __put_user(stat->ino, &statbuf->st_ino); | ||
225 | err |= __put_user(stat->mode, &statbuf->st_mode); | ||
226 | err |= __put_user(stat->nlink, &statbuf->st_nlink); | ||
227 | err |= __put_user(stat->uid, &statbuf->st_uid); | ||
228 | err |= __put_user(stat->gid, &statbuf->st_gid); | ||
229 | err |= __put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev); | ||
230 | err |= __put_user(stat->size, &statbuf->st_size); | ||
231 | err |= __put_user(stat->atime.tv_sec, &statbuf->st_atime); | ||
232 | err |= __put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec); | ||
233 | err |= __put_user(stat->mtime.tv_sec, &statbuf->st_mtime); | ||
234 | err |= __put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec); | ||
235 | err |= __put_user(stat->ctime.tv_sec, &statbuf->st_ctime); | ||
236 | err |= __put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec); | ||
237 | err |= __put_user(stat->blksize, &statbuf->st_blksize); | ||
238 | err |= __put_user(stat->blocks, &statbuf->st_blocks); | ||
239 | err |= __put_user(0, &statbuf->__unused4[0]); | ||
240 | err |= __put_user(0, &statbuf->__unused4[1]); | ||
241 | |||
242 | return err; | ||
243 | } | ||
244 | |||
245 | /* Note: it is necessary to treat option as an unsigned int, | ||
246 | * with the corresponding cast to a signed int to insure that the | ||
247 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
248 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
249 | */ | ||
250 | asmlinkage long sys32_sysfs(u32 option, u32 arg1, u32 arg2) | ||
251 | { | ||
252 | return sys_sysfs((int)option, arg1, arg2); | ||
253 | } | ||
254 | |||
255 | /* Handle adjtimex compatibility. */ | ||
256 | struct timex32 { | ||
257 | u32 modes; | ||
258 | s32 offset, freq, maxerror, esterror; | ||
259 | s32 status, constant, precision, tolerance; | ||
260 | struct compat_timeval time; | ||
261 | s32 tick; | ||
262 | s32 ppsfreq, jitter, shift, stabil; | ||
263 | s32 jitcnt, calcnt, errcnt, stbcnt; | ||
264 | s32 :32; s32 :32; s32 :32; s32 :32; | ||
265 | s32 :32; s32 :32; s32 :32; s32 :32; | ||
266 | s32 :32; s32 :32; s32 :32; s32 :32; | ||
267 | }; | ||
268 | |||
269 | extern int do_adjtimex(struct timex *); | ||
270 | extern void ppc_adjtimex(void); | ||
271 | |||
272 | asmlinkage long sys32_adjtimex(struct timex32 __user *utp) | ||
273 | { | ||
274 | struct timex txc; | ||
275 | int ret; | ||
276 | |||
277 | memset(&txc, 0, sizeof(struct timex)); | ||
278 | |||
279 | if(get_user(txc.modes, &utp->modes) || | ||
280 | __get_user(txc.offset, &utp->offset) || | ||
281 | __get_user(txc.freq, &utp->freq) || | ||
282 | __get_user(txc.maxerror, &utp->maxerror) || | ||
283 | __get_user(txc.esterror, &utp->esterror) || | ||
284 | __get_user(txc.status, &utp->status) || | ||
285 | __get_user(txc.constant, &utp->constant) || | ||
286 | __get_user(txc.precision, &utp->precision) || | ||
287 | __get_user(txc.tolerance, &utp->tolerance) || | ||
288 | __get_user(txc.time.tv_sec, &utp->time.tv_sec) || | ||
289 | __get_user(txc.time.tv_usec, &utp->time.tv_usec) || | ||
290 | __get_user(txc.tick, &utp->tick) || | ||
291 | __get_user(txc.ppsfreq, &utp->ppsfreq) || | ||
292 | __get_user(txc.jitter, &utp->jitter) || | ||
293 | __get_user(txc.shift, &utp->shift) || | ||
294 | __get_user(txc.stabil, &utp->stabil) || | ||
295 | __get_user(txc.jitcnt, &utp->jitcnt) || | ||
296 | __get_user(txc.calcnt, &utp->calcnt) || | ||
297 | __get_user(txc.errcnt, &utp->errcnt) || | ||
298 | __get_user(txc.stbcnt, &utp->stbcnt)) | ||
299 | return -EFAULT; | ||
300 | |||
301 | ret = do_adjtimex(&txc); | ||
302 | |||
303 | /* adjust the conversion of TB to time of day to track adjtimex */ | ||
304 | ppc_adjtimex(); | ||
305 | |||
306 | if(put_user(txc.modes, &utp->modes) || | ||
307 | __put_user(txc.offset, &utp->offset) || | ||
308 | __put_user(txc.freq, &utp->freq) || | ||
309 | __put_user(txc.maxerror, &utp->maxerror) || | ||
310 | __put_user(txc.esterror, &utp->esterror) || | ||
311 | __put_user(txc.status, &utp->status) || | ||
312 | __put_user(txc.constant, &utp->constant) || | ||
313 | __put_user(txc.precision, &utp->precision) || | ||
314 | __put_user(txc.tolerance, &utp->tolerance) || | ||
315 | __put_user(txc.time.tv_sec, &utp->time.tv_sec) || | ||
316 | __put_user(txc.time.tv_usec, &utp->time.tv_usec) || | ||
317 | __put_user(txc.tick, &utp->tick) || | ||
318 | __put_user(txc.ppsfreq, &utp->ppsfreq) || | ||
319 | __put_user(txc.jitter, &utp->jitter) || | ||
320 | __put_user(txc.shift, &utp->shift) || | ||
321 | __put_user(txc.stabil, &utp->stabil) || | ||
322 | __put_user(txc.jitcnt, &utp->jitcnt) || | ||
323 | __put_user(txc.calcnt, &utp->calcnt) || | ||
324 | __put_user(txc.errcnt, &utp->errcnt) || | ||
325 | __put_user(txc.stbcnt, &utp->stbcnt)) | ||
326 | ret = -EFAULT; | ||
327 | |||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | asmlinkage long sys32_pause(void) | ||
332 | { | ||
333 | current->state = TASK_INTERRUPTIBLE; | ||
334 | schedule(); | ||
335 | |||
336 | return -ERESTARTNOHAND; | ||
337 | } | ||
338 | |||
339 | static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) | ||
340 | { | ||
341 | long usec; | ||
342 | |||
343 | if (!access_ok(VERIFY_READ, i, sizeof(*i))) | ||
344 | return -EFAULT; | ||
345 | if (__get_user(o->tv_sec, &i->tv_sec)) | ||
346 | return -EFAULT; | ||
347 | if (__get_user(usec, &i->tv_usec)) | ||
348 | return -EFAULT; | ||
349 | o->tv_nsec = usec * 1000; | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) | ||
354 | { | ||
355 | return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || | ||
356 | (__put_user(i->tv_sec, &o->tv_sec) | | ||
357 | __put_user(i->tv_usec, &o->tv_usec))); | ||
358 | } | ||
359 | |||
360 | struct sysinfo32 { | ||
361 | s32 uptime; | ||
362 | u32 loads[3]; | ||
363 | u32 totalram; | ||
364 | u32 freeram; | ||
365 | u32 sharedram; | ||
366 | u32 bufferram; | ||
367 | u32 totalswap; | ||
368 | u32 freeswap; | ||
369 | unsigned short procs; | ||
370 | unsigned short pad; | ||
371 | u32 totalhigh; | ||
372 | u32 freehigh; | ||
373 | u32 mem_unit; | ||
374 | char _f[20-2*sizeof(int)-sizeof(int)]; | ||
375 | }; | ||
376 | |||
377 | asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info) | ||
378 | { | ||
379 | struct sysinfo s; | ||
380 | int ret, err; | ||
381 | int bitcount=0; | ||
382 | mm_segment_t old_fs = get_fs (); | ||
383 | |||
384 | /* The __user cast is valid due to set_fs() */ | ||
385 | set_fs (KERNEL_DS); | ||
386 | ret = sys_sysinfo((struct sysinfo __user *)&s); | ||
387 | set_fs (old_fs); | ||
388 | |||
389 | /* Check to see if any memory value is too large for 32-bit and | ||
390 | * scale down if needed. | ||
391 | */ | ||
392 | if ((s.totalram >> 32) || (s.totalswap >> 32)) { | ||
393 | while (s.mem_unit < PAGE_SIZE) { | ||
394 | s.mem_unit <<= 1; | ||
395 | bitcount++; | ||
396 | } | ||
397 | s.totalram >>=bitcount; | ||
398 | s.freeram >>= bitcount; | ||
399 | s.sharedram >>= bitcount; | ||
400 | s.bufferram >>= bitcount; | ||
401 | s.totalswap >>= bitcount; | ||
402 | s.freeswap >>= bitcount; | ||
403 | s.totalhigh >>= bitcount; | ||
404 | s.freehigh >>= bitcount; | ||
405 | } | ||
406 | |||
407 | err = put_user (s.uptime, &info->uptime); | ||
408 | err |= __put_user (s.loads[0], &info->loads[0]); | ||
409 | err |= __put_user (s.loads[1], &info->loads[1]); | ||
410 | err |= __put_user (s.loads[2], &info->loads[2]); | ||
411 | err |= __put_user (s.totalram, &info->totalram); | ||
412 | err |= __put_user (s.freeram, &info->freeram); | ||
413 | err |= __put_user (s.sharedram, &info->sharedram); | ||
414 | err |= __put_user (s.bufferram, &info->bufferram); | ||
415 | err |= __put_user (s.totalswap, &info->totalswap); | ||
416 | err |= __put_user (s.freeswap, &info->freeswap); | ||
417 | err |= __put_user (s.procs, &info->procs); | ||
418 | err |= __put_user (s.totalhigh, &info->totalhigh); | ||
419 | err |= __put_user (s.freehigh, &info->freehigh); | ||
420 | err |= __put_user (s.mem_unit, &info->mem_unit); | ||
421 | if (err) | ||
422 | return -EFAULT; | ||
423 | |||
424 | return ret; | ||
425 | } | ||
426 | |||
427 | |||
428 | |||
429 | |||
430 | /* Translations due to time_t size differences. Which affects all | ||
431 | sorts of things, like timeval and itimerval. */ | ||
432 | extern struct timezone sys_tz; | ||
433 | |||
434 | asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) | ||
435 | { | ||
436 | if (tv) { | ||
437 | struct timeval ktv; | ||
438 | do_gettimeofday(&ktv); | ||
439 | if (put_tv32(tv, &ktv)) | ||
440 | return -EFAULT; | ||
441 | } | ||
442 | if (tz) { | ||
443 | if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) | ||
444 | return -EFAULT; | ||
445 | } | ||
446 | |||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | |||
451 | |||
452 | asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) | ||
453 | { | ||
454 | struct timespec kts; | ||
455 | struct timezone ktz; | ||
456 | |||
457 | if (tv) { | ||
458 | if (get_ts32(&kts, tv)) | ||
459 | return -EFAULT; | ||
460 | } | ||
461 | if (tz) { | ||
462 | if (copy_from_user(&ktz, tz, sizeof(ktz))) | ||
463 | return -EFAULT; | ||
464 | } | ||
465 | |||
466 | return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); | ||
467 | } | ||
468 | |||
469 | #ifdef CONFIG_SYSVIPC | ||
470 | long sys32_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, | ||
471 | u32 fifth) | ||
472 | { | ||
473 | int version; | ||
474 | |||
475 | version = call >> 16; /* hack for backward compatibility */ | ||
476 | call &= 0xffff; | ||
477 | |||
478 | switch (call) { | ||
479 | |||
480 | case SEMTIMEDOP: | ||
481 | if (fifth) | ||
482 | /* sign extend semid */ | ||
483 | return compat_sys_semtimedop((int)first, | ||
484 | compat_ptr(ptr), second, | ||
485 | compat_ptr(fifth)); | ||
486 | /* else fall through for normal semop() */ | ||
487 | case SEMOP: | ||
488 | /* struct sembuf is the same on 32 and 64bit :)) */ | ||
489 | /* sign extend semid */ | ||
490 | return sys_semtimedop((int)first, compat_ptr(ptr), second, | ||
491 | NULL); | ||
492 | case SEMGET: | ||
493 | /* sign extend key, nsems */ | ||
494 | return sys_semget((int)first, (int)second, third); | ||
495 | case SEMCTL: | ||
496 | /* sign extend semid, semnum */ | ||
497 | return compat_sys_semctl((int)first, (int)second, third, | ||
498 | compat_ptr(ptr)); | ||
499 | |||
500 | case MSGSND: | ||
501 | /* sign extend msqid */ | ||
502 | return compat_sys_msgsnd((int)first, (int)second, third, | ||
503 | compat_ptr(ptr)); | ||
504 | case MSGRCV: | ||
505 | /* sign extend msqid, msgtyp */ | ||
506 | return compat_sys_msgrcv((int)first, second, (int)fifth, | ||
507 | third, version, compat_ptr(ptr)); | ||
508 | case MSGGET: | ||
509 | /* sign extend key */ | ||
510 | return sys_msgget((int)first, second); | ||
511 | case MSGCTL: | ||
512 | /* sign extend msqid */ | ||
513 | return compat_sys_msgctl((int)first, second, compat_ptr(ptr)); | ||
514 | |||
515 | case SHMAT: | ||
516 | /* sign extend shmid */ | ||
517 | return compat_sys_shmat((int)first, second, third, version, | ||
518 | compat_ptr(ptr)); | ||
519 | case SHMDT: | ||
520 | return sys_shmdt(compat_ptr(ptr)); | ||
521 | case SHMGET: | ||
522 | /* sign extend key_t */ | ||
523 | return sys_shmget((int)first, second, third); | ||
524 | case SHMCTL: | ||
525 | /* sign extend shmid */ | ||
526 | return compat_sys_shmctl((int)first, second, compat_ptr(ptr)); | ||
527 | |||
528 | default: | ||
529 | return -ENOSYS; | ||
530 | } | ||
531 | |||
532 | return -ENOSYS; | ||
533 | } | ||
534 | #endif | ||
535 | |||
536 | /* Note: it is necessary to treat out_fd and in_fd as unsigned ints, | ||
537 | * with the corresponding cast to a signed int to insure that the | ||
538 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
539 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
540 | */ | ||
541 | asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count) | ||
542 | { | ||
543 | mm_segment_t old_fs = get_fs(); | ||
544 | int ret; | ||
545 | off_t of; | ||
546 | off_t __user *up; | ||
547 | |||
548 | if (offset && get_user(of, offset)) | ||
549 | return -EFAULT; | ||
550 | |||
551 | /* The __user pointer cast is valid because of the set_fs() */ | ||
552 | set_fs(KERNEL_DS); | ||
553 | up = offset ? (off_t __user *) &of : NULL; | ||
554 | ret = sys_sendfile((int)out_fd, (int)in_fd, up, count); | ||
555 | set_fs(old_fs); | ||
556 | |||
557 | if (offset && put_user(of, offset)) | ||
558 | return -EFAULT; | ||
559 | |||
560 | return ret; | ||
561 | } | ||
562 | |||
563 | asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count) | ||
564 | { | ||
565 | mm_segment_t old_fs = get_fs(); | ||
566 | int ret; | ||
567 | loff_t lof; | ||
568 | loff_t __user *up; | ||
569 | |||
570 | if (offset && get_user(lof, offset)) | ||
571 | return -EFAULT; | ||
572 | |||
573 | /* The __user pointer cast is valid because of the set_fs() */ | ||
574 | set_fs(KERNEL_DS); | ||
575 | up = offset ? (loff_t __user *) &lof : NULL; | ||
576 | ret = sys_sendfile64(out_fd, in_fd, up, count); | ||
577 | set_fs(old_fs); | ||
578 | |||
579 | if (offset && put_user(lof, offset)) | ||
580 | return -EFAULT; | ||
581 | |||
582 | return ret; | ||
583 | } | ||
584 | |||
585 | long sys32_execve(unsigned long a0, unsigned long a1, unsigned long a2, | ||
586 | unsigned long a3, unsigned long a4, unsigned long a5, | ||
587 | struct pt_regs *regs) | ||
588 | { | ||
589 | int error; | ||
590 | char * filename; | ||
591 | |||
592 | filename = getname((char __user *) a0); | ||
593 | error = PTR_ERR(filename); | ||
594 | if (IS_ERR(filename)) | ||
595 | goto out; | ||
596 | flush_fp_to_thread(current); | ||
597 | flush_altivec_to_thread(current); | ||
598 | |||
599 | error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs); | ||
600 | |||
601 | if (error == 0) { | ||
602 | task_lock(current); | ||
603 | current->ptrace &= ~PT_DTRACE; | ||
604 | task_unlock(current); | ||
605 | } | ||
606 | putname(filename); | ||
607 | |||
608 | out: | ||
609 | return error; | ||
610 | } | ||
611 | |||
612 | /* Note: it is necessary to treat option as an unsigned int, | ||
613 | * with the corresponding cast to a signed int to insure that the | ||
614 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
615 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
616 | */ | ||
617 | asmlinkage long sys32_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5) | ||
618 | { | ||
619 | return sys_prctl((int)option, | ||
620 | (unsigned long) arg2, | ||
621 | (unsigned long) arg3, | ||
622 | (unsigned long) arg4, | ||
623 | (unsigned long) arg5); | ||
624 | } | ||
625 | |||
626 | /* Note: it is necessary to treat pid as an unsigned int, | ||
627 | * with the corresponding cast to a signed int to insure that the | ||
628 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
629 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
630 | */ | ||
631 | asmlinkage long sys32_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval) | ||
632 | { | ||
633 | struct timespec t; | ||
634 | int ret; | ||
635 | mm_segment_t old_fs = get_fs (); | ||
636 | |||
637 | /* The __user pointer cast is valid because of the set_fs() */ | ||
638 | set_fs (KERNEL_DS); | ||
639 | ret = sys_sched_rr_get_interval((int)pid, (struct timespec __user *) &t); | ||
640 | set_fs (old_fs); | ||
641 | if (put_compat_timespec(&t, interval)) | ||
642 | return -EFAULT; | ||
643 | return ret; | ||
644 | } | ||
645 | |||
646 | asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf) | ||
647 | { | ||
648 | return sys_pciconfig_read((unsigned long) bus, | ||
649 | (unsigned long) dfn, | ||
650 | (unsigned long) off, | ||
651 | (unsigned long) len, | ||
652 | compat_ptr(ubuf)); | ||
653 | } | ||
654 | |||
655 | asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf) | ||
656 | { | ||
657 | return sys_pciconfig_write((unsigned long) bus, | ||
658 | (unsigned long) dfn, | ||
659 | (unsigned long) off, | ||
660 | (unsigned long) len, | ||
661 | compat_ptr(ubuf)); | ||
662 | } | ||
663 | |||
664 | asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) | ||
665 | { | ||
666 | return sys_pciconfig_iobase(which, in_bus, in_devfn); | ||
667 | } | ||
668 | |||
669 | |||
670 | /* Note: it is necessary to treat mode as an unsigned int, | ||
671 | * with the corresponding cast to a signed int to insure that the | ||
672 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
673 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
674 | */ | ||
675 | asmlinkage long sys32_access(const char __user * filename, u32 mode) | ||
676 | { | ||
677 | return sys_access(filename, (int)mode); | ||
678 | } | ||
679 | |||
680 | |||
681 | /* Note: it is necessary to treat mode as an unsigned int, | ||
682 | * with the corresponding cast to a signed int to insure that the | ||
683 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
684 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
685 | */ | ||
686 | asmlinkage long sys32_creat(const char __user * pathname, u32 mode) | ||
687 | { | ||
688 | return sys_creat(pathname, (int)mode); | ||
689 | } | ||
690 | |||
691 | |||
692 | /* Note: it is necessary to treat pid and options as unsigned ints, | ||
693 | * with the corresponding cast to a signed int to insure that the | ||
694 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
695 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
696 | */ | ||
697 | asmlinkage long sys32_waitpid(u32 pid, unsigned int __user * stat_addr, u32 options) | ||
698 | { | ||
699 | return sys_waitpid((int)pid, stat_addr, (int)options); | ||
700 | } | ||
701 | |||
702 | |||
703 | /* Note: it is necessary to treat gidsetsize as an unsigned int, | ||
704 | * with the corresponding cast to a signed int to insure that the | ||
705 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
706 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
707 | */ | ||
708 | asmlinkage long sys32_getgroups(u32 gidsetsize, gid_t __user *grouplist) | ||
709 | { | ||
710 | return sys_getgroups((int)gidsetsize, grouplist); | ||
711 | } | ||
712 | |||
713 | |||
714 | /* Note: it is necessary to treat pid as an unsigned int, | ||
715 | * with the corresponding cast to a signed int to insure that the | ||
716 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
717 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
718 | */ | ||
719 | asmlinkage long sys32_getpgid(u32 pid) | ||
720 | { | ||
721 | return sys_getpgid((int)pid); | ||
722 | } | ||
723 | |||
724 | |||
725 | |||
726 | /* Note: it is necessary to treat pid as an unsigned int, | ||
727 | * with the corresponding cast to a signed int to insure that the | ||
728 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
729 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
730 | */ | ||
731 | asmlinkage long sys32_getsid(u32 pid) | ||
732 | { | ||
733 | return sys_getsid((int)pid); | ||
734 | } | ||
735 | |||
736 | |||
737 | /* Note: it is necessary to treat pid and sig as unsigned ints, | ||
738 | * with the corresponding cast to a signed int to insure that the | ||
739 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
740 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
741 | */ | ||
742 | asmlinkage long sys32_kill(u32 pid, u32 sig) | ||
743 | { | ||
744 | return sys_kill((int)pid, (int)sig); | ||
745 | } | ||
746 | |||
747 | |||
748 | /* Note: it is necessary to treat mode as an unsigned int, | ||
749 | * with the corresponding cast to a signed int to insure that the | ||
750 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
751 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
752 | */ | ||
753 | asmlinkage long sys32_mkdir(const char __user * pathname, u32 mode) | ||
754 | { | ||
755 | return sys_mkdir(pathname, (int)mode); | ||
756 | } | ||
757 | |||
758 | long sys32_nice(u32 increment) | ||
759 | { | ||
760 | /* sign extend increment */ | ||
761 | return sys_nice((int)increment); | ||
762 | } | ||
763 | |||
764 | off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin) | ||
765 | { | ||
766 | /* sign extend n */ | ||
767 | return sys_lseek(fd, (int)offset, origin); | ||
768 | } | ||
769 | |||
770 | /* Note: it is necessary to treat bufsiz as an unsigned int, | ||
771 | * with the corresponding cast to a signed int to insure that the | ||
772 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
773 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
774 | */ | ||
775 | asmlinkage long sys32_readlink(const char __user * path, char __user * buf, u32 bufsiz) | ||
776 | { | ||
777 | return sys_readlink(path, buf, (int)bufsiz); | ||
778 | } | ||
779 | |||
780 | /* Note: it is necessary to treat option as an unsigned int, | ||
781 | * with the corresponding cast to a signed int to insure that the | ||
782 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
783 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
784 | */ | ||
785 | asmlinkage long sys32_sched_get_priority_max(u32 policy) | ||
786 | { | ||
787 | return sys_sched_get_priority_max((int)policy); | ||
788 | } | ||
789 | |||
790 | |||
791 | /* Note: it is necessary to treat policy as an unsigned int, | ||
792 | * with the corresponding cast to a signed int to insure that the | ||
793 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
794 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
795 | */ | ||
796 | asmlinkage long sys32_sched_get_priority_min(u32 policy) | ||
797 | { | ||
798 | return sys_sched_get_priority_min((int)policy); | ||
799 | } | ||
800 | |||
801 | |||
802 | /* Note: it is necessary to treat pid as an unsigned int, | ||
803 | * with the corresponding cast to a signed int to insure that the | ||
804 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
805 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
806 | */ | ||
807 | asmlinkage long sys32_sched_getparam(u32 pid, struct sched_param __user *param) | ||
808 | { | ||
809 | return sys_sched_getparam((int)pid, param); | ||
810 | } | ||
811 | |||
812 | |||
813 | /* Note: it is necessary to treat pid as an unsigned int, | ||
814 | * with the corresponding cast to a signed int to insure that the | ||
815 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
816 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
817 | */ | ||
818 | asmlinkage long sys32_sched_getscheduler(u32 pid) | ||
819 | { | ||
820 | return sys_sched_getscheduler((int)pid); | ||
821 | } | ||
822 | |||
823 | |||
824 | /* Note: it is necessary to treat pid as an unsigned int, | ||
825 | * with the corresponding cast to a signed int to insure that the | ||
826 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
827 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
828 | */ | ||
829 | asmlinkage long sys32_sched_setparam(u32 pid, struct sched_param __user *param) | ||
830 | { | ||
831 | return sys_sched_setparam((int)pid, param); | ||
832 | } | ||
833 | |||
834 | |||
835 | /* Note: it is necessary to treat pid and policy as unsigned ints, | ||
836 | * with the corresponding cast to a signed int to insure that the | ||
837 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
838 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
839 | */ | ||
840 | asmlinkage long sys32_sched_setscheduler(u32 pid, u32 policy, struct sched_param __user *param) | ||
841 | { | ||
842 | return sys_sched_setscheduler((int)pid, (int)policy, param); | ||
843 | } | ||
844 | |||
845 | |||
846 | /* Note: it is necessary to treat len as an unsigned int, | ||
847 | * with the corresponding cast to a signed int to insure that the | ||
848 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
849 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
850 | */ | ||
851 | asmlinkage long sys32_setdomainname(char __user *name, u32 len) | ||
852 | { | ||
853 | return sys_setdomainname(name, (int)len); | ||
854 | } | ||
855 | |||
856 | |||
857 | /* Note: it is necessary to treat gidsetsize as an unsigned int, | ||
858 | * with the corresponding cast to a signed int to insure that the | ||
859 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
860 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
861 | */ | ||
862 | asmlinkage long sys32_setgroups(u32 gidsetsize, gid_t __user *grouplist) | ||
863 | { | ||
864 | return sys_setgroups((int)gidsetsize, grouplist); | ||
865 | } | ||
866 | |||
867 | |||
868 | asmlinkage long sys32_sethostname(char __user *name, u32 len) | ||
869 | { | ||
870 | /* sign extend len */ | ||
871 | return sys_sethostname(name, (int)len); | ||
872 | } | ||
873 | |||
874 | |||
875 | /* Note: it is necessary to treat pid and pgid as unsigned ints, | ||
876 | * with the corresponding cast to a signed int to insure that the | ||
877 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
878 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
879 | */ | ||
880 | asmlinkage long sys32_setpgid(u32 pid, u32 pgid) | ||
881 | { | ||
882 | return sys_setpgid((int)pid, (int)pgid); | ||
883 | } | ||
884 | |||
885 | long sys32_getpriority(u32 which, u32 who) | ||
886 | { | ||
887 | /* sign extend which and who */ | ||
888 | return sys_getpriority((int)which, (int)who); | ||
889 | } | ||
890 | |||
891 | long sys32_setpriority(u32 which, u32 who, u32 niceval) | ||
892 | { | ||
893 | /* sign extend which, who and niceval */ | ||
894 | return sys_setpriority((int)which, (int)who, (int)niceval); | ||
895 | } | ||
896 | |||
897 | long sys32_ioprio_get(u32 which, u32 who) | ||
898 | { | ||
899 | /* sign extend which and who */ | ||
900 | return sys_ioprio_get((int)which, (int)who); | ||
901 | } | ||
902 | |||
903 | long sys32_ioprio_set(u32 which, u32 who, u32 ioprio) | ||
904 | { | ||
905 | /* sign extend which, who and ioprio */ | ||
906 | return sys_ioprio_set((int)which, (int)who, (int)ioprio); | ||
907 | } | ||
908 | |||
909 | /* Note: it is necessary to treat newmask as an unsigned int, | ||
910 | * with the corresponding cast to a signed int to insure that the | ||
911 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
912 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
913 | */ | ||
914 | asmlinkage long sys32_ssetmask(u32 newmask) | ||
915 | { | ||
916 | return sys_ssetmask((int) newmask); | ||
917 | } | ||
918 | |||
919 | asmlinkage long sys32_syslog(u32 type, char __user * buf, u32 len) | ||
920 | { | ||
921 | /* sign extend len */ | ||
922 | return sys_syslog(type, buf, (int)len); | ||
923 | } | ||
924 | |||
925 | |||
926 | /* Note: it is necessary to treat mask as an unsigned int, | ||
927 | * with the corresponding cast to a signed int to insure that the | ||
928 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | ||
929 | * and the register representation of a signed int (msr in 64-bit mode) is performed. | ||
930 | */ | ||
931 | asmlinkage long sys32_umask(u32 mask) | ||
932 | { | ||
933 | return sys_umask((int)mask); | ||
934 | } | ||
935 | |||
936 | #ifdef CONFIG_SYSCTL | ||
937 | struct __sysctl_args32 { | ||
938 | u32 name; | ||
939 | int nlen; | ||
940 | u32 oldval; | ||
941 | u32 oldlenp; | ||
942 | u32 newval; | ||
943 | u32 newlen; | ||
944 | u32 __unused[4]; | ||
945 | }; | ||
946 | |||
947 | asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) | ||
948 | { | ||
949 | struct __sysctl_args32 tmp; | ||
950 | int error; | ||
951 | size_t oldlen; | ||
952 | size_t __user *oldlenp = NULL; | ||
953 | unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7; | ||
954 | |||
955 | if (copy_from_user(&tmp, args, sizeof(tmp))) | ||
956 | return -EFAULT; | ||
957 | |||
958 | if (tmp.oldval && tmp.oldlenp) { | ||
959 | /* Duh, this is ugly and might not work if sysctl_args | ||
960 | is in read-only memory, but do_sysctl does indirectly | ||
961 | a lot of uaccess in both directions and we'd have to | ||
962 | basically copy the whole sysctl.c here, and | ||
963 | glibc's __sysctl uses rw memory for the structure | ||
964 | anyway. */ | ||
965 | oldlenp = (size_t __user *)addr; | ||
966 | if (get_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)) || | ||
967 | put_user(oldlen, oldlenp)) | ||
968 | return -EFAULT; | ||
969 | } | ||
970 | |||
971 | lock_kernel(); | ||
972 | error = do_sysctl(compat_ptr(tmp.name), tmp.nlen, | ||
973 | compat_ptr(tmp.oldval), oldlenp, | ||
974 | compat_ptr(tmp.newval), tmp.newlen); | ||
975 | unlock_kernel(); | ||
976 | if (oldlenp) { | ||
977 | if (!error) { | ||
978 | if (get_user(oldlen, oldlenp) || | ||
979 | put_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp))) | ||
980 | error = -EFAULT; | ||
981 | } | ||
982 | copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); | ||
983 | } | ||
984 | return error; | ||
985 | } | ||
986 | #endif | ||
987 | |||
988 | unsigned long sys32_mmap2(unsigned long addr, size_t len, | ||
989 | unsigned long prot, unsigned long flags, | ||
990 | unsigned long fd, unsigned long pgoff) | ||
991 | { | ||
992 | /* This should remain 12 even if PAGE_SIZE changes */ | ||
993 | return sys_mmap(addr, len, prot, flags, fd, pgoff << 12); | ||
994 | } | ||
995 | |||
996 | int get_compat_timeval(struct timeval *tv, struct compat_timeval __user *ctv) | ||
997 | { | ||
998 | return (!access_ok(VERIFY_READ, ctv, sizeof(*ctv)) || | ||
999 | __get_user(tv->tv_sec, &ctv->tv_sec) || | ||
1000 | __get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0; | ||
1001 | } | ||
1002 | |||
1003 | asmlinkage long sys32_utimes(char __user *filename, struct compat_timeval __user *tvs) | ||
1004 | { | ||
1005 | struct timeval ktvs[2], *ptr; | ||
1006 | |||
1007 | ptr = NULL; | ||
1008 | if (tvs) { | ||
1009 | if (get_compat_timeval(&ktvs[0], &tvs[0]) || | ||
1010 | get_compat_timeval(&ktvs[1], &tvs[1])) | ||
1011 | return -EFAULT; | ||
1012 | ptr = ktvs; | ||
1013 | } | ||
1014 | |||
1015 | return do_utimes(filename, ptr); | ||
1016 | } | ||
1017 | |||
1018 | long sys32_tgkill(u32 tgid, u32 pid, int sig) | ||
1019 | { | ||
1020 | /* sign extend tgid, pid */ | ||
1021 | return sys_tgkill((int)tgid, (int)pid, sig); | ||
1022 | } | ||
1023 | |||
1024 | /* | ||
1025 | * long long munging: | ||
1026 | * The 32 bit ABI passes long longs in an odd even register pair. | ||
1027 | */ | ||
1028 | |||
1029 | compat_ssize_t sys32_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, | ||
1030 | u32 reg6, u32 poshi, u32 poslo) | ||
1031 | { | ||
1032 | return sys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); | ||
1033 | } | ||
1034 | |||
1035 | compat_ssize_t sys32_pwrite64(unsigned int fd, char __user *ubuf, compat_size_t count, | ||
1036 | u32 reg6, u32 poshi, u32 poslo) | ||
1037 | { | ||
1038 | return sys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo); | ||
1039 | } | ||
1040 | |||
1041 | compat_ssize_t sys32_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count) | ||
1042 | { | ||
1043 | return sys_readahead(fd, ((loff_t)offhi << 32) | offlo, count); | ||
1044 | } | ||
1045 | |||
1046 | asmlinkage int sys32_truncate64(const char __user * path, u32 reg4, | ||
1047 | unsigned long high, unsigned long low) | ||
1048 | { | ||
1049 | return sys_truncate(path, (high << 32) | low); | ||
1050 | } | ||
1051 | |||
1052 | asmlinkage int sys32_ftruncate64(unsigned int fd, u32 reg4, unsigned long high, | ||
1053 | unsigned long low) | ||
1054 | { | ||
1055 | return sys_ftruncate(fd, (high << 32) | low); | ||
1056 | } | ||
1057 | |||
1058 | long ppc32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char __user *buf, | ||
1059 | size_t len) | ||
1060 | { | ||
1061 | return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low, | ||
1062 | buf, len); | ||
1063 | } | ||
1064 | |||
1065 | long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low, | ||
1066 | size_t len, int advice) | ||
1067 | { | ||
1068 | return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low, len, | ||
1069 | advice); | ||
1070 | } | ||
1071 | |||
1072 | long ppc32_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low, | ||
1073 | u32 len_high, u32 len_low) | ||
1074 | { | ||
1075 | return sys_fadvise64(fd, (u64)offset_high << 32 | offset_low, | ||
1076 | (u64)len_high << 32 | len_low, advice); | ||
1077 | } | ||
1078 | |||
1079 | long ppc32_timer_create(clockid_t clock, | ||
1080 | struct compat_sigevent __user *ev32, | ||
1081 | timer_t __user *timer_id) | ||
1082 | { | ||
1083 | sigevent_t event; | ||
1084 | timer_t t; | ||
1085 | long err; | ||
1086 | mm_segment_t savefs; | ||
1087 | |||
1088 | if (ev32 == NULL) | ||
1089 | return sys_timer_create(clock, NULL, timer_id); | ||
1090 | |||
1091 | if (get_compat_sigevent(&event, ev32)) | ||
1092 | return -EFAULT; | ||
1093 | |||
1094 | if (!access_ok(VERIFY_WRITE, timer_id, sizeof(timer_t))) | ||
1095 | return -EFAULT; | ||
1096 | |||
1097 | savefs = get_fs(); | ||
1098 | set_fs(KERNEL_DS); | ||
1099 | /* The __user pointer casts are valid due to the set_fs() */ | ||
1100 | err = sys_timer_create(clock, | ||
1101 | (sigevent_t __user *) &event, | ||
1102 | (timer_t __user *) &t); | ||
1103 | set_fs(savefs); | ||
1104 | |||
1105 | if (err == 0) | ||
1106 | err = __put_user(t, timer_id); | ||
1107 | |||
1108 | return err; | ||
1109 | } | ||
1110 | |||
1111 | asmlinkage long sys32_add_key(const char __user *_type, | ||
1112 | const char __user *_description, | ||
1113 | const void __user *_payload, | ||
1114 | u32 plen, | ||
1115 | u32 ringid) | ||
1116 | { | ||
1117 | return sys_add_key(_type, _description, _payload, plen, ringid); | ||
1118 | } | ||
1119 | |||
1120 | asmlinkage long sys32_request_key(const char __user *_type, | ||
1121 | const char __user *_description, | ||
1122 | const char __user *_callout_info, | ||
1123 | u32 destringid) | ||
1124 | { | ||
1125 | return sys_request_key(_type, _description, _callout_info, destringid); | ||
1126 | } | ||
1127 | |||
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c new file mode 100644 index 000000000000..3e3a4f67de96 --- /dev/null +++ b/arch/powerpc/kernel/syscalls.c | |||
@@ -0,0 +1,351 @@ | |||
1 | /* | ||
2 | * Implementation of various system calls for Linux/PowerPC | ||
3 | * | ||
4 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | ||
5 | * | ||
6 | * Derived from "arch/i386/kernel/sys_i386.c" | ||
7 | * Adapted from the i386 version by Gary Thomas | ||
8 | * Modified by Cort Dougan (cort@cs.nmt.edu) | ||
9 | * and Paul Mackerras (paulus@cs.anu.edu.au). | ||
10 | * | ||
11 | * This file contains various random system calls that | ||
12 | * have a non-standard calling sequence on the Linux/PPC | ||
13 | * platform. | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License | ||
17 | * as published by the Free Software Foundation; either version | ||
18 | * 2 of the License, or (at your option) any later version. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/errno.h> | ||
23 | #include <linux/sched.h> | ||
24 | #include <linux/syscalls.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/mman.h> | ||
33 | #include <linux/sys.h> | ||
34 | #include <linux/ipc.h> | ||
35 | #include <linux/utsname.h> | ||
36 | #include <linux/file.h> | ||
37 | #include <linux/init.h> | ||
38 | #include <linux/personality.h> | ||
39 | |||
40 | #include <asm/uaccess.h> | ||
41 | #include <asm/ipc.h> | ||
42 | #include <asm/semaphore.h> | ||
43 | #include <asm/time.h> | ||
44 | #include <asm/unistd.h> | ||
45 | |||
46 | extern unsigned long wall_jiffies; | ||
47 | |||
48 | |||
49 | /* | ||
50 | * sys_ipc() is the de-multiplexer for the SysV IPC calls.. | ||
51 | * | ||
52 | * This is really horribly ugly. | ||
53 | */ | ||
54 | int sys_ipc(uint call, int first, unsigned long second, long third, | ||
55 | void __user *ptr, long fifth) | ||
56 | { | ||
57 | int version, ret; | ||
58 | |||
59 | version = call >> 16; /* hack for backward compatibility */ | ||
60 | call &= 0xffff; | ||
61 | |||
62 | ret = -ENOSYS; | ||
63 | switch (call) { | ||
64 | case SEMOP: | ||
65 | ret = sys_semtimedop(first, (struct sembuf __user *)ptr, | ||
66 | (unsigned)second, NULL); | ||
67 | break; | ||
68 | case SEMTIMEDOP: | ||
69 | ret = sys_semtimedop(first, (struct sembuf __user *)ptr, | ||
70 | (unsigned)second, | ||
71 | (const struct timespec __user *) fifth); | ||
72 | break; | ||
73 | case SEMGET: | ||
74 | ret = sys_semget (first, (int)second, third); | ||
75 | break; | ||
76 | case SEMCTL: { | ||
77 | union semun fourth; | ||
78 | |||
79 | ret = -EINVAL; | ||
80 | if (!ptr) | ||
81 | break; | ||
82 | if ((ret = get_user(fourth.__pad, (void __user * __user *)ptr))) | ||
83 | break; | ||
84 | ret = sys_semctl(first, (int)second, third, fourth); | ||
85 | break; | ||
86 | } | ||
87 | case MSGSND: | ||
88 | ret = sys_msgsnd(first, (struct msgbuf __user *)ptr, | ||
89 | (size_t)second, third); | ||
90 | break; | ||
91 | case MSGRCV: | ||
92 | switch (version) { | ||
93 | case 0: { | ||
94 | struct ipc_kludge tmp; | ||
95 | |||
96 | ret = -EINVAL; | ||
97 | if (!ptr) | ||
98 | break; | ||
99 | if ((ret = copy_from_user(&tmp, | ||
100 | (struct ipc_kludge __user *) ptr, | ||
101 | sizeof (tmp)) ? -EFAULT : 0)) | ||
102 | break; | ||
103 | ret = sys_msgrcv(first, tmp.msgp, (size_t) second, | ||
104 | tmp.msgtyp, third); | ||
105 | break; | ||
106 | } | ||
107 | default: | ||
108 | ret = sys_msgrcv (first, (struct msgbuf __user *) ptr, | ||
109 | (size_t)second, fifth, third); | ||
110 | break; | ||
111 | } | ||
112 | break; | ||
113 | case MSGGET: | ||
114 | ret = sys_msgget((key_t)first, (int)second); | ||
115 | break; | ||
116 | case MSGCTL: | ||
117 | ret = sys_msgctl(first, (int)second, | ||
118 | (struct msqid_ds __user *)ptr); | ||
119 | break; | ||
120 | case SHMAT: { | ||
121 | ulong raddr; | ||
122 | ret = do_shmat(first, (char __user *)ptr, (int)second, &raddr); | ||
123 | if (ret) | ||
124 | break; | ||
125 | ret = put_user(raddr, (ulong __user *) third); | ||
126 | break; | ||
127 | } | ||
128 | case SHMDT: | ||
129 | ret = sys_shmdt((char __user *)ptr); | ||
130 | break; | ||
131 | case SHMGET: | ||
132 | ret = sys_shmget(first, (size_t)second, third); | ||
133 | break; | ||
134 | case SHMCTL: | ||
135 | ret = sys_shmctl(first, (int)second, | ||
136 | (struct shmid_ds __user *)ptr); | ||
137 | break; | ||
138 | } | ||
139 | |||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * sys_pipe() is the normal C calling standard for creating | ||
145 | * a pipe. It's not the way unix traditionally does this, though. | ||
146 | */ | ||
147 | int sys_pipe(int __user *fildes) | ||
148 | { | ||
149 | int fd[2]; | ||
150 | int error; | ||
151 | |||
152 | error = do_pipe(fd); | ||
153 | if (!error) { | ||
154 | if (copy_to_user(fildes, fd, 2*sizeof(int))) | ||
155 | error = -EFAULT; | ||
156 | } | ||
157 | return error; | ||
158 | } | ||
159 | |||
160 | static inline unsigned long do_mmap2(unsigned long addr, size_t len, | ||
161 | unsigned long prot, unsigned long flags, | ||
162 | unsigned long fd, unsigned long off, int shift) | ||
163 | { | ||
164 | struct file * file = NULL; | ||
165 | int ret = -EINVAL; | ||
166 | |||
167 | if (shift) { | ||
168 | if (off & ((1 << shift) - 1)) | ||
169 | goto out; | ||
170 | off >>= shift; | ||
171 | } | ||
172 | |||
173 | ret = -EBADF; | ||
174 | if (!(flags & MAP_ANONYMOUS)) { | ||
175 | if (!(file = fget(fd))) | ||
176 | goto out; | ||
177 | } | ||
178 | |||
179 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
180 | |||
181 | down_write(¤t->mm->mmap_sem); | ||
182 | ret = do_mmap_pgoff(file, addr, len, prot, flags, off); | ||
183 | up_write(¤t->mm->mmap_sem); | ||
184 | if (file) | ||
185 | fput(file); | ||
186 | out: | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | unsigned 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 | |||
197 | unsigned 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 | */ | ||
211 | int | ||
212 | ppc_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 | ||
230 | long ppc64_personality(unsigned long personality) | ||
231 | { | ||
232 | long ret; | ||
233 | |||
234 | if (personality(current->personality) == PER_LINUX32 | ||
235 | && personality == PER_LINUX) | ||
236 | personality = PER_LINUX32; | ||
237 | ret = sys_personality(personality); | ||
238 | if (ret == PER_LINUX32) | ||
239 | ret = PER_LINUX; | ||
240 | return ret; | ||
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 | ||
249 | |||
250 | static 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 | |||
260 | long ppc_newuname(struct new_utsname __user * name) | ||
261 | { | ||
262 | int err = 0; | ||
263 | |||
264 | down_read(&uts_sem); | ||
265 | if (copy_to_user(name, &system_utsname, sizeof(*name))) | ||
266 | err = -EFAULT; | ||
267 | up_read(&uts_sem); | ||
268 | if (!err) | ||
269 | err = override_machine(name->machine); | ||
270 | return err; | ||
271 | } | ||
272 | |||
273 | int 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 | |||
286 | int 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 | ||
315 | time_t sys64_time(time_t __user * tloc) | ||
316 | { | ||
317 | time_t secs; | ||
318 | time_t usecs; | ||
319 | |||
320 | long tb_delta = tb_ticks_since(tb_last_stamp); | ||
321 | tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy; | ||
322 | |||
323 | secs = xtime.tv_sec; | ||
324 | usecs = (xtime.tv_nsec/1000) + tb_delta / tb_ticks_per_usec; | ||
325 | while (usecs >= USEC_PER_SEC) { | ||
326 | ++secs; | ||
327 | usecs -= USEC_PER_SEC; | ||
328 | } | ||
329 | |||
330 | if (tloc) { | ||
331 | if (put_user(secs,tloc)) | ||
332 | secs = -EFAULT; | ||
333 | } | ||
334 | |||
335 | return secs; | ||
336 | } | ||
337 | #endif | ||
338 | |||
339 | void do_show_syscall(unsigned long r3, unsigned long r4, unsigned long r5, | ||
340 | unsigned long r6, unsigned long r7, unsigned long r8, | ||
341 | struct pt_regs *regs) | ||
342 | { | ||
343 | printk("syscall %ld(%lx, %lx, %lx, %lx, %lx, %lx) regs=%p current=%p" | ||
344 | " cpu=%d\n", regs->gpr[0], r3, r4, r5, r6, r7, r8, regs, | ||
345 | current, smp_processor_id()); | ||
346 | } | ||
347 | |||
348 | void do_show_syscall_exit(unsigned long r3) | ||
349 | { | ||
350 | printk(" -> %lx, current=%p cpu=%d\n", r3, current, smp_processor_id()); | ||
351 | } | ||
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) | |||
102 | SYSCALL(ni_syscall) | 102 | SYSCALL(ni_syscall) |
103 | SYSCALL32(setpgid) | 103 | SYSCALL32(setpgid) |
104 | SYSCALL(ni_syscall) | 104 | SYSCALL(ni_syscall) |
105 | SYS32ONLY(olduname) | 105 | SYSX(sys_ni_syscall,sys_olduname, sys_olduname) |
106 | SYSCALL32(umask) | 106 | SYSCALL32(umask) |
107 | SYSCALL(chroot) | 107 | SYSCALL(chroot) |
108 | SYSCALL(ustat) | 108 | SYSCALL(ustat) |
@@ -152,7 +152,7 @@ COMPAT_SYS(getitimer) | |||
152 | COMPAT_SYS(newstat) | 152 | COMPAT_SYS(newstat) |
153 | COMPAT_SYS(newlstat) | 153 | COMPAT_SYS(newlstat) |
154 | COMPAT_SYS(newfstat) | 154 | COMPAT_SYS(newfstat) |
155 | SYSX(sys_ni_syscall,sys32_uname,sys_uname) | 155 | SYSX(sys_ni_syscall,sys_uname,sys_uname) |
156 | SYSCALL(ni_syscall) | 156 | SYSCALL(ni_syscall) |
157 | SYSCALL(vhangup) | 157 | SYSCALL(vhangup) |
158 | SYSCALL(ni_syscall) | 158 | SYSCALL(ni_syscall) |
@@ -165,7 +165,7 @@ SYSCALL(fsync) | |||
165 | SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn) | 165 | SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn) |
166 | PPC_SYS(clone) | 166 | PPC_SYS(clone) |
167 | SYSCALL32(setdomainname) | 167 | SYSCALL32(setdomainname) |
168 | SYSX(ppc64_newuname,ppc64_newuname,sys_newuname) | 168 | PPC_SYS(newuname) |
169 | SYSCALL(ni_syscall) | 169 | SYSCALL(ni_syscall) |
170 | SYSCALL32(adjtimex) | 170 | SYSCALL32(adjtimex) |
171 | SYSCALL(mprotect) | 171 | SYSCALL(mprotect) |