From: Haren Myneni <haren@us.ibm.com>
Subject: powerpc: Move branch instruction from ACCOUNT_CPU_USER_ENTRY to caller
Git-commit: 5d75b26443aff37a7bd356f9dbd6d6e11ec122aa
Patch-mainline: yes
References: bnc#795905,fate#314033 

The first instruction in ACCOUNT_CPU_USER_ENTRY is 'beq' which checks for
exceptions coming from kernel mode. PPR value will be saved immediately after
ACCOUNT_CPU_USER_ENTRY and is also for user level exceptions. So moved this
branch instruction in the caller code.

Signed-off-by: Haren Myneni <haren@us.ibm.com>
Acked-by: Torsten Duwe <duwe@suse.de>

diff -Naurp linux.orig/arch/powerpc/include/asm/exception-64s.h linux1/arch/powerpc/include/asm/exception-64s.h
--- linux.orig/arch/powerpc/include/asm/exception-64s.h	2012-12-21 20:24:40.000000000 -0800
+++ linux1/arch/powerpc/include/asm/exception-64s.h	2012-12-21 23:15:19.000000000 -0800
@@ -121,8 +121,9 @@
 	std	r10,0(r1);		/* make stack chain pointer	*/ \
 	std	r0,GPR0(r1);		/* save r0 in stackframe	*/ \
 	std	r10,GPR1(r1);		/* save r1 in stackframe	*/ \
+	beq	4f;			/* if from kernel mode		*/ \
 	ACCOUNT_CPU_USER_ENTRY(r9, r10);				   \
-	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \
+4:	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \
 	SAVE_4GPRS(3, r1);		/* save r3 - r6 in stackframe	*/ \
 	SAVE_2GPRS(7, r1);		/* save r7, r8 in stackframe	*/ \
 	ld	r9,area+EX_R9(r13);	/* move r9, r10 to stackframe	*/ \
diff -Naurp linux.orig/arch/powerpc/include/asm/ppc_asm.h linux1/arch/powerpc/include/asm/ppc_asm.h
--- linux.orig/arch/powerpc/include/asm/ppc_asm.h	2012-12-21 20:24:40.000000000 -0800
+++ linux1/arch/powerpc/include/asm/ppc_asm.h	2012-12-21 23:16:25.000000000 -0800
@@ -30,7 +30,6 @@
 #define ACCOUNT_STOLEN_TIME
 #else
 #define ACCOUNT_CPU_USER_ENTRY(ra, rb)					\
-	beq	2f;			/* if from kernel mode */	\
 	MFTB(ra);			/* get timebase */		\
 	ld	rb,PACA_STARTTIME_USER(r13);				\
 	std	ra,PACA_STARTTIME(r13);					\
@@ -38,7 +37,6 @@
 	ld	ra,PACA_USER_TIME(r13);					\
 	add	ra,ra,rb;		/* add on to user time */	\
 	std	ra,PACA_USER_TIME(r13);					\
-2:
 
 #define ACCOUNT_CPU_USER_EXIT(ra, rb)					\
 	MFTB(ra);			/* get timebase */		\
diff -Naurp linux.orig/arch/powerpc/kernel/entry_64.S linux1/arch/powerpc/kernel/entry_64.S
--- linux.orig/arch/powerpc/kernel/entry_64.S	2012-12-21 20:24:40.000000000 -0800
+++ linux1/arch/powerpc/kernel/entry_64.S	2012-12-21 23:17:24.000000000 -0800
@@ -61,6 +61,7 @@ system_call_common:
 	std	r12,_MSR(r1)
 	std	r0,GPR0(r1)
 	std	r10,GPR1(r1)
+	beq	2f			/* if from kernel mode */
 	ACCOUNT_CPU_USER_ENTRY(r10, r11)
 	/*
 	 * This "crclr so" clears CR0.SO, which is the error indication on
@@ -68,7 +69,7 @@ system_call_common:
 	 * between it and the "mfcr r9" below, otherwise if XER.SO is set,
 	 * CR0.SO will get set, causing all system calls to appear to fail.
 	 */
-	crclr	so
+2:	crclr	so
 	std	r2,GPR2(r1)
 	std	r3,GPR3(r1)
 	std	r4,GPR4(r1)
diff -Naurp linux.orig/arch/powerpc/kernel/exceptions-64e.S linux1/arch/powerpc/kernel/exceptions-64e.S
--- linux.orig/arch/powerpc/kernel/exceptions-64e.S	2012-12-21 20:24:40.000000000 -0800
+++ linux1/arch/powerpc/kernel/exceptions-64e.S	2012-12-21 23:18:20.000000000 -0800
@@ -131,8 +131,9 @@
 	std	r9,GPR9(r1);		/* save r9 in stackframe */	    \
 	std	r10,_NIP(r1);		/* save SRR0 to stackframe */	    \
 	std	r11,_MSR(r1);		/* save SRR1 to stackframe */	    \
+	beq	2f;			/* if from kernel mode */	    \
 	ACCOUNT_CPU_USER_ENTRY(r10,r11);/* accounting (uses cr0+eq) */	    \
-	ld	r3,excf+EX_R10(r13);	/* get back r10 */		    \
+2:	ld	r3,excf+EX_R10(r13);	/* get back r10 */		    \
 	ld	r4,excf+EX_R11(r13);	/* get back r11 */		    \
 	mfspr	r5,SPRN_SPRG_GEN_SCRATCH;/* get back r13 */		    \
 	std	r12,GPR12(r1);		/* save r12 in stackframe */	    \
