Commit f9a4660b authored by Stephen Rothwell's avatar Stephen Rothwell Committed by Linus Torvalds

[PATCH] mips64 compatibility syscall layer

Given Ralf's blessing, here is the mips64 part of the initial compatibility
syscall layer.
parent a9ff25c8
...@@ -371,6 +371,11 @@ config MIPS32_COMPAT ...@@ -371,6 +371,11 @@ config MIPS32_COMPAT
compatibility. Since all software available for Linux/MIPS is compatibility. Since all software available for Linux/MIPS is
currently 32-bit you should say Y here. currently 32-bit you should say Y here.
config COMPAT
bool
depends on MIPS32_COMPAT
default y
config BINFMT_ELF32 config BINFMT_ELF32
bool bool
depends on MIPS32_COMPAT depends on MIPS32_COMPAT
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/compat.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -65,14 +66,9 @@ static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg) ...@@ -65,14 +66,9 @@ static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
#define A(__x) ((unsigned long)(__x)) #define A(__x) ((unsigned long)(__x))
struct timeval32 {
int tv_sec;
int tv_usec;
};
static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg) static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
{ {
struct timeval32 *up = (struct timeval32 *)arg; struct compat_timeval *up = (struct compat_timeval *)arg;
struct timeval ktv; struct timeval ktv;
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
int err; int err;
......
...@@ -22,11 +22,11 @@ ...@@ -22,11 +22,11 @@
#include <linux/sem.h> #include <linux/sem.h>
#include <linux/msg.h> #include <linux/msg.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
#include <linux/utime.h>
#include <linux/utsname.h> #include <linux/utsname.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/timex.h> #include <linux/timex.h>
#include <linux/dnotify.h> #include <linux/dnotify.h>
#include <linux/compat.h>
#include <net/sock.h> #include <net/sock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -116,36 +116,6 @@ asmlinkage int sys_ftruncate64(unsigned int fd, unsigned int high, ...@@ -116,36 +116,6 @@ asmlinkage int sys_ftruncate64(unsigned int fd, unsigned int high,
return sys_ftruncate(fd, ((long) high << 32) | low); return sys_ftruncate(fd, ((long) high << 32) | low);
} }
extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
__kernel_time_t32 actime, modtime;
};
asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
{
struct utimbuf t;
mm_segment_t old_fs;
int ret;
char *filenam;
if (!times)
return sys_utime(filename, NULL);
if (get_user (t.actime, &times->actime) ||
__get_user (t.modtime, &times->modtime))
return -EFAULT;
filenam = getname (filename);
ret = PTR_ERR(filenam);
if (!IS_ERR(filenam)) {
old_fs = get_fs();
set_fs (KERNEL_DS);
ret = sys_utime(filenam, &t);
set_fs (old_fs);
putname (filenam);
}
return ret;
}
#if 0 #if 0
/* /*
* count32() counts the number of arguments/envelopes * count32() counts the number of arguments/envelopes
...@@ -463,20 +433,9 @@ sys32_readdir(unsigned int fd, void * dirent32, unsigned int count) ...@@ -463,20 +433,9 @@ sys32_readdir(unsigned int fd, void * dirent32, unsigned int count)
return(n); return(n);
} }
struct timeval32
{
int tv_sec, tv_usec;
};
struct itimerval32
{
struct timeval32 it_interval;
struct timeval32 it_value;
};
struct rusage32 { struct rusage32 {
struct timeval32 ru_utime; struct compat_timeval ru_utime;
struct timeval32 ru_stime; struct compat_timeval ru_stime;
int ru_maxrss; int ru_maxrss;
int ru_ixrss; int ru_ixrss;
int ru_idrss; int ru_idrss;
...@@ -683,7 +642,7 @@ sys32_getrusage(int who, struct rusage32 *ru) ...@@ -683,7 +642,7 @@ sys32_getrusage(int who, struct rusage32 *ru)
} }
static inline long static inline long
get_tv32(struct timeval *o, struct timeval32 *i) get_tv32(struct timeval *o, struct compat_timeval *i)
{ {
return (!access_ok(VERIFY_READ, i, sizeof(*i)) || return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
(__get_user(o->tv_sec, &i->tv_sec) | (__get_user(o->tv_sec, &i->tv_sec) |
...@@ -691,72 +650,13 @@ get_tv32(struct timeval *o, struct timeval32 *i) ...@@ -691,72 +650,13 @@ get_tv32(struct timeval *o, struct timeval32 *i)
} }
static inline long static inline long
get_it32(struct itimerval *o, struct itimerval32 *i) put_tv32(struct compat_timeval *o, struct timeval *i)
{
return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
(__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
__get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
__get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
__get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
}
static inline long
put_tv32(struct timeval32 *o, struct timeval *i)
{ {
return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
(__put_user(i->tv_sec, &o->tv_sec) | (__put_user(i->tv_sec, &o->tv_sec) |
__put_user(i->tv_usec, &o->tv_usec))); __put_user(i->tv_usec, &o->tv_usec)));
} }
static inline long
put_it32(struct itimerval32 *o, struct itimerval *i)
{
return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
__put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
__put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
__put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
}
extern int do_getitimer(int which, struct itimerval *value);
asmlinkage int
sys32_getitimer(int which, struct itimerval32 *it)
{
struct itimerval kit;
int error;
error = do_getitimer(which, &kit);
if (!error && put_it32(it, &kit))
error = -EFAULT;
return error;
}
extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
asmlinkage int
sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
{
struct itimerval kin, kout;
int error;
if (in) {
if (get_it32(&kin, in))
return -EFAULT;
} else
memset(&kin, 0, sizeof(kin));
error = do_setitimer(which, &kin, out ? &kout : NULL);
if (error || !out)
return error;
if (put_it32(out, &kout))
return -EFAULT;
return 0;
}
asmlinkage unsigned long asmlinkage unsigned long
sys32_alarm(unsigned int seconds) sys32_alarm(unsigned int seconds)
{ {
...@@ -784,7 +684,7 @@ extern struct timezone sys_tz; ...@@ -784,7 +684,7 @@ extern struct timezone sys_tz;
extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz); extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
asmlinkage int asmlinkage int
sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz) sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
{ {
if (tv) { if (tv) {
struct timeval ktv; struct timeval ktv;
...@@ -800,7 +700,7 @@ sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz) ...@@ -800,7 +700,7 @@ sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
} }
asmlinkage int asmlinkage int
sys32_settimeofday(struct timeval32 *tv, struct timezone *tz) sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
{ {
struct timeval ktv; struct timeval ktv;
struct timezone ktz; struct timezone ktz;
...@@ -1112,7 +1012,7 @@ set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset) ...@@ -1112,7 +1012,7 @@ set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
#define MAX_SELECT_SECONDS \ #define MAX_SELECT_SECONDS \
((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, struct timeval32 *tvp) asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, struct compat_timeval *tvp)
{ {
fd_set_bits fds; fd_set_bits fds;
char *bits; char *bits;
...@@ -1205,16 +1105,11 @@ asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, struct timeval ...@@ -1205,16 +1105,11 @@ asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, struct timeval
struct timespec32 {
int tv_sec;
int tv_nsec;
};
extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, extern asmlinkage int sys_sched_rr_get_interval(pid_t pid,
struct timespec *interval); struct timespec *interval);
asmlinkage int asmlinkage int
sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval) sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct compat_timespec *interval)
{ {
struct timespec t; struct timespec t;
int ret; int ret;
...@@ -1230,31 +1125,6 @@ sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval) ...@@ -1230,31 +1125,6 @@ sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
} }
extern asmlinkage int sys_nanosleep(struct timespec *rqtp,
struct timespec *rmtp);
asmlinkage int
sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
{
struct timespec t;
int ret;
mm_segment_t old_fs = get_fs ();
if (get_user (t.tv_sec, &rqtp->tv_sec) ||
__get_user (t.tv_nsec, &rqtp->tv_nsec))
return -EFAULT;
set_fs (KERNEL_DS);
ret = sys_nanosleep(&t, rmtp ? &t : NULL);
set_fs (old_fs);
if (rmtp && ret == -EINTR) {
if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
__put_user (t.tv_nsec, &rmtp->tv_nsec))
return -EFAULT;
}
return ret;
}
struct tms32 { struct tms32 {
int tms_utime; int tms_utime;
int tms_stime; int tms_stime;
...@@ -1418,8 +1288,8 @@ struct ipc_perm32 ...@@ -1418,8 +1288,8 @@ struct ipc_perm32
struct semid_ds32 { struct semid_ds32 {
struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */ struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
__kernel_time_t32 sem_otime; /* last semop time */ compat_time_t sem_otime; /* last semop time */
__kernel_time_t32 sem_ctime; /* last change time */ compat_time_t sem_ctime; /* last change time */
u32 sem_base; /* ptr to first semaphore in array */ u32 sem_base; /* ptr to first semaphore in array */
u32 sem_pending; /* pending operations to be processed */ u32 sem_pending; /* pending operations to be processed */
u32 sem_pending_last; /* last pending operation */ u32 sem_pending_last; /* last pending operation */
...@@ -1432,9 +1302,9 @@ struct msqid_ds32 ...@@ -1432,9 +1302,9 @@ struct msqid_ds32
struct ipc_perm32 msg_perm; struct ipc_perm32 msg_perm;
u32 msg_first; u32 msg_first;
u32 msg_last; u32 msg_last;
__kernel_time_t32 msg_stime; compat_time_t msg_stime;
__kernel_time_t32 msg_rtime; compat_time_t msg_rtime;
__kernel_time_t32 msg_ctime; compat_time_t msg_ctime;
u32 wwait; u32 wwait;
u32 rwait; u32 rwait;
unsigned short msg_cbytes; unsigned short msg_cbytes;
...@@ -1447,9 +1317,9 @@ struct msqid_ds32 ...@@ -1447,9 +1317,9 @@ struct msqid_ds32
struct shmid_ds32 { struct shmid_ds32 {
struct ipc_perm32 shm_perm; struct ipc_perm32 shm_perm;
int shm_segsz; int shm_segsz;
__kernel_time_t32 shm_atime; compat_time_t shm_atime;
__kernel_time_t32 shm_dtime; compat_time_t shm_dtime;
__kernel_time_t32 shm_ctime; compat_time_t shm_ctime;
__kernel_ipc_pid_t32 shm_cpid; __kernel_ipc_pid_t32 shm_cpid;
__kernel_ipc_pid_t32 shm_lpid; __kernel_ipc_pid_t32 shm_lpid;
unsigned short shm_nattch; unsigned short shm_nattch;
...@@ -1819,7 +1689,7 @@ struct sysctl_args32 ...@@ -1819,7 +1689,7 @@ struct sysctl_args32
__kernel_caddr_t32 oldval; __kernel_caddr_t32 oldval;
__kernel_caddr_t32 oldlenp; __kernel_caddr_t32 oldlenp;
__kernel_caddr_t32 newval; __kernel_caddr_t32 newval;
__kernel_size_t32 newlen; compat_size_t newlen;
unsigned int __unused[4]; unsigned int __unused[4];
}; };
...@@ -1935,7 +1805,7 @@ struct timex32 { ...@@ -1935,7 +1805,7 @@ struct timex32 {
u32 modes; u32 modes;
s32 offset, freq, maxerror, esterror; s32 offset, freq, maxerror, esterror;
s32 status, constant, precision, tolerance; s32 status, constant, precision, tolerance;
struct timeval32 time; struct compat_timeval time;
s32 tick; s32 tick;
s32 ppsfreq, jitter, shift, stabil; s32 ppsfreq, jitter, shift, stabil;
s32 jitcnt, calcnt, errcnt, stbcnt; s32 jitcnt, calcnt, errcnt, stbcnt;
......
...@@ -263,7 +263,7 @@ illegal_syscall: ...@@ -263,7 +263,7 @@ illegal_syscall:
sys sys32_alarm 1 sys sys32_alarm 1
sys sys_fstat 2 sys sys_fstat 2
sys sys_pause 0 sys sys_pause 0
sys sys32_utime 2 /* 4030 */ sys compat_sys_utime 2 /* 4030 */
sys sys_ni_syscall 0 sys sys_ni_syscall 0
sys sys_ni_syscall 0 sys sys_ni_syscall 0
sys sys_access 2 sys sys_access 2
...@@ -337,8 +337,8 @@ illegal_syscall: ...@@ -337,8 +337,8 @@ illegal_syscall:
sys sys_ni_syscall 0 /* sys_ioperm */ sys sys_ni_syscall 0 /* sys_ioperm */
sys sys_socketcall 2 sys sys_socketcall 2
sys sys_syslog 3 sys sys_syslog 3
sys sys32_setitimer 3 sys compat_sys_setitimer 3
sys sys32_getitimer 2 /* 4105 */ sys compat_sys_getitimer 2 /* 4105 */
sys sys32_newstat 2 sys sys32_newstat 2
sys sys32_newlstat 2 sys sys32_newlstat 2
sys sys32_newfstat 2 sys sys32_newfstat 2
...@@ -399,7 +399,7 @@ illegal_syscall: ...@@ -399,7 +399,7 @@ illegal_syscall:
sys sys_sched_get_priority_max 1 sys sys_sched_get_priority_max 1
sys sys_sched_get_priority_min 1 sys sys_sched_get_priority_min 1
sys sys32_sched_rr_get_interval 2 /* 4165 */ sys sys32_sched_rr_get_interval 2 /* 4165 */
sys sys32_nanosleep 2 sys compat_sys_nanosleep 2
sys sys_mremap 4 sys sys_mremap 4
sys sys_accept 3 sys sys_accept 3
sys sys_bind 3 sys sys_bind 3
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/compat.h>
#include <asm/asm.h> #include <asm/asm.h>
#include <asm/bitops.h> #include <asm/bitops.h>
...@@ -59,7 +60,7 @@ struct sigaction32 { ...@@ -59,7 +60,7 @@ struct sigaction32 {
/* IRIX compatible stack_t */ /* IRIX compatible stack_t */
typedef struct sigaltstack32 { typedef struct sigaltstack32 {
s32 ss_sp; s32 ss_sp;
__kernel_size_t32 ss_size; compat_size_t ss_size;
int ss_flags; int ss_flags;
} stack32_t; } stack32_t;
......
#ifndef _ASM_MIPS64_COMPAT_H
#define _ASM_MIPS64_COMPAT_H
/*
* Architecture specific compatibility types
*/
#include <linux/types.h>
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
typedef s32 compat_time_t;
typedef s32 compat_suseconds_t;
struct compat_timespec {
compat_time_t tv_sec;
s32 tv_nsec;
};
#endif /* _ASM_MIPS64_COMPAT_H */
...@@ -58,10 +58,7 @@ typedef int __kernel_pid_t32; ...@@ -58,10 +58,7 @@ typedef int __kernel_pid_t32;
typedef int __kernel_ipc_pid_t32; typedef int __kernel_ipc_pid_t32;
typedef int __kernel_uid_t32; typedef int __kernel_uid_t32;
typedef int __kernel_gid_t32; typedef int __kernel_gid_t32;
typedef unsigned int __kernel_size_t32;
typedef int __kernel_ssize_t32;
typedef int __kernel_ptrdiff_t32; typedef int __kernel_ptrdiff_t32;
typedef int __kernel_time_t32;
typedef int __kernel_suseconds_t32; typedef int __kernel_suseconds_t32;
typedef int __kernel_clock_t32; typedef int __kernel_clock_t32;
typedef int __kernel_daddr_t32; typedef int __kernel_daddr_t32;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define _ASM_STAT_H #define _ASM_STAT_H
#include <linux/types.h> #include <linux/types.h>
#include <linux/compat.h>
struct __old_kernel_stat { struct __old_kernel_stat {
unsigned int st_dev; unsigned int st_dev;
...@@ -40,11 +41,11 @@ struct stat32 { ...@@ -40,11 +41,11 @@ struct stat32 {
int st_pad2[2]; int st_pad2[2];
__kernel_off_t32 st_size; __kernel_off_t32 st_size;
int st_pad3; int st_pad3;
__kernel_time_t32 st_atime; compat_time_t st_atime;
int reserved0; int reserved0;
__kernel_time_t32 st_mtime; compat_time_t st_mtime;
int reserved1; int reserved1;
__kernel_time_t32 st_ctime; compat_time_t st_ctime;
int reserved2; int reserved2;
int st_blksize; int st_blksize;
int st_blocks; int st_blocks;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment