summaryrefslogtreecommitdiffstats
path: root/arch/mips64/kernel/linux32.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-09-05 21:30:08 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-09-05 21:30:08 +0000
commit73c5c49c4d59b104dd3fc00a3e23ec73fc1a9e9c (patch)
tree9aa42e87ed13ed5b8943c72831b73ba7b675419b /arch/mips64/kernel/linux32.c
parentcd6236bd58e553626c20d99234566a4dbbf1734a (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.c89
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;
+}