From: Paul Mackerras <paulus@samba.org>

At present rtas_call() can be called before the kmalloc subsystem is
initialized, and if RTAS reports a hardware error, the code tries to do a
kmalloc to make a copy of the error report.  This patch changes it so that
we don't do the kmalloc in that situation.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/ppc64/kernel/rtas.c   |   12 ++++++++----
 25-akpm/include/asm-ppc64/system.h |    2 ++
 2 files changed, 10 insertions(+), 4 deletions(-)

diff -puN arch/ppc64/kernel/rtas.c~ppc64-rtas_call-was-calling-kmalloc-too-early arch/ppc64/kernel/rtas.c
--- 25/arch/ppc64/kernel/rtas.c~ppc64-rtas_call-was-calling-kmalloc-too-early	2004-08-18 22:55:48.391128656 -0700
+++ 25-akpm/arch/ppc64/kernel/rtas.c	2004-08-18 22:55:48.422123944 -0700
@@ -167,9 +167,12 @@ int rtas_call(int token, int nargs, int 
 
 	/* Log the error in the unlikely case that there was one. */
 	if (unlikely(logit)) {
-		buff_copy = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC);
-		if (buff_copy) {
-			memcpy(buff_copy, rtas_err_buf, RTAS_ERROR_LOG_MAX);
+		buff_copy = rtas_err_buf;
+		if (mem_init_done) {
+			buff_copy = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC);
+			if (buff_copy)
+				memcpy(buff_copy, rtas_err_buf,
+				       RTAS_ERROR_LOG_MAX);
 		}
 	}
 
@@ -178,7 +181,8 @@ int rtas_call(int token, int nargs, int 
 
 	if (buff_copy) {
 		log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0);
-		kfree(buff_copy);
+		if (mem_init_done)
+			kfree(buff_copy);
 	}
 	return ret;
 }
diff -puN include/asm-ppc64/system.h~ppc64-rtas_call-was-calling-kmalloc-too-early include/asm-ppc64/system.h
--- 25/include/asm-ppc64/system.h~ppc64-rtas_call-was-calling-kmalloc-too-early	2004-08-18 22:55:48.415125008 -0700
+++ 25-akpm/include/asm-ppc64/system.h	2004-08-18 22:55:48.424123640 -0700
@@ -128,6 +128,8 @@ static inline void flush_altivec_to_thre
 }
 #endif
 
+extern int mem_init_done;	/* set on boot once kmalloc can be called */
+
 /* EBCDIC -> ASCII conversion for [0-9A-Z] on iSeries */
 extern unsigned char e2a(unsigned char);
 
_