PER_LINUX32 Fixes for Linux/ppc64
(cf. http://blog.blackdown.de/2005/04/04/per_linux32-fixes-for-linuxppc64/)

* Fix uname for PER_LINUX32
* Inherit PER_LINUX32

Signed-off-by: Juergen Kreileder <jk@blackdown.de>

diff -urp linux-2.6.12-rc1-mm4/arch/ppc64/kernel/syscalls.c linux/arch/ppc64/kernel/syscalls.c
--- linux-2.6.12-rc1-mm4/arch/ppc64/kernel/syscalls.c	2005-04-01 21:19:44.000000000 +0200
+++ linux/arch/ppc64/kernel/syscalls.c	2005-04-01 19:07:36.000000000 +0200
@@ -210,14 +210,17 @@ __setup("fakeppc", set_fakeppc);
 
 asmlinkage int sys_uname(struct old_utsname __user * name)
 {
-	int err = -EFAULT;
-	
+	int err;
+	if (!name)
+		return -EFAULT;
+
 	down_read(&uts_sem);
-	if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
-		err = 0;
+	err = copy_to_user(name, &system_utsname, sizeof (*name));
 	up_read(&uts_sem);
+	if (personality(current->personality) == PER_LINUX32) 
+		err |= copy_to_user(&name->machine, "ppc", 4);
 	
-	return err;
+	return err ? - EFAULT : 0;
 }
 
 asmlinkage time_t sys64_time(time_t __user * tloc)
diff -urp linux-2.6.12-rc1-mm4/arch/ppc64/kernel/sys_ppc32.c linux/arch/ppc64/kernel/sys_ppc32.c
--- linux-2.6.12-rc1-mm4/arch/ppc64/kernel/sys_ppc32.c	2005-04-01 21:19:44.000000000 +0200
+++ linux/arch/ppc64/kernel/sys_ppc32.c	2005-04-01 19:50:05.000000000 +0200
@@ -793,20 +793,23 @@ asmlinkage int sys32_pciconfig_iobase(u3
 
 asmlinkage int ppc64_newuname(struct new_utsname __user * name)
 {
-	int errno = sys_newuname(name);
+	int err;
+	if (!name)
+		return -EFAULT;
 
-	if (current->personality == PER_LINUX32 && !errno) {
-		if(copy_to_user(name->machine, "ppc\0\0", 8)) {
-			errno = -EFAULT;
-		}
-	}
-	return errno;
+	down_read(&uts_sem);
+	err = copy_to_user(name, &system_utsname, sizeof (*name));
+	up_read(&uts_sem);
+	if (personality(current->personality) == PER_LINUX32) 
+		err |= copy_to_user(&name->machine, "ppc", 4);
+	return err ? -EFAULT : 0;
 }
 
 asmlinkage int ppc64_personality(unsigned long personality)
 {
 	int ret;
-	if (current->personality == PER_LINUX32 && personality == PER_LINUX)
+	if (personality(current->personality) == PER_LINUX32 &&
+	    personality == PER_LINUX)
 		personality = PER_LINUX32;
 	ret = sys_personality(personality);
 	if (ret == PER_LINUX32)
@@ -1176,8 +1179,13 @@ asmlinkage int sys32_olduname(struct old
 	error -= __put_user(0,name->release+__OLD_UTS_LEN);
 	error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
 	error -= __put_user(0,name->version+__OLD_UTS_LEN);
-	error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
-	error = __put_user(0,name->machine+__OLD_UTS_LEN);
+	{ 
+		char *arch = "ppc64";
+		if (personality(current->personality) == PER_LINUX32)
+			arch = "ppc";
+		 
+		__copy_to_user(&name->machine, arch, strlen(arch) + 1);
+	}
 	up_read(&uts_sem);
 
 	error = error ? -EFAULT : 0;
diff -urp linux-2.6.12-rc1-mm4/include/asm-ppc64/elf.h linux/include/asm-ppc64/elf.h
--- linux-2.6.12-rc1-mm4/include/asm-ppc64/elf.h	2005-04-01 21:19:29.000000000 +0200
+++ linux/include/asm-ppc64/elf.h	2005-04-01 21:01:16.000000000 +0200
@@ -211,20 +211,20 @@ extern int dump_task_fpu(struct task_str
 } while (0)
 
 #ifdef __KERNEL__
-#define SET_PERSONALITY(ex, ibcs2)				\
-do {								\
-	unsigned long new_flags = 0;				\
-	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
-		new_flags = _TIF_32BIT;				\
-	if ((current_thread_info()->flags & _TIF_32BIT)		\
-	    != new_flags)					\
-		set_thread_flag(TIF_ABI_PENDING);		\
-	else							\
-		clear_thread_flag(TIF_ABI_PENDING);		\
-	if (ibcs2)						\
-		set_personality(PER_SVR4);			\
-	else if (current->personality != PER_LINUX32)		\
-		set_personality(PER_LINUX);			\
+#define SET_PERSONALITY(ex, ibcs2)					\
+do {									\
+	unsigned long new_flags = 0;					\
+	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)			\
+		new_flags = _TIF_32BIT;					\
+	if ((current_thread_info()->flags & _TIF_32BIT)			\
+	    != new_flags)						\
+		set_thread_flag(TIF_ABI_PENDING);			\
+	else								\
+		clear_thread_flag(TIF_ABI_PENDING);			\
+	if (ibcs2)							\
+		set_personality(PER_SVR4);				\
+	else if (personality(current->personality) != PER_LINUX32)	\
+		set_personality(PER_LINUX);				\
 } while (0)
 
 /*
=
