diff mbox

[v3] powerpc32: provide VIRT_CPU_ACCOUNTING

Message ID 20160210145848.01F031A2446@localhost.localdomain (mailing list archive)
State Superseded
Headers show

Commit Message

Christophe Leroy Feb. 10, 2016, 2:58 p.m. UTC
This patch provides VIRT_CPU_ACCOUTING to PPC32 architecture.
PPC32 doesn't have the PACA structure, so we use the task_info
structure to store the accounting data.

In order to reuse on PPC32 the PPC64 functions, all u64 data has
been replaced by 'unsigned long' so that it is u32 on PPC32 and
u64 on PPC64

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
Changes in v3: unlike previous version of the patch that was inspired
from IA64 architecture, this new version tries to reuse as much as
possible the PPC64 implementation.

PPC32 doesn't have PACA and past discusion on v2 version has shown
that it is not worth implementing a PACA in PPC32 architecture
(see below benh opinion)

benh: PACA is actually a data structure and you really really don't want it
on ppc32 :-) Having a register point to current works, having a register
point to per-cpu data instead works too (ie, change what we do today),
but don't introduce a PACA *please* :-)

 arch/powerpc/Kconfig                   |  1 +
 arch/powerpc/include/asm/cputime.h     |  4 ++++
 arch/powerpc/include/asm/ppc_asm.h     | 31 ++++++++++++++++-----------
 arch/powerpc/include/asm/reg.h         |  1 +
 arch/powerpc/include/asm/thread_info.h | 11 ++++++++++
 arch/powerpc/kernel/asm-offsets.c      |  5 +++++
 arch/powerpc/kernel/entry_32.S         | 17 +++++++++++++++
 arch/powerpc/kernel/entry_64.S         |  6 +++---
 arch/powerpc/kernel/time.c             | 38 +++++++++++++++++++++++++++-------
 arch/powerpc/platforms/Kconfig.cputype |  1 -
 10 files changed, 92 insertions(+), 23 deletions(-)

Comments

kernel test robot Feb. 10, 2016, 4:13 p.m. UTC | #1
Hi Christophe,

[auto build test ERROR on powerpc/next]
[also build test ERROR on v4.5-rc3 next-20160210]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/Christophe-Leroy/powerpc32-provide-VIRT_CPU_ACCOUNTING/20160210-230049
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-defconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=powerpc 

All errors (new ones prefixed by >>):

   In file included from arch/powerpc/kernel/head_64.S:180:0:
>> arch/powerpc/kernel/exceptions-64s.S:776:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0x100, system_reset, system_reset_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:778:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ)
    ^
   arch/powerpc/kernel/exceptions-64s.S:779:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, timer_interrupt)
    ^
   arch/powerpc/kernel/exceptions-64s.S:780:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0x980, hdecrementer, hdec_interrupt)
    ^
   arch/powerpc/kernel/exceptions-64s.S:782:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, doorbell_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:786:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0xb00, trap_0b, unknown_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:787:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0xd00, single_step, single_step_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:788:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0xe00, trap_0e, unknown_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:789:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0xe40, emulation_assist, emulation_assist_interrupt)
    ^
   arch/powerpc/kernel/exceptions-64s.S:790:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON_ASYNC(0xe60, hmi_exception, handle_hmi_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:792:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, doorbell_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:796:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, performance_monitor_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:797:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, instruction_breakpoint_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:798:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0x1502, denorm, unknown_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:800:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0x1700, altivec_assist, altivec_assist_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:805:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0x1200, cbe_system_error, cbe_system_error_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:806:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, cbe_maintenance_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:807:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0x1800, cbe_thermal, cbe_thermal_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:980:43: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
                                              ^
   arch/powerpc/kernel/exceptions-64s.S:995:43: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN)
                                              ^
   arch/powerpc/kernel/exceptions-64s.S:1005:43: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
                                              ^
   arch/powerpc/kernel/exceptions-64s.S:1013:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0xe20, h_instr_storage, unknown_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:1091:42: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
                                             ^
   arch/powerpc/kernel/exceptions-64s.S:1110:43: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
                                              ^
   arch/powerpc/kernel/exceptions-64s.S:1124:43: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
                                              ^
   arch/powerpc/kernel/exceptions-64s.S:1134:43: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
                                              ^
   arch/powerpc/kernel/exceptions-64s.S:1164:43: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
                                              ^
   arch/powerpc/kernel/exceptions-64s.S:1199:43: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN)
                                              ^
   arch/powerpc/kernel/exceptions-64s.S:1230:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0xf60, facility_unavailable, facility_unavailable_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:1231:1: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     STD_EXCEPTION_COMMON(0xf80, hv_facility_unavailable, facility_unavailable_exception)
    ^
   arch/powerpc/kernel/exceptions-64s.S:1517:44: error: macro "ACCOUNT_CPU_USER_ENTRY" requires 3 arguments, but only 2 given
     EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
                                               ^

