ppc64: merge binfmt_elf32.c

and use start_thread for both 32 and 64 bit bineries.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index f03f6d4f..adac749 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -11,6 +11,7 @@
 endif
 
 obj-y				:= semaphore.o cputable.o
+obj-$(CONFIG_PPC64)		+= binfmt_elf32.o
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
 obj-$(CONFIG_POWER4)		+= idle_power4.o
 
diff --git a/arch/powerpc/kernel/binfmt_elf32.c b/arch/powerpc/kernel/binfmt_elf32.c
new file mode 100644
index 0000000..8ad6b0f
--- /dev/null
+++ b/arch/powerpc/kernel/binfmt_elf32.c
@@ -0,0 +1,75 @@
+/*
+ * binfmt_elf32.c: Support 32-bit PPC ELF binaries on Power3 and followons.
+ * based on the SPARC64 version.
+ * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller	(davem@redhat.com)
+ * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek	(jj@ultra.linux.cz)
+ *
+ * Copyright (C) 2000,2001 Ken Aaker (kdaaker@rchland.vnet.ibm.com), IBM Corp
+ * Copyright (C) 2001 Anton Blanchard (anton@au.ibm.com), IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define ELF_ARCH		EM_PPC
+#define ELF_CLASS		ELFCLASS32
+#define ELF_DATA		ELFDATA2MSB;
+
+#include <asm/processor.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/elfcore.h>
+#include <linux/compat.h>
+
+#define elf_prstatus elf_prstatus32
+struct elf_prstatus32
+{
+	struct elf_siginfo pr_info;	/* Info associated with signal */
+	short	pr_cursig;		/* Current signal */
+	unsigned int pr_sigpend;	/* Set of pending signals */
+	unsigned int pr_sighold;	/* Set of held signals */
+	pid_t	pr_pid;
+	pid_t	pr_ppid;
+	pid_t	pr_pgrp;
+	pid_t	pr_sid;
+	struct compat_timeval pr_utime;	/* User time */
+	struct compat_timeval pr_stime;	/* System time */
+	struct compat_timeval pr_cutime;	/* Cumulative user time */
+	struct compat_timeval pr_cstime;	/* Cumulative system time */
+	elf_gregset_t pr_reg;		/* General purpose registers. */
+	int pr_fpvalid;		/* True if math co-processor being used. */
+};
+
+#define elf_prpsinfo elf_prpsinfo32
+struct elf_prpsinfo32
+{
+	char	pr_state;	/* numeric process state */
+	char	pr_sname;	/* char for pr_state */
+	char	pr_zomb;	/* zombie */
+	char	pr_nice;	/* nice val */
+	unsigned int pr_flag;	/* flags */
+	u32	pr_uid;
+	u32	pr_gid;
+	pid_t	pr_pid, pr_ppid, pr_pgrp, pr_sid;
+	/* Lots missing */
+	char	pr_fname[16];	/* filename of executable */
+	char	pr_psargs[ELF_PRARGSZ];	/* initial part of arg list */
+};
+
+#include <linux/time.h>
+
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
+static __inline__ void
+cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
+{
+	unsigned long jiffies = cputime_to_jiffies(cputime);
+	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
+	value->tv_sec = jiffies / HZ;
+}
+
+#define init_elf_binfmt init_elf32_binfmt
+
+#include "../../../fs/binfmt_elf.c"
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 92bc75f..193c8c1 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -620,7 +620,7 @@
 	regs->nip = start;
 	regs->msr = MSR_USER;
 #else
-	{
+	if (!test_thread_flag(TIF_32BIT)) {
 		unsigned long entry, toc, load_addr = regs->gpr[2];
 
 		/* start is a relocated pointer to the function descriptor for
@@ -641,6 +641,10 @@
 		regs->nip = entry;
 		regs->gpr[2] = toc;
 		regs->msr = MSR_USER64;
+	} else {
+		regs->nip = start;
+		regs->gpr[2] = 0;
+		regs->msr = MSR_USER32;
 	}
 #endif