diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-09-05 21:30:08 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-09-05 21:30:08 +0000 |
commit | 73c5c49c4d59b104dd3fc00a3e23ec73fc1a9e9c (patch) | |
tree | 9aa42e87ed13ed5b8943c72831b73ba7b675419b /arch/mips64/kernel/linux32.c | |
parent | cd6236bd58e553626c20d99234566a4dbbf1734a (diff) |
- adjtimex(2) emulation.
- set_rtc_mmss was crashing the machine. This went unnoticed so far
only because it only happens one the machine is time synchronized.
The machine now synchronizes with NTP quite well.
- Better personality(2) emulation. This code is taken from Sparc64
which seems to do the right thing but I still wonder how it's
supposed to work there. Uname(2) returning sparc64 or mips64
instead of sparc or mips is breaking alot of configuration scripts
but on the other side returning the arch name without the 64 would
prevent easy detection of the architecture by autoconf style
scripts. I also don't see how the personality of 32-bit processes
is ever being set to PER_LINUX32.
Diffstat (limited to 'arch/mips64/kernel/linux32.c')
-rw-r--r-- | arch/mips64/kernel/linux32.c | 89 |
1 files changed, 88 insertions, 1 deletions
diff --git a/arch/mips64/kernel/linux32.c b/arch/mips64/kernel/linux32.c index f7e2f41cb..9c6643f81 100644 --- a/arch/mips64/kernel/linux32.c +++ b/arch/mips64/kernel/linux32.c @@ -5,7 +5,6 @@ * Written by Ulf Carlsson (ulfc@engr.sgi.com) * sys32_execve from ia64/ia32 code, Feb 2000, Kanoj Sarcar (kanoj@sgi.com) */ - #include <linux/mm.h> #include <linux/errno.h> #include <linux/file.h> @@ -24,6 +23,8 @@ #include <linux/msg.h> #include <linux/sysctl.h> #include <linux/utsname.h> +#include <linux/personality.h> +#include <linux/timex.h> #include <asm/uaccess.h> #include <asm/mman.h> @@ -1884,3 +1885,89 @@ asmlinkage long sys32_newuname(struct new_utsname * name) return ret; } + +extern asmlinkage long sys_personality(unsigned long); + +asmlinkage int sys32_personality(unsigned long personality) +{ + int ret; + if (current->personality == PER_LINUX32 && personality == PER_LINUX) + personality = PER_LINUX32; + ret = sys_personality(personality); + if (ret == PER_LINUX32) + ret = PER_LINUX; + return ret; +} + +/* Handle adjtimex compatability. */ + +struct timex32 { + u32 modes; + s32 offset, freq, maxerror, esterror; + s32 status, constant, precision, tolerance; + struct timeval32 time; + s32 tick; + s32 ppsfreq, jitter, shift, stabil; + s32 jitcnt, calcnt, errcnt, stbcnt; + s32 :32; s32 :32; s32 :32; s32 :32; + s32 :32; s32 :32; s32 :32; s32 :32; + s32 :32; s32 :32; s32 :32; s32 :32; +}; + +extern int do_adjtimex(struct timex *); + +asmlinkage int sys32_adjtimex(struct timex32 *utp) +{ + struct timex txc; + int ret; + + memset(&txc, 0, sizeof(struct timex)); + + if(get_user(txc.modes, &utp->modes) || + __get_user(txc.offset, &utp->offset) || + __get_user(txc.freq, &utp->freq) || + __get_user(txc.maxerror, &utp->maxerror) || + __get_user(txc.esterror, &utp->esterror) || + __get_user(txc.status, &utp->status) || + __get_user(txc.constant, &utp->constant) || + __get_user(txc.precision, &utp->precision) || + __get_user(txc.tolerance, &utp->tolerance) || + __get_user(txc.time.tv_sec, &utp->time.tv_sec) || + __get_user(txc.time.tv_usec, &utp->time.tv_usec) || + __get_user(txc.tick, &utp->tick) || + __get_user(txc.ppsfreq, &utp->ppsfreq) || + __get_user(txc.jitter, &utp->jitter) || + __get_user(txc.shift, &utp->shift) || + __get_user(txc.stabil, &utp->stabil) || + __get_user(txc.jitcnt, &utp->jitcnt) || + __get_user(txc.calcnt, &utp->calcnt) || + __get_user(txc.errcnt, &utp->errcnt) || + __get_user(txc.stbcnt, &utp->stbcnt)) + return -EFAULT; + + ret = do_adjtimex(&txc); + + if(put_user(txc.modes, &utp->modes) || + __put_user(txc.offset, &utp->offset) || + __put_user(txc.freq, &utp->freq) || + __put_user(txc.maxerror, &utp->maxerror) || + __put_user(txc.esterror, &utp->esterror) || + __put_user(txc.status, &utp->status) || + __put_user(txc.constant, &utp->constant) || + __put_user(txc.precision, &utp->precision) || + __put_user(txc.tolerance, &utp->tolerance) || + __put_user(txc.time.tv_sec, &utp->time.tv_sec) || + __put_user(txc.time.tv_usec, &utp->time.tv_usec) || + __put_user(txc.tick, &utp->tick) || + __put_user(txc.ppsfreq, &utp->ppsfreq) || + __put_user(txc.jitter, &utp->jitter) || + __put_user(txc.shift, &utp->shift) || + __put_user(txc.stabil, &utp->stabil) || + __put_user(txc.jitcnt, &utp->jitcnt) || + __put_user(txc.calcnt, &utp->calcnt) || + __put_user(txc.errcnt, &utp->errcnt) || + __put_user(txc.stbcnt, &utp->stbcnt)) + ret = -EFAULT; + + return ret; +} |