vim +/ACCOUNT_CPU_USER_ENTRY +776 arch/powerpc/kernel/exceptions-64s.S

61e2390ed Michael Neuling        2012-11-05  770   * which uses an ori instruction, these handlers must be in
61e2390ed Michael Neuling        2012-11-05  771   * the first 64k of the kernel image.
0ebc4cdaa Benjamin Herrenschmidt 2009-06-02  772   */
0ebc4cdaa Benjamin Herrenschmidt 2009-06-02  773  
0ebc4cdaa Benjamin Herrenschmidt 2009-06-02  774  /*** Common interrupt handlers ***/
0ebc4cdaa Benjamin Herrenschmidt 2009-06-02  775  
354255014 Anton Blanchard        2014-02-04 @776  	STD_EXCEPTION_COMMON(0x100, system_reset, system_reset_exception)
0ebc4cdaa Benjamin Herrenschmidt 2009-06-02  777  
7450f6f03 Benjamin Herrenschmidt 2012-03-01  778  	STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ)
354255014 Anton Blanchard        2014-02-04  779  	STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, timer_interrupt)

:::::: The code at line 776 was first introduced by commit
:::::: 354255014a9042b9204e5bed22704110326d5ecf powerpc: Remove dot symbol usage in exception macros

:::::: TO: Anton Blanchard <anton@samba.org>
:::::: CC: Anton Blanchard <anton@samba.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot Feb. 10, 2016, 4:20 p.m. UTC | #2
Hi Christophe,

[auto build test ERROR on powerpc/next]
[also build test ERROR on v4.5-rc3 next-20160210]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/Christophe-Leroy/powerpc32-provide-VIRT_CPU_ACCOUNTING/20160210-230049
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-allnoconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=powerpc 

All error/warnings (new ones prefixed by >>):

   In file included from arch/powerpc/kernel/asm-offsets.c:30:0:
   arch/powerpc/kernel/asm-offsets.c: In function 'main':
