summaryrefslogtreecommitdiffstats
path: root/arch/mips64/kernel
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
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')
-rw-r--r--arch/mips64/kernel/linux32.c89
-rw-r--r--arch/mips64/kernel/scall_o32.S4
2 files changed, 90 insertions, 3 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;
+}
diff --git a/arch/mips64/kernel/scall_o32.S b/arch/mips64/kernel/scall_o32.S
index 6d3f211d7..4d1450a6b 100644
--- a/arch/mips64/kernel/scall_o32.S
+++ b/arch/mips64/kernel/scall_o32.S
@@ -325,7 +325,7 @@ illegal_syscall:
sys sys_setdomainname 2
sys sys32_newuname 1
sys sys_ni_syscall 0 /* sys_modify_ldt */
- sys sys_adjtimex 1
+ sys sys32_adjtimex 1
sys sys_mprotect 3 /* 4125 */
sys sys32_sigprocmask 3
sys sys_create_module 2
@@ -337,7 +337,7 @@ illegal_syscall:
sys sys_fchdir 1
sys sys_bdflush 2
sys sys_sysfs 3 /* 4135 */
- sys sys_personality 1
+ sys sys32_personality 1
sys sys_ni_syscall 0 /* for afs_syscall */
sys sys_setfsuid 1
sys sys_setfsgid 1