[PARISC] Allow overriding personality with sys_personality
Kyle McMartin [Sun, 27 Aug 2006 15:12:13 +0000 (11:12 -0400)]
And now suddenly, linux32 works on parisc...

Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>

arch/parisc/kernel/sys_parisc.c
arch/parisc/kernel/syscall_table.S

index 8b5df98..1db5588 100644 (file)
@@ -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;
+}
index e27b432..701d66a 100644 (file)
        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)
        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)