>> include/linux/compiler-gcc.h:158:2: error: 'struct thread_info' has no member named 'starttime'
     __builtin_offsetof(a, b)
     ^
   include/linux/kbuild.h:5:55: note: in definition of macro 'DEFINE'
            asm volatile("\n->" #sym " %0 " #val : : "i" (val))
                                                          ^
   include/linux/stddef.h:16:32: note: in expansion of macro '__compiler_offsetof'
    #define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)
                                   ^
>> arch/powerpc/kernel/asm-offsets.c:260:25: note: in expansion of macro 'offsetof'
     DEFINE(PACA_STARTTIME, offsetof(struct thread_info, starttime));
                            ^
>> include/linux/compiler-gcc.h:158:2: error: 'struct thread_info' has no member named 'starttime_user'
     __builtin_offsetof(a, b)
     ^
   include/linux/kbuild.h:5:55: note: in definition of macro 'DEFINE'
            asm volatile("\n->" #sym " %0 " #val : : "i" (val))
                                                          ^
   include/linux/stddef.h:16:32: note: in expansion of macro '__compiler_offsetof'
    #define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)
                                   ^
   arch/powerpc/kernel/asm-offsets.c:261:30: note: in expansion of macro 'offsetof'
     DEFINE(PACA_STARTTIME_USER, offsetof(struct thread_info, starttime_user));
                                 ^
>> include/linux/compiler-gcc.h:158:2: error: 'struct thread_info' has no member named 'user_time'
     __builtin_offsetof(a, b)
     ^
   include/linux/kbuild.h:5:55: note: in definition of macro 'DEFINE'
            asm volatile("\n->" #sym " %0 " #val : : "i" (val))
                                                          ^
   include/linux/stddef.h:16:32: note: in expansion of macro '__compiler_offsetof'
    #define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)
                                   ^
   arch/powerpc/kernel/asm-offsets.c:262:25: note: in expansion of macro 'offsetof'
     DEFINE(PACA_USER_TIME, offsetof(struct thread_info, user_time));
                            ^
>> include/linux/compiler-gcc.h:158:2: error: 'struct thread_info' has no member named 'system_time'
     __builtin_offsetof(a, b)
     ^
   include/linux/kbuild.h:5:55: note: in definition of macro 'DEFINE'
            asm volatile("\n->" #sym " %0 " #val : : "i" (val))
                                                          ^
   include/linux/stddef.h:16:32: note: in expansion of macro '__compiler_offsetof'
    #define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)
                                   ^
   arch/powerpc/kernel/asm-offsets.c:263:27: note: in expansion of macro 'offsetof'
     DEFINE(PACA_SYSTEM_TIME, offsetof(struct thread_info, system_time));
                              ^
   make[2]: *** [arch/powerpc/kernel/asm-offsets.s] Error 1
   make[2]: Target '__build' not remade because of errors.
   make[1]: *** [prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [sub-make] Error 2

vim +158 include/linux/compiler-gcc.h

cb984d10 Joe Perches 2015-06-25  152  #  error Your version of gcc miscompiles the __weak directive
cb984d10 Joe Perches 2015-06-25  153  # endif
cb984d10 Joe Perches 2015-06-25  154  #endif
cb984d10 Joe Perches 2015-06-25  155  
cb984d10 Joe Perches 2015-06-25  156  #define __used			__attribute__((__used__))
cb984d10 Joe Perches 2015-06-25  157  #define __compiler_offsetof(a, b)					\
cb984d10 Joe Perches 2015-06-25 @158  	__builtin_offsetof(a, b)
cb984d10 Joe Perches 2015-06-25  159  
cb984d10 Joe Perches 2015-06-25  160  #if GCC_VERSION >= 40100 && GCC_VERSION < 40600
cb984d10 Joe Perches 2015-06-25  161  # define __compiletime_object_size(obj) __builtin_object_size(obj, 0)

:::::: The code at line 158 was first introduced by commit
:::::: cb984d101b30eb7478d32df56a0023e4603cba7f compiler-gcc: integrate the various compiler-gcc[345].h files

:::::: TO: Joe Perches <joe@perches.com>
:::::: CC: Linus Torvalds <torvalds@linux-foundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox

Patch

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 3a557be..57ce4ff 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -159,6 +159,7 @@  config PPC
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select HAVE_ARCH_SECCOMP_FILTER
 	select ARCH_HAS_UBSAN_SANITIZE_ALL
+	select HAVE_VIRT_CPU_ACCOUNTING
 
 config GENERIC_CSUM
 	def_bool CPU_LITTLE_ENDIAN
diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h
index e245255..c4c33be 100644
--- a/arch/powerpc/include/asm/cputime.h
+++ b/arch/powerpc/include/asm/cputime.h
@@ -230,7 +230,11 @@  static inline cputime_t clock_t_to_cputime(const unsigned long clk)
 
 #define cputime64_to_clock_t(ct)	cputime_to_clock_t((cputime_t)(ct))
 
+#ifdef CONFIG_PPC64
 static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
+#else
+void arch_vtime_task_switch(struct task_struct *tsk);
+#endif
 
 #endif /* __KERNEL__ */
 #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 499d9f8..05b6738 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -24,27 +24,34 @@ 
  */
 
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
-#define ACCOUNT_CPU_USER_ENTRY(ra, rb)
-#define ACCOUNT_CPU_USER_EXIT(ra, rb)
+#define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb)
+#define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb)
 #define ACCOUNT_STOLEN_TIME
 #else
-#define ACCOUNT_CPU_USER_ENTRY(ra, rb)					\
+#ifdef CONFIG_PPC64
+#define AC_LD	ld
+#define AC_STD	std
+#else
+#define AC_LD	lwz
+#define AC_STD	stw
+#endif
+#define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb)				\
 	MFTB(ra);			/* get timebase */		\
-	ld	rb,PACA_STARTTIME_USER(r13);				\
-	std	ra,PACA_STARTTIME(r13);					\
+	AC_LD	rb, PACA_STARTTIME_USER(ptr);				\
+	AC_STD	ra, PACA_STARTTIME(ptr);				\
 	subf	rb,rb,ra;		/* subtract start value */	\
-	ld	ra,PACA_USER_TIME(r13);					\
+	AC_LD	ra, PACA_USER_TIME(ptr);				\
 	add	ra,ra,rb;		/* add on to user time */	\
-	std	ra,PACA_USER_TIME(r13);					\
+	AC_STD	ra, PACA_USER_TIME(ptr);				\
 
-#define ACCOUNT_CPU_USER_EXIT(ra, rb)					\
+#define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb)				\
 	MFTB(ra);			/* get timebase */		\
-	ld	rb,PACA_STARTTIME(r13);					\
-	std	ra,PACA_STARTTIME_USER(r13);				\
+	AC_LD	rb, PACA_STARTTIME(ptr);				\
+	AC_STD	ra, PACA_STARTTIME_USER(ptr);				\
 	subf	rb,rb,ra;		/* subtract start value */	\
-	ld	ra,PACA_SYSTEM_TIME(r13);				\
+	AC_LD	ra, PACA_SYSTEM_TIME(ptr);				\
 	add	ra,ra,rb;		/* add on to system time */	\
-	std	ra,PACA_SYSTEM_TIME(r13)
+	AC_STD	ra, PACA_SYSTEM_TIME(ptr)
 
 #ifdef CONFIG_PPC_SPLPAR
 #define ACCOUNT_STOLEN_TIME						\
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index c4cb2ff..ff6b591 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -1275,6 +1275,7 @@  static inline unsigned long mfvtb (void)
 			asm volatile("mfspr %0, %1" : "=r" (rval) : \
 				"i" (SPRN_TBRU)); rval;})
 #endif
+#define mftb()		mftbl()
 #endif /* !__powerpc64__ */
 
 #define mttbl(v)	asm volatile("mttbl %0":: "r"(v))
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index 7efee4a..4f19e96 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -44,6 +44,17 @@  struct thread_info {
 						   <0 => BUG */
 	unsigned long	local_flags;		/* private flags for thread */
 
+#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(CONFIG_PPC32)
+	/* Stuff for accurate time accounting */
+	unsigned long user_time;	/* accumulated usermode TB ticks */
+	unsigned long system_time;	/* accumulated system TB ticks */
+	unsigned long user_time_scaled;	/* accumulated usermode SPURR ticks */
+	unsigned long starttime;	/* TB value snapshot */
+	unsigned long starttime_user;	/* TB value on exit to usermode */
+	unsigned long startspurr;	/* SPURR value snapshot */
+	unsigned long utime_sspurr;	/* ->user_time when ->startspurr set */
+#endif
+
 	/* low level flags - has atomic operations done on it */
 	unsigned long	flags ____cacheline_aligned_in_smp;
 };
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 07cebc3..ea91dd8 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -256,6 +256,11 @@  int main(void)
 	DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
 	DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost));
 	DEFINE(PACA_SPRG_VDSO, offsetof(struct paca_struct, sprg_vdso));
+#else /* CONFIG_PPC64 */
+	DEFINE(PACA_STARTTIME, offsetof(struct thread_info, starttime));
+	DEFINE(PACA_STARTTIME_USER, offsetof(struct thread_info, starttime_user));
+	DEFINE(PACA_USER_TIME, offsetof(struct thread_info, user_time));
+	DEFINE(PACA_SYSTEM_TIME, offsetof(struct thread_info, system_time));
 #endif /* CONFIG_PPC64 */
 
 	/* RTAS */
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 2405631..9899032 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -175,6 +175,12 @@  transfer_to_handler:
 	addi	r12,r12,-1
 	stw	r12,4(r11)
 #endif
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+	CURRENT_THREAD_INFO(r9, r1)
+	tophys(r9, r9)
+	ACCOUNT_CPU_USER_ENTRY(r9, r11, r12)
+#endif
+
 	b	3f
 
 2:	/* if from kernel, check interrupted DOZE/NAP mode and
@@ -398,6 +404,13 @@  BEGIN_FTR_SECTION
 	lwarx	r7,0,r1
 END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
 	stwcx.	r0,0,r1			/* to clear the reservation */
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+	andi.	r4,r8,MSR_PR
+	beq	3f
+	CURRENT_THREAD_INFO(r4, r1)
+	ACCOUNT_CPU_USER_EXIT(r4, r5, r7)
+3:
+#endif
 	lwz	r4,_LINK(r1)
 	lwz	r5,_CCR(r1)
 	mtlr	r4
@@ -769,6 +782,10 @@  restore_user:
 	andis.	r10,r0,DBCR0_IDM@h
 	bnel-	load_dbcr0
 #endif
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+	CURRENT_THREAD_INFO(r9, r1)
+	ACCOUNT_CPU_USER_EXIT(r9, r10, r11)
+#endif
 
 	b	restore
 
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 0d525ce..d9bf82b 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -70,7 +70,7 @@  END_FTR_SECTION_IFSET(CPU_FTR_TM)
 	std	r0,GPR0(r1)
 	std	r10,GPR1(r1)
 	beq	2f			/* if from kernel mode */
-	ACCOUNT_CPU_USER_ENTRY(r10, r11)
+	ACCOUNT_CPU_USER_ENTRY(r13, r10, r11)
 2:	std	r2,GPR2(r1)
 	std	r3,GPR3(r1)
 	mfcr	r2
@@ -222,7 +222,7 @@  END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
 	ld	r4,_LINK(r1)
 
 	beq-	1f
-	ACCOUNT_CPU_USER_EXIT(r11, r12)
+	ACCOUNT_CPU_USER_EXIT(r13, r11, r12)
 
 BEGIN_FTR_SECTION
 	HMT_MEDIUM_LOW
@@ -822,7 +822,7 @@  END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
 BEGIN_FTR_SECTION
 	mtspr	SPRN_PPR,r2	/* Restore PPR */
 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
-	ACCOUNT_CPU_USER_EXIT(r2, r4)
+	ACCOUNT_CPU_USER_EXIT(r13, r2, r4)
 	REST_GPR(13, r1)
 1:
 	mtspr	SPRN_SRR1,r3
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 81b0900..6307b09 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -165,7 +165,13 @@  DEFINE_PER_CPU(unsigned long, cputime_scaled_last_delta);
 
 cputime_t cputime_one_jiffy;
 
+#ifdef CONFIG_PPC_SPLPAR
 void (*dtl_consumer)(struct dtl_entry *, u64);
+#endif
+
+#ifdef CONFIG_PPC32
+#define get_paca()	task_thread_info(tsk)
+#endif
 
 static void calc_cputime_factors(void)
 {
@@ -185,7 +191,7 @@  static void calc_cputime_factors(void)
  * Read the SPURR on systems that have it, otherwise the PURR,
  * or if that doesn't exist return the timebase value passed in.
  */
-static u64 read_spurr(u64 tb)
+static unsigned long read_spurr(unsigned long tb)
 {
 	if (cpu_has_feature(CPU_FTR_SPURR))
 		return mfspr(SPRN_SPURR);
@@ -294,11 +300,12 @@  static inline u64 calculate_stolen_time(u64 stop_tb)
  * Account time for a transition between system, hard irq
  * or soft irq state.
  */
-static u64 vtime_delta(struct task_struct *tsk,
-			u64 *sys_scaled, u64 *stolen)
+static unsigned long vtime_delta(struct task_struct *tsk,
+				 unsigned long *sys_scaled,
+				 unsigned long *stolen)
 {
-	u64 now, nowscaled, deltascaled;
-	u64 udelta, delta, user_scaled;
+	unsigned long now, nowscaled, deltascaled;
+	unsigned long udelta, delta, user_scaled;
 
 	WARN_ON_ONCE(!irqs_disabled());
 
@@ -343,7 +350,7 @@  static u64 vtime_delta(struct task_struct *tsk,
 
 void vtime_account_system(struct task_struct *tsk)
 {
-	u64 delta, sys_scaled, stolen;
+	unsigned long delta, sys_scaled, stolen;
 
 	delta = vtime_delta(tsk, &sys_scaled, &stolen);
 	account_system_time(tsk, 0, delta, sys_scaled);
@@ -354,7 +361,7 @@  EXPORT_SYMBOL_GPL(vtime_account_system);
 
 void vtime_account_idle(struct task_struct *tsk)
 {
-	u64 delta, sys_scaled, stolen;
+	unsigned long delta, sys_scaled, stolen;
 
 	delta = vtime_delta(tsk, &sys_scaled, &stolen);
 	account_idle_time(delta + stolen);
@@ -381,6 +388,23 @@  void vtime_account_user(struct task_struct *tsk)
 	account_user_time(tsk, utime, utimescaled);
 }
 
+#ifdef CONFIG_PPC32
+/*
+ * Called from the context switch with interrupts disabled, to charge all
+ * accumulated times to the current process, and to prepare accounting on
+ * the next process.
+ */
+void arch_vtime_task_switch(struct task_struct *prev)
+{
+	struct thread_info *pi = task_thread_info(prev);
+	struct thread_info *ni = task_thread_info(current);
+
+	ni->starttime = pi->starttime;
+	ni->system_time = 0;
+	ni->user_time = 0;
+}
+#endif /* CONFIG_PPC32 */
+
 #else /* ! CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
 #define calc_cputime_factors()
 #endif
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 142dff5..54b8043 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -1,7 +1,6 @@ 
 config PPC64
 	bool "64-bit kernel"
 	default n
-	select HAVE_VIRT_CPU_ACCOUNTING
 	select ZLIB_DEFLATE
 	help
 	  This option selects whether a 32-bit or a 64-bit kernel