#include <linux/file.h>
#include <linux/smp_lock.h>
#include <linux/highuid.h>
-#include <linux/dirent.h>
#include <linux/resource.h>
#include <linux/highmem.h>
#include <linux/time.h>
#include <linux/security.h>
#include <linux/compat.h>
#include <linux/vfs.h>
+#include <linux/ipc.h>
#include <net/sock.h>
#include <net/scm.h>
-#include <asm/ipc.h>
+#include <asm/compat-signal.h>
#include <asm/sim.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#define AA(__x) ((unsigned long)((int)__x))
#ifdef __MIPSEB__
-#define merge_64(r1,r2) ((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL))
+#define merge_64(r1, r2) ((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL))
#endif
#ifdef __MIPSEL__
-#define merge_64(r1,r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
+#define merge_64(r1, r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
#endif
-/*
- * Revalidate the inode. This is required for proper NFS attribute caching.
- */
-
-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
-{
- struct compat_stat tmp;
-
- if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
- return -EOVERFLOW;
-
- memset(&tmp, 0, sizeof(tmp));
- tmp.st_dev = new_encode_dev(stat->dev);
- tmp.st_ino = stat->ino;
- if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
- return -EOVERFLOW;
- tmp.st_mode = stat->mode;
- tmp.st_nlink = stat->nlink;
- SET_UID(tmp.st_uid, stat->uid);
- SET_GID(tmp.st_gid, stat->gid);
- tmp.st_rdev = new_encode_dev(stat->rdev);
- tmp.st_size = stat->size;
- tmp.st_atime = stat->atime.tv_sec;
- tmp.st_mtime = stat->mtime.tv_sec;
- tmp.st_ctime = stat->ctime.tv_sec;
-#ifdef STAT_HAVE_NSEC
- tmp.st_atime_nsec = stat->atime.tv_nsec;
- tmp.st_mtime_nsec = stat->mtime.tv_nsec;
- tmp.st_ctime_nsec = stat->ctime.tv_nsec;
-#endif
- tmp.st_blocks = stat->blocks;
- tmp.st_blksize = stat->blksize;
- return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
-}
-
-asmlinkage unsigned long
-sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
- unsigned long flags, unsigned long fd, unsigned long pgoff)
+SYSCALL_DEFINE6(32_mmap2, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags, unsigned long, fd,
+ unsigned long, pgoff)
{
struct file * file = NULL;
unsigned long error;
return error;
}
-
-asmlinkage int sys_truncate64(const char __user *path, unsigned int high,
- unsigned int low)
-{
- if ((int)high < 0)
- return -EINVAL;
- return sys_truncate(path, ((long) high << 32) | low);
-}
-
-asmlinkage int sys_ftruncate64(unsigned int fd, unsigned int high,
- unsigned int low)
-{
- if ((int)high < 0)
- return -EINVAL;
- return sys_ftruncate(fd, ((long) high << 32) | low);
-}
-
/*
* sys_execve() executes a new program.
*/
return error;
}
-asmlinkage long
-sysn32_waitid(int which, compat_pid_t pid,
- siginfo_t __user *uinfo, int options,
- struct compat_rusage __user *uru)
-{
- struct rusage ru;
- long ret;
- mm_segment_t old_fs = get_fs();
- int si_signo;
-
- if (!access_ok(VERIFY_WRITE, uinfo, sizeof(*uinfo)))
- return -EFAULT;
-
- set_fs (KERNEL_DS);
- ret = sys_waitid(which, pid, uinfo, options,
- uru ? (struct rusage __user *) &ru : NULL);
- set_fs (old_fs);
-
- if (__get_user(si_signo, &uinfo->si_signo))
- return -EFAULT;
- if (ret < 0 || si_signo == 0)
- return ret;
-
- if (uru)
- ret = put_compat_rusage(&ru, uru);
- return ret;
-}
-
-struct sysinfo32 {
- s32 uptime;
- u32 loads[3];
- u32 totalram;
- u32 freeram;
- u32 sharedram;
- u32 bufferram;
- u32 totalswap;
- u32 freeswap;
- u16 procs;
- u32 totalhigh;
- u32 freehigh;
- u32 mem_unit;
- char _f[8];
-};
-
-asmlinkage int sys32_sysinfo(struct sysinfo32 __user *info)
-{
- struct sysinfo s;
- int ret, err;
- mm_segment_t old_fs = get_fs ();
-
- set_fs (KERNEL_DS);
- ret = sys_sysinfo((struct sysinfo __user *)&s);
- set_fs (old_fs);
- err = put_user (s.uptime, &info->uptime);
- err |= __put_user (s.loads[0], &info->loads[0]);
- err |= __put_user (s.loads[1], &info->loads[1]);
- err |= __put_user (s.loads[2], &info->loads[2]);
- err |= __put_user (s.totalram, &info->totalram);
- err |= __put_user (s.freeram, &info->freeram);
- err |= __put_user (s.sharedram, &info->sharedram);
- err |= __put_user (s.bufferram, &info->bufferram);
- err |= __put_user (s.totalswap, &info->totalswap);
- err |= __put_user (s.freeswap, &info->freeswap);
- err |= __put_user (s.procs, &info->procs);
- err |= __put_user (s.totalhigh, &info->totalhigh);
- err |= __put_user (s.freehigh, &info->freehigh);
- err |= __put_user (s.mem_unit, &info->mem_unit);
- if (err)
- return -EFAULT;
- return ret;
-}
-
#define RLIM_INFINITY32 0x7fffffff
#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
int rlim_max;
};
-#ifdef __MIPSEB__
-asmlinkage long sys32_truncate64(const char __user * path, unsigned long __dummy,
- int length_hi, int length_lo)
-#endif
-#ifdef __MIPSEL__
-asmlinkage long sys32_truncate64(const char __user * path, unsigned long __dummy,
- int length_lo, int length_hi)
-#endif
-{
- loff_t length;
-
- length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
-
- return sys_truncate(path, length);
-}
-
-#ifdef __MIPSEB__
-asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
- int length_hi, int length_lo)
-#endif
-#ifdef __MIPSEL__
-asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
- int length_lo, int length_hi)
-#endif
+SYSCALL_DEFINE4(32_truncate64, const char __user *, path,
+ unsigned long, __dummy, unsigned long, a2, unsigned long, a3)
{
- loff_t length;
-
- length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
-
- return sys_ftruncate(fd, length);
+ return sys_truncate(path, merge_64(a2, a3));
}
-static inline long
-get_tv32(struct timeval *o, struct compat_timeval __user *i)
+SYSCALL_DEFINE4(32_ftruncate64, unsigned long, fd, unsigned long, __dummy,
+ unsigned long, a2, unsigned long, a3)
{
- return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
- (__get_user(o->tv_sec, &i->tv_sec) |
- __get_user(o->tv_usec, &i->tv_usec)));
+ return sys_ftruncate(fd, merge_64(a2, a3));
}
-static inline long
-put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
- return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
- (__put_user(i->tv_sec, &o->tv_sec) |
- __put_user(i->tv_usec, &o->tv_usec)));
-}
-
-extern struct timezone sys_tz;
-
-asmlinkage int
-sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
- if (tv) {
- struct timeval ktv;
- do_gettimeofday(&ktv);
- if (put_tv32(tv, &ktv))
- return -EFAULT;
- }
- if (tz) {
- if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
- return -EFAULT;
- }
- return 0;
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
- long usec;
-
- if (!access_ok(VERIFY_READ, i, sizeof(*i)))
- return -EFAULT;
- if (__get_user(o->tv_sec, &i->tv_sec))
- return -EFAULT;
- if (__get_user(usec, &i->tv_usec))
- return -EFAULT;
- o->tv_nsec = usec * 1000;
- return 0;
-}
-
-asmlinkage int
-sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
- struct timespec kts;
- struct timezone ktz;
-
- if (tv) {
- if (get_ts32(&kts, tv))
- return -EFAULT;
- }
- if (tz) {
- if (copy_from_user(&ktz, tz, sizeof(ktz)))
- return -EFAULT;
- }
-
- return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
-asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
- unsigned int offset_low, loff_t __user * result,
- unsigned int origin)
+SYSCALL_DEFINE5(32_llseek, unsigned int, fd, unsigned int, offset_high,
+ unsigned int, offset_low, loff_t __user *, result,
+ unsigned int, origin)
{
return sys_llseek(fd, offset_high, offset_low, result, origin);
}
lseek back to original location. They fail just like lseek does on
non-seekable files. */
-asmlinkage ssize_t sys32_pread(unsigned int fd, char __user * buf,
- size_t count, u32 unused, u64 a4, u64 a5)
+SYSCALL_DEFINE6(32_pread, unsigned long, fd, char __user *, buf, size_t, count,
+ unsigned long, unused, unsigned long, a4, unsigned long, a5)
{
return sys_pread64(fd, buf, count, merge_64(a4, a5));
}
-asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char __user * buf,
- size_t count, u32 unused, u64 a4, u64 a5)
+SYSCALL_DEFINE6(32_pwrite, unsigned int, fd, const char __user *, buf,
+ size_t, count, u32, unused, u64, a4, u64, a5)
{
return sys_pwrite64(fd, buf, count, merge_64(a4, a5));
}
-asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid,
- struct compat_timespec __user *interval)
+SYSCALL_DEFINE2(32_sched_rr_get_interval, compat_pid_t, pid,
+ struct compat_timespec __user *, interval)
{
struct timespec t;
int ret;
- mm_segment_t old_fs = get_fs ();
+ mm_segment_t old_fs = get_fs();
- set_fs (KERNEL_DS);
+ set_fs(KERNEL_DS);
ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
- set_fs (old_fs);
+ set_fs(old_fs);
if (put_user (t.tv_sec, &interval->tv_sec) ||
- __put_user (t.tv_nsec, &interval->tv_nsec))
+ __put_user(t.tv_nsec, &interval->tv_nsec))
return -EFAULT;
return ret;
}
-asmlinkage long
-sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
+#ifdef CONFIG_SYSVIPC
+
+SYSCALL_DEFINE6(32_ipc, u32, call, long, first, long, second, long, third,
+ unsigned long, ptr, unsigned long, fifth)
{
int version, err;
return err;
}
+#else
+
+SYSCALL_DEFINE6(32_ipc, u32, call, int, first, int, second, int, third,
+ u32, ptr, u32, fifth)
+{
+ return -ENOSYS;
+}
+
+#endif /* CONFIG_SYSVIPC */
+
#ifdef CONFIG_MIPS32_N32
-asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, union semun arg)
+SYSCALL_DEFINE4(n32_semctl, int, semid, int, semnum, int, cmd, u32, arg)
{
/* compat_sys_semctl expects a pointer to union semun */
u32 __user *uptr = compat_alloc_user_space(sizeof(u32));
- if (put_user(ptr_to_compat(arg.__pad), uptr))
+ if (put_user(arg, uptr))
return -EFAULT;
return compat_sys_semctl(semid, semnum, cmd, uptr);
}
+
+SYSCALL_DEFINE4(n32_msgsnd, int, msqid, u32, msgp, unsigned int, msgsz,
+ int, msgflg)
+{
+ return compat_sys_msgsnd(msqid, msgsz, msgflg, compat_ptr(msgp));
+}
+
+SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz,
+ int, msgtyp, int, msgflg)
+{
+ return compat_sys_msgrcv(msqid, msgsz, msgtyp, msgflg, IPC_64,
+ compat_ptr(msgp));
+}
#endif
struct sysctl_args32
#ifdef CONFIG_SYSCTL_SYSCALL
-asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args)
+SYSCALL_DEFINE1(32_sysctl, struct sysctl_args32 __user *, args)
{
struct sysctl_args32 tmp;
int error;
return error;
}
+#else
+
+SYSCALL_DEFINE1(32_sysctl, struct sysctl_args32 __user *, args)
+{
+ return -ENOSYS;
+}
+
#endif /* CONFIG_SYSCTL_SYSCALL */
-asmlinkage long sys32_newuname(struct new_utsname __user * name)
+SYSCALL_DEFINE1(32_newuname, struct new_utsname __user *, name)
{
int ret = 0;
return ret;
}
-asmlinkage int sys32_personality(unsigned long personality)
+SYSCALL_DEFINE1(32_personality, unsigned long, personality)
{
int ret;
personality &= 0xffffffff;
return ret;
}
-/* ustat compatibility */
-struct ustat32 {
- compat_daddr_t f_tfree;
- compat_ino_t f_tinode;
- char f_fname[6];
- char f_fpack[6];
-};
-
-extern asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf);
-
-asmlinkage int sys32_ustat(dev_t dev, struct ustat32 __user * ubuf32)
-{
- int err;
- struct ustat tmp;
- struct ustat32 tmp32;
- mm_segment_t old_fs = get_fs();
-
- set_fs(KERNEL_DS);
- err = sys_ustat(dev, (struct ustat __user *)&tmp);
- set_fs (old_fs);
-
- if (err)
- goto out;
-
- memset(&tmp32,0,sizeof(struct ustat32));
- tmp32.f_tfree = tmp.f_tfree;
- tmp32.f_tinode = tmp.f_tinode;
-
- err = copy_to_user(ubuf32,&tmp32,sizeof(struct ustat32)) ? -EFAULT : 0;
-
-out:
- return err;
-}
-
-asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset,
- s32 count)
+SYSCALL_DEFINE4(32_sendfile, long, out_fd, long, in_fd,
+ compat_off_t __user *, offset, s32, count)
{
mm_segment_t old_fs = get_fs();
int ret;
flags);
}
-/* Argument list sizes for sys_socketcall */
-#define AL(x) ((x) * sizeof(unsigned int))
-static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
- AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
- AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
-#undef AL
-
-/*
- * System call vectors.
- *
- * Argument checking cleaned up. Saved 20% in size.
- * This function doesn't need to set the kernel lock because
- * it is set by the callees.
- */
-
-asmlinkage long sys32_socketcall(int call, unsigned int __user *args32)
+asmlinkage long sys32_fadvise64_64(int fd, int __pad,
+ unsigned long a2, unsigned long a3,
+ unsigned long a4, unsigned long a5,
+ int flags)
{
- unsigned int a[6];
- unsigned int a0,a1;
- int err;
-
- extern asmlinkage long sys_socket(int family, int type, int protocol);
- extern asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen);
- extern asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen);
- extern asmlinkage long sys_listen(int fd, int backlog);
- extern asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen);
- extern asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len);
- extern asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len);
- extern asmlinkage long sys_socketpair(int family, int type, int protocol, int __user *usockvec);
- extern asmlinkage long sys_send(int fd, void __user * buff, size_t len, unsigned flags);
- extern asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flags,
- struct sockaddr __user *addr, int addr_len);
- extern asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags);
- extern asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned flags,
- struct sockaddr __user *addr, int __user *addr_len);
- extern asmlinkage long sys_shutdown(int fd, int how);
- extern asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen);
- extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen);
- extern asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
- extern asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flags);
-
-
- if(call<1||call>SYS_RECVMSG)
- return -EINVAL;
-
- /* copy_from_user should be SMP safe. */
- if (copy_from_user(a, args32, socketcall_nargs[call]))
- return -EFAULT;
-
- a0=a[0];
- a1=a[1];
-
- switch(call)
- {
- case SYS_SOCKET:
- err = sys_socket(a0,a1,a[2]);
- break;
- case SYS_BIND:
- err = sys_bind(a0,(struct sockaddr __user *)A(a1), a[2]);
- break;
- case SYS_CONNECT:
- err = sys_connect(a0, (struct sockaddr __user *)A(a1), a[2]);
- break;
- case SYS_LISTEN:
- err = sys_listen(a0,a1);
- break;
- case SYS_ACCEPT:
- err = sys_accept(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
- break;
- case SYS_GETSOCKNAME:
- err = sys_getsockname(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
- break;
- case SYS_GETPEERNAME:
- err = sys_getpeername(a0, (struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
- break;
- case SYS_SOCKETPAIR:
- err = sys_socketpair(a0,a1, a[2], (int __user *)A(a[3]));
- break;
- case SYS_SEND:
- err = sys_send(a0, (void __user *)A(a1), a[2], a[3]);
- break;
- case SYS_SENDTO:
- err = sys_sendto(a0,(void __user *)A(a1), a[2], a[3],
- (struct sockaddr __user *)A(a[4]), a[5]);
- break;
- case SYS_RECV:
- err = sys_recv(a0, (void __user *)A(a1), a[2], a[3]);
- break;
- case SYS_RECVFROM:
- err = sys_recvfrom(a0, (void __user *)A(a1), a[2], a[3],
- (struct sockaddr __user *)A(a[4]), (int __user *)A(a[5]));
- break;
- case SYS_SHUTDOWN:
- err = sys_shutdown(a0,a1);
- break;
- case SYS_SETSOCKOPT:
- err = sys_setsockopt(a0, a1, a[2], (char __user *)A(a[3]), a[4]);
- break;
- case SYS_GETSOCKOPT:
- err = sys_getsockopt(a0, a1, a[2], (char __user *)A(a[3]), (int __user *)A(a[4]));
- break;
- case SYS_SENDMSG:
- err = sys_sendmsg(a0, (struct msghdr __user *) A(a1), a[2]);
- break;
- case SYS_RECVMSG:
- err = sys_recvmsg(a0, (struct msghdr __user *) A(a1), a[2]);
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
+ return sys_fadvise64_64(fd,
+ merge_64(a2, a3), merge_64(a4, a5),
+ flags);
}
-struct sigevent32 {
- u32 sigev_value;
- u32 sigev_signo;
- u32 sigev_notify;
- u32 payload[(64 / 4) - 3];
-};
-
-extern asmlinkage long
-sys_timer_create(clockid_t which_clock,
- struct sigevent __user *timer_event_spec,
- timer_t __user * created_timer_id);
-
-long
-sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id)
+asmlinkage long sys32_fallocate(int fd, int mode, unsigned offset_a2,
+ unsigned offset_a3, unsigned len_a4, unsigned len_a5)
{
- struct sigevent __user *p = NULL;
- if (se32) {
- struct sigevent se;
- p = compat_alloc_user_space(sizeof(struct sigevent));
- memset(&se, 0, sizeof(struct sigevent));
- if (get_user(se.sigev_value.sival_int, &se32->sigev_value) ||
- __get_user(se.sigev_signo, &se32->sigev_signo) ||
- __get_user(se.sigev_notify, &se32->sigev_notify) ||
- __copy_from_user(&se._sigev_un._pad, &se32->payload,
- sizeof(se32->payload)) ||
- copy_to_user(p, &se, sizeof(se)))
- return -EFAULT;
- }
- return sys_timer_create(clock, p, timer_id);
+ return sys_fallocate(fd, mode, merge_64(offset_a2, offset_a3),
+ merge_64(len_a4, len_a5));
}
save_static_function(sys32_clone);
-__attribute_used__ noinline static int
+static int noinline __used
_sys32_clone(nabi_no_regargs struct pt_regs regs)
{
unsigned long clone_flags;
return do_fork(clone_flags, newsp, ®s, 0,
parent_tidptr, child_tidptr);
}
+
+asmlinkage long sys32_lookup_dcookie(u32 a0, u32 a1, char __user *buf,
+ size_t len)
+{
+ return sys_lookup_dcookie(merge_64(a0, a1), buf, len);
+}