diff options
author | Kyle McMartin <kyle@parisc-linux.org> | 2006-08-27 17:12:13 +0200 |
---|---|---|
committer | Matthew Wilcox <willy@parisc-linux.org> | 2006-10-04 14:46:53 +0200 |
commit | 75a4958154f5d0028d5464f2479b4297d55cf4a3 (patch) | |
tree | 54121490e3a1f423b18e78d7f216dfc32bc71b64 /arch/parisc | |
parent | [PARISC] Switch is_compat_task to use TIF_32BIT (diff) | |
download | linux-75a4958154f5d0028d5464f2479b4297d55cf4a3.tar.xz linux-75a4958154f5d0028d5464f2479b4297d55cf4a3.zip |
[PARISC] Allow overriding personality with sys_personality
And now suddenly, linux32 works on parisc...
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'arch/parisc')
-rw-r--r-- | arch/parisc/kernel/sys_parisc.c | 45 | ||||
-rw-r--r-- | arch/parisc/kernel/syscall_table.S | 4 |
2 files changed, 47 insertions, 2 deletions
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 8b5df98e2b31..1db5588ceacf 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -31,6 +31,8 @@ #include <linux/shm.h> #include <linux/smp_lock.h> #include <linux/syscalls.h> +#include <linux/utsname.h> +#include <linux/personality.h> int sys_pipe(int __user *fildes) { @@ -248,3 +250,46 @@ asmlinkage int sys_free_hugepages(unsigned long addr) { return -EINVAL; } + +long parisc_personality(unsigned long personality) +{ + long err; + + if (personality(current->personality) == PER_LINUX32 + && personality == PER_LINUX) + personality = PER_LINUX32; + + err = sys_personality(personality); + if (err == PER_LINUX32) + err = PER_LINUX; + + return err; +} + +static inline int override_machine(char __user *mach) { +#ifdef CONFIG_COMPAT + if (personality(current->personality) == PER_LINUX32) { + if (__put_user(0, mach + 6) || + __put_user(0, mach + 7)) + return -EFAULT; + } + + return 0; +#else /*!CONFIG_COMPAT*/ + return 0; +#endif /*CONFIG_COMPAT*/ +} + +long parisc_newuname(struct new_utsname __user *utsname) +{ + int err = 0; + + down_read(&uts_sem); + if (copy_to_user(utsname, &system_utsname, sizeof(*utsname))) + err = -EFAULT; + up_read(&uts_sem); + + err = override_machine(utsname->machine); + + return (long)err; +} diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index e27b432f90a8..701d66a596e8 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -132,7 +132,7 @@ ENTRY_SAME(socketpair) ENTRY_SAME(setpgid) ENTRY_SAME(send) - ENTRY_SAME(newuname) + ENTRY_OURS(newuname) ENTRY_SAME(umask) /* 60 */ ENTRY_SAME(chroot) ENTRY_SAME(ustat) @@ -221,7 +221,7 @@ ENTRY_SAME(fchdir) ENTRY_SAME(bdflush) ENTRY_SAME(sysfs) /* 135 */ - ENTRY_SAME(personality) + ENTRY_OURS(personality) ENTRY_SAME(ni_syscall) /* for afs_syscall */ ENTRY_SAME(setfsuid) ENTRY_SAME(setfsgid) |