aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorChristophe Leroy <christophe.leroy@c-s.fr>2016-05-17 02:33:46 -0400
committerScott Wood <oss@buserror.net>2016-07-09 02:43:50 -0400
commitc223c90386bc2306510e0ceacd768a0123ff2a2f (patch)
tree520a7bc88a7e36bbd0615cc5a035337a36729fb8 /arch/powerpc
parent1afbf61750364864adf6a17818c5bbbea4dea531 (diff)
powerpc32: provide VIRT_CPU_ACCOUNTING
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> Signed-off-by: Scott Wood <oss@buserror.net>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Kconfig1
-rw-r--r--arch/powerpc/include/asm/accounting.h24
-rw-r--r--arch/powerpc/include/asm/cputime.h14
-rw-r--r--arch/powerpc/include/asm/exception-64s.h2
-rw-r--r--arch/powerpc/include/asm/paca.h9
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h24
-rw-r--r--arch/powerpc/include/asm/reg.h1
-rw-r--r--arch/powerpc/include/asm/thread_info.h4
-rw-r--r--arch/powerpc/kernel/asm-offsets.c23
-rw-r--r--arch/powerpc/kernel/entry_32.S17
-rw-r--r--arch/powerpc/kernel/entry_64.S6
-rw-r--r--arch/powerpc/kernel/exceptions-64e.S4
-rw-r--r--arch/powerpc/kernel/time.c81
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype1
-rw-r--r--arch/powerpc/xmon/xmon.c14
15 files changed, 158 insertions, 67 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index ee82f9a09a85..394f9dc7be08 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -165,6 +165,7 @@ config PPC
165 select ARCH_HAS_UBSAN_SANITIZE_ALL 165 select ARCH_HAS_UBSAN_SANITIZE_ALL
166 select ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT 166 select ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT
167 select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS 167 select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS
168 select HAVE_VIRT_CPU_ACCOUNTING
168 169
169config GENERIC_CSUM 170config GENERIC_CSUM
170 def_bool CPU_LITTLE_ENDIAN 171 def_bool CPU_LITTLE_ENDIAN
diff --git a/arch/powerpc/include/asm/accounting.h b/arch/powerpc/include/asm/accounting.h
new file mode 100644
index 000000000000..c133246df467
--- /dev/null
+++ b/arch/powerpc/include/asm/accounting.h
@@ -0,0 +1,24 @@
1/*
2 * Common time accounting prototypes and such for all ppc machines.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#ifndef __POWERPC_ACCOUNTING_H
11#define __POWERPC_ACCOUNTING_H
12
13/* Stuff for accurate time accounting */
14struct cpu_accounting_data {
15 unsigned long user_time; /* accumulated usermode TB ticks */
16 unsigned long system_time; /* accumulated system TB ticks */
17 unsigned long user_time_scaled; /* accumulated usermode SPURR ticks */
18 unsigned long starttime; /* TB value snapshot */
19 unsigned long starttime_user; /* TB value on exit to usermode */
20 unsigned long startspurr; /* SPURR value snapshot */
21 unsigned long utime_sspurr; /* ->user_time when ->startspurr set */
22};
23
24#endif
diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h
index e2452550bcb1..2dfd4fc41f3e 100644
--- a/arch/powerpc/include/asm/cputime.h
+++ b/arch/powerpc/include/asm/cputime.h
@@ -90,11 +90,10 @@ static inline void setup_cputime_one_jiffy(void)
90static inline cputime64_t jiffies64_to_cputime64(const u64 jif) 90static inline cputime64_t jiffies64_to_cputime64(const u64 jif)
91{ 91{
92 u64 ct; 92 u64 ct;
93 u64 sec; 93 u64 sec = jif;
94 94
95 /* have to be a little careful about overflow */ 95 /* have to be a little careful about overflow */
96 ct = jif % HZ; 96 ct = do_div(sec, HZ);
97 sec = jif / HZ;
98 if (ct) { 97 if (ct) {
99 ct *= tb_ticks_per_sec; 98 ct *= tb_ticks_per_sec;
100 do_div(ct, HZ); 99 do_div(ct, HZ);
@@ -230,7 +229,16 @@ static inline cputime_t clock_t_to_cputime(const unsigned long clk)
230 229
231#define cputime64_to_clock_t(ct) cputime_to_clock_t((cputime_t)(ct)) 230#define cputime64_to_clock_t(ct) cputime_to_clock_t((cputime_t)(ct))
232 231
232/*
233 * PPC64 uses PACA which is task independent for storing accounting data while
234 * PPC32 uses struct thread_info, therefore at task switch the accounting data
235 * has to be populated in the new task
236 */
237#ifdef CONFIG_PPC64
233static inline void arch_vtime_task_switch(struct task_struct *tsk) { } 238static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
239#else
240void arch_vtime_task_switch(struct task_struct *tsk);
241#endif
234 242
235#endif /* __KERNEL__ */ 243#endif /* __KERNEL__ */
236#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ 244#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 93ae809fe5ea..8bc38d179c36 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -287,7 +287,7 @@ do_kvm_##n: \
287 std r0,GPR0(r1); /* save r0 in stackframe */ \ 287 std r0,GPR0(r1); /* save r0 in stackframe */ \
288 std r10,GPR1(r1); /* save r1 in stackframe */ \ 288 std r10,GPR1(r1); /* save r1 in stackframe */ \
289 beq 4f; /* if from kernel mode */ \ 289 beq 4f; /* if from kernel mode */ \
290 ACCOUNT_CPU_USER_ENTRY(r9, r10); \ 290 ACCOUNT_CPU_USER_ENTRY(r13, r9, r10); \
291 SAVE_PPR(area, r9, r10); \ 291 SAVE_PPR(area, r9, r10); \
2924: EXCEPTION_PROLOG_COMMON_2(area) \ 2924: EXCEPTION_PROLOG_COMMON_2(area) \
293 EXCEPTION_PROLOG_COMMON_3(n) \ 293 EXCEPTION_PROLOG_COMMON_3(n) \
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 546540b91095..ad171e979ab0 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -25,6 +25,7 @@
25#ifdef CONFIG_KVM_BOOK3S_64_HANDLER 25#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
26#include <asm/kvm_book3s_asm.h> 26#include <asm/kvm_book3s_asm.h>
27#endif 27#endif
28#include <asm/accounting.h>
28 29
29register struct paca_struct *local_paca asm("r13"); 30register struct paca_struct *local_paca asm("r13");
30 31
@@ -184,13 +185,7 @@ struct paca_struct {
184#endif 185#endif
185 186
186 /* Stuff for accurate time accounting */ 187 /* Stuff for accurate time accounting */
187 u64 user_time; /* accumulated usermode TB ticks */ 188 struct cpu_accounting_data accounting;
188 u64 system_time; /* accumulated system TB ticks */
189 u64 user_time_scaled; /* accumulated usermode SPURR ticks */
190 u64 starttime; /* TB value snapshot */
191 u64 starttime_user; /* TB value on exit to usermode */
192 u64 startspurr; /* SPURR value snapshot */
193 u64 utime_sspurr; /* ->user_time when ->startspurr set */
194 u64 stolen_time; /* TB ticks taken by hypervisor */ 189 u64 stolen_time; /* TB ticks taken by hypervisor */
195 u64 dtl_ridx; /* read index in dispatch log */ 190 u64 dtl_ridx; /* read index in dispatch log */
196 struct dtl_entry *dtl_curr; /* pointer corresponding to dtl_ridx */ 191 struct dtl_entry *dtl_curr; /* pointer corresponding to dtl_ridx */
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 7b591f98edcc..96b06dc93b4c 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -24,27 +24,27 @@
24 */ 24 */
25 25
26#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE 26#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
27#define ACCOUNT_CPU_USER_ENTRY(ra, rb) 27#define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb)
28#define ACCOUNT_CPU_USER_EXIT(ra, rb) 28#define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb)
29#define ACCOUNT_STOLEN_TIME 29#define ACCOUNT_STOLEN_TIME
30#else 30#else
31#define ACCOUNT_CPU_USER_ENTRY(ra, rb) \ 31#define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb) \
32 MFTB(ra); /* get timebase */ \ 32 MFTB(ra); /* get timebase */ \
33 ld rb,PACA_STARTTIME_USER(r13); \ 33 PPC_LL rb, ACCOUNT_STARTTIME_USER(ptr); \
34 std ra,PACA_STARTTIME(r13); \ 34 PPC_STL ra, ACCOUNT_STARTTIME(ptr); \
35 subf rb,rb,ra; /* subtract start value */ \ 35 subf rb,rb,ra; /* subtract start value */ \
36 ld ra,PACA_USER_TIME(r13); \ 36 PPC_LL ra, ACCOUNT_USER_TIME(ptr); \
37 add ra,ra,rb; /* add on to user time */ \ 37 add ra,ra,rb; /* add on to user time */ \
38 std ra,PACA_USER_TIME(r13); \ 38 PPC_STL ra, ACCOUNT_USER_TIME(ptr); \
39 39
40#define ACCOUNT_CPU_USER_EXIT(ra, rb) \ 40#define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb) \
41 MFTB(ra); /* get timebase */ \ 41 MFTB(ra); /* get timebase */ \
42 ld rb,PACA_STARTTIME(r13); \ 42 PPC_LL rb, ACCOUNT_STARTTIME(ptr); \
43 std ra,PACA_STARTTIME_USER(r13); \ 43 PPC_STL ra, ACCOUNT_STARTTIME_USER(ptr); \
44 subf rb,rb,ra; /* subtract start value */ \ 44 subf rb,rb,ra; /* subtract start value */ \
45 ld ra,PACA_SYSTEM_TIME(r13); \ 45 PPC_LL ra, ACCOUNT_SYSTEM_TIME(ptr); \
46 add ra,ra,rb; /* add on to system time */ \ 46 add ra,ra,rb; /* add on to system time */ \
47 std ra,PACA_SYSTEM_TIME(r13) 47 PPC_STL ra, ACCOUNT_SYSTEM_TIME(ptr)
48 48
49#ifdef CONFIG_PPC_SPLPAR 49#ifdef CONFIG_PPC_SPLPAR
50#define ACCOUNT_STOLEN_TIME \ 50#define ACCOUNT_STOLEN_TIME \
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 320136f5fe28..d383f13b9fac 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -1294,6 +1294,7 @@ static inline unsigned long mfvtb (void)
1294 asm volatile("mfspr %0, %1" : "=r" (rval) : \ 1294 asm volatile("mfspr %0, %1" : "=r" (rval) : \
1295 "i" (SPRN_TBRU)); rval;}) 1295 "i" (SPRN_TBRU)); rval;})
1296#endif 1296#endif
1297#define mftb() mftbl()
1297#endif /* !__powerpc64__ */ 1298#endif /* !__powerpc64__ */
1298 1299
1299#define mttbl(v) asm volatile("mttbl %0":: "r"(v)) 1300#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 8febc3f66d53..b21bb1f72314 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -33,6 +33,7 @@
33#include <asm/processor.h> 33#include <asm/processor.h>
34#include <asm/page.h> 34#include <asm/page.h>
35#include <linux/stringify.h> 35#include <linux/stringify.h>
36#include <asm/accounting.h>
36 37
37/* 38/*
38 * low level task data. 39 * low level task data.
@@ -46,6 +47,9 @@ struct thread_info {
46#ifdef CONFIG_LIVEPATCH 47#ifdef CONFIG_LIVEPATCH
47 unsigned long *livepatch_sp; 48 unsigned long *livepatch_sp;
48#endif 49#endif
50#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(CONFIG_PPC32)
51 struct cpu_accounting_data accounting;
52#endif
49 /* low level flags - has atomic operations done on it */ 53 /* low level flags - has atomic operations done on it */
50 unsigned long flags ____cacheline_aligned_in_smp; 54 unsigned long flags ____cacheline_aligned_in_smp;
51}; 55};
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 5b99f956e32f..047892869257 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -240,13 +240,28 @@ int main(void)
240 DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); 240 DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
241 DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state)); 241 DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
242 DEFINE(PACA_DSCR_DEFAULT, offsetof(struct paca_struct, dscr_default)); 242 DEFINE(PACA_DSCR_DEFAULT, offsetof(struct paca_struct, dscr_default));
243 DEFINE(PACA_STARTTIME, offsetof(struct paca_struct, starttime)); 243 DEFINE(ACCOUNT_STARTTIME,
244 DEFINE(PACA_STARTTIME_USER, offsetof(struct paca_struct, starttime_user)); 244 offsetof(struct paca_struct, accounting.starttime));
245 DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); 245 DEFINE(ACCOUNT_STARTTIME_USER,
246 DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); 246 offsetof(struct paca_struct, accounting.starttime_user));
247 DEFINE(ACCOUNT_USER_TIME,
248 offsetof(struct paca_struct, accounting.user_time));
249 DEFINE(ACCOUNT_SYSTEM_TIME,
250 offsetof(struct paca_struct, accounting.system_time));
247 DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save)); 251 DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
248 DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost)); 252 DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost));
249 DEFINE(PACA_SPRG_VDSO, offsetof(struct paca_struct, sprg_vdso)); 253 DEFINE(PACA_SPRG_VDSO, offsetof(struct paca_struct, sprg_vdso));
254#else /* CONFIG_PPC64 */
255#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
256 DEFINE(ACCOUNT_STARTTIME,
257 offsetof(struct thread_info, accounting.starttime));
258 DEFINE(ACCOUNT_STARTTIME_USER,
259 offsetof(struct thread_info, accounting.starttime_user));
260 DEFINE(ACCOUNT_USER_TIME,
261 offsetof(struct thread_info, accounting.user_time));
262 DEFINE(ACCOUNT_SYSTEM_TIME,
263 offsetof(struct thread_info, accounting.system_time));
264#endif
250#endif /* CONFIG_PPC64 */ 265#endif /* CONFIG_PPC64 */
251 266
252 /* RTAS */ 267 /* RTAS */
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 2405631e91a2..9899032230b4 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -175,6 +175,12 @@ transfer_to_handler:
175 addi r12,r12,-1 175 addi r12,r12,-1
176 stw r12,4(r11) 176 stw r12,4(r11)
177#endif 177#endif
178#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
179 CURRENT_THREAD_INFO(r9, r1)
180 tophys(r9, r9)
181 ACCOUNT_CPU_USER_ENTRY(r9, r11, r12)
182#endif
183
178 b 3f 184 b 3f
179 185
1802: /* if from kernel, check interrupted DOZE/NAP mode and 1862: /* if from kernel, check interrupted DOZE/NAP mode and
@@ -398,6 +404,13 @@ BEGIN_FTR_SECTION
398 lwarx r7,0,r1 404 lwarx r7,0,r1
399END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) 405END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
400 stwcx. r0,0,r1 /* to clear the reservation */ 406 stwcx. r0,0,r1 /* to clear the reservation */
407#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
408 andi. r4,r8,MSR_PR
409 beq 3f
410 CURRENT_THREAD_INFO(r4, r1)
411 ACCOUNT_CPU_USER_EXIT(r4, r5, r7)
4123:
413#endif
401 lwz r4,_LINK(r1) 414 lwz r4,_LINK(r1)
402 lwz r5,_CCR(r1) 415 lwz r5,_CCR(r1)
403 mtlr r4 416 mtlr r4
@@ -769,6 +782,10 @@ restore_user:
769 andis. r10,r0,DBCR0_IDM@h 782 andis. r10,r0,DBCR0_IDM@h
770 bnel- load_dbcr0 783 bnel- load_dbcr0
771#endif 784#endif
785#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
786 CURRENT_THREAD_INFO(r9, r1)
787 ACCOUNT_CPU_USER_EXIT(r9, r10, r11)
788#endif
772 789
773 b restore 790 b restore
774 791
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2e0c565754aa..fcb2887f5a33 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -72,7 +72,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
72 std r0,GPR0(r1) 72 std r0,GPR0(r1)
73 std r10,GPR1(r1) 73 std r10,GPR1(r1)
74 beq 2f /* if from kernel mode */ 74 beq 2f /* if from kernel mode */
75 ACCOUNT_CPU_USER_ENTRY(r10, r11) 75 ACCOUNT_CPU_USER_ENTRY(r13, r10, r11)
762: std r2,GPR2(r1) 762: std r2,GPR2(r1)
77 std r3,GPR3(r1) 77 std r3,GPR3(r1)
78 mfcr r2 78 mfcr r2
@@ -246,7 +246,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
246 ld r4,_LINK(r1) 246 ld r4,_LINK(r1)
247 247
248 beq- 1f 248 beq- 1f
249 ACCOUNT_CPU_USER_EXIT(r11, r12) 249 ACCOUNT_CPU_USER_EXIT(r13, r11, r12)
250 250
251BEGIN_FTR_SECTION 251BEGIN_FTR_SECTION
252 HMT_MEDIUM_LOW 252 HMT_MEDIUM_LOW
@@ -859,7 +859,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
859BEGIN_FTR_SECTION 859BEGIN_FTR_SECTION
860 mtspr SPRN_PPR,r2 /* Restore PPR */ 860 mtspr SPRN_PPR,r2 /* Restore PPR */
861END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) 861END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
862 ACCOUNT_CPU_USER_EXIT(r2, r4) 862 ACCOUNT_CPU_USER_EXIT(r13, r2, r4)
863 REST_GPR(13, r1) 863 REST_GPR(13, r1)
8641: 8641:
865 mtspr SPRN_SRR1,r3 865 mtspr SPRN_SRR1,r3
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 2d3b40fd9bac..38a1f96430e1 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -386,7 +386,7 @@ exc_##n##_common: \
386 std r10,_NIP(r1); /* save SRR0 to stackframe */ \ 386 std r10,_NIP(r1); /* save SRR0 to stackframe */ \
387 std r11,_MSR(r1); /* save SRR1 to stackframe */ \ 387 std r11,_MSR(r1); /* save SRR1 to stackframe */ \
388 beq 2f; /* if from kernel mode */ \ 388 beq 2f; /* if from kernel mode */ \
389 ACCOUNT_CPU_USER_ENTRY(r10,r11);/* accounting (uses cr0+eq) */ \ 389 ACCOUNT_CPU_USER_ENTRY(r13,r10,r11);/* accounting (uses cr0+eq) */ \
3902: ld r3,excf+EX_R10(r13); /* get back r10 */ \ 3902: ld r3,excf+EX_R10(r13); /* get back r10 */ \
391 ld r4,excf+EX_R11(r13); /* get back r11 */ \ 391 ld r4,excf+EX_R11(r13); /* get back r11 */ \
392 mfspr r5,scratch; /* get back r13 */ \ 392 mfspr r5,scratch; /* get back r13 */ \
@@ -1059,7 +1059,7 @@ fast_exception_return:
1059 andi. r6,r10,MSR_PR 1059 andi. r6,r10,MSR_PR
1060 REST_2GPRS(6, r1) 1060 REST_2GPRS(6, r1)
1061 beq 1f 1061 beq 1f
1062 ACCOUNT_CPU_USER_EXIT(r10, r11) 1062 ACCOUNT_CPU_USER_EXIT(r13, r10, r11)
1063 ld r0,GPR13(r1) 1063 ld r0,GPR13(r1)
1064 1064
10651: stdcx. r0,0,r1 /* to clear the reservation */ 10651: stdcx. r0,0,r1 /* to clear the reservation */
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 6b4d01d1ccf0..4e7759c8ca30 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -167,7 +167,15 @@ DEFINE_PER_CPU(unsigned long, cputime_scaled_last_delta);
167 167
168cputime_t cputime_one_jiffy; 168cputime_t cputime_one_jiffy;
169 169
170#ifdef CONFIG_PPC_SPLPAR
170void (*dtl_consumer)(struct dtl_entry *, u64); 171void (*dtl_consumer)(struct dtl_entry *, u64);
172#endif
173
174#ifdef CONFIG_PPC64
175#define get_accounting(tsk) (&get_paca()->accounting)
176#else
177#define get_accounting(tsk) (&task_thread_info(tsk)->accounting)
178#endif
171 179
172static void calc_cputime_factors(void) 180static void calc_cputime_factors(void)
173{ 181{
@@ -187,7 +195,7 @@ static void calc_cputime_factors(void)
187 * Read the SPURR on systems that have it, otherwise the PURR, 195 * Read the SPURR on systems that have it, otherwise the PURR,
188 * or if that doesn't exist return the timebase value passed in. 196 * or if that doesn't exist return the timebase value passed in.
189 */ 197 */
190static u64 read_spurr(u64 tb) 198static unsigned long read_spurr(unsigned long tb)
191{ 199{
192 if (cpu_has_feature(CPU_FTR_SPURR)) 200 if (cpu_has_feature(CPU_FTR_SPURR))
193 return mfspr(SPRN_SPURR); 201 return mfspr(SPRN_SPURR);
@@ -250,8 +258,8 @@ static u64 scan_dispatch_log(u64 stop_tb)
250void accumulate_stolen_time(void) 258void accumulate_stolen_time(void)
251{ 259{
252 u64 sst, ust; 260 u64 sst, ust;
253
254 u8 save_soft_enabled = local_paca->soft_enabled; 261 u8 save_soft_enabled = local_paca->soft_enabled;
262 struct cpu_accounting_data *acct = &local_paca->accounting;
255 263
256 /* We are called early in the exception entry, before 264 /* We are called early in the exception entry, before
257 * soft/hard_enabled are sync'ed to the expected state 265 * soft/hard_enabled are sync'ed to the expected state
@@ -261,10 +269,10 @@ void accumulate_stolen_time(void)
261 */ 269 */
262 local_paca->soft_enabled = 0; 270 local_paca->soft_enabled = 0;
263 271
264 sst = scan_dispatch_log(local_paca->starttime_user); 272 sst = scan_dispatch_log(acct->starttime_user);
265 ust = scan_dispatch_log(local_paca->starttime); 273 ust = scan_dispatch_log(acct->starttime);
266 local_paca->system_time -= sst; 274 acct->system_time -= sst;
267 local_paca->user_time -= ust; 275 acct->user_time -= ust;
268 local_paca->stolen_time += ust + sst; 276 local_paca->stolen_time += ust + sst;
269 277
270 local_paca->soft_enabled = save_soft_enabled; 278 local_paca->soft_enabled = save_soft_enabled;
@@ -276,7 +284,7 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
276 284
277 if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx)) { 285 if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx)) {
278 stolen = scan_dispatch_log(stop_tb); 286 stolen = scan_dispatch_log(stop_tb);
279 get_paca()->system_time -= stolen; 287 get_paca()->accounting.system_time -= stolen;
280 } 288 }
281 289
282 stolen += get_paca()->stolen_time; 290 stolen += get_paca()->stolen_time;
@@ -296,27 +304,29 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
296 * Account time for a transition between system, hard irq 304 * Account time for a transition between system, hard irq
297 * or soft irq state. 305 * or soft irq state.
298 */ 306 */
299static u64 vtime_delta(struct task_struct *tsk, 307static unsigned long vtime_delta(struct task_struct *tsk,
300 u64 *sys_scaled, u64 *stolen) 308 unsigned long *sys_scaled,
309 unsigned long *stolen)
301{ 310{
302 u64 now, nowscaled, deltascaled; 311 unsigned long now, nowscaled, deltascaled;
303 u64 udelta, delta, user_scaled; 312 unsigned long udelta, delta, user_scaled;
313 struct cpu_accounting_data *acct = get_accounting(tsk);
304 314
305 WARN_ON_ONCE(!irqs_disabled()); 315 WARN_ON_ONCE(!irqs_disabled());
306 316
307 now = mftb(); 317 now = mftb();
308 nowscaled = read_spurr(now); 318 nowscaled = read_spurr(now);
309 get_paca()->system_time += now - get_paca()->starttime; 319 acct->system_time += now - acct->starttime;
310 get_paca()->starttime = now; 320 acct->starttime = now;
311 deltascaled = nowscaled - get_paca()->startspurr; 321 deltascaled = nowscaled - acct->startspurr;
312 get_paca()->startspurr = nowscaled; 322 acct->startspurr = nowscaled;
313 323
314 *stolen = calculate_stolen_time(now); 324 *stolen = calculate_stolen_time(now);
315 325
316 delta = get_paca()->system_time; 326 delta = acct->system_time;
317 get_paca()->system_time = 0; 327 acct->system_time = 0;
318 udelta = get_paca()->user_time - get_paca()->utime_sspurr; 328 udelta = acct->user_time - acct->utime_sspurr;
319 get_paca()->utime_sspurr = get_paca()->user_time; 329 acct->utime_sspurr = acct->user_time;
320 330
321 /* 331 /*
322 * Because we don't read the SPURR on every kernel entry/exit, 332 * Because we don't read the SPURR on every kernel entry/exit,
@@ -338,14 +348,14 @@ static u64 vtime_delta(struct task_struct *tsk,
338 *sys_scaled = deltascaled; 348 *sys_scaled = deltascaled;
339 } 349 }
340 } 350 }
341 get_paca()->user_time_scaled += user_scaled; 351 acct->user_time_scaled += user_scaled;
342 352
343 return delta; 353 return delta;
344} 354}
345 355
346void vtime_account_system(struct task_struct *tsk) 356void vtime_account_system(struct task_struct *tsk)
347{ 357{
348 u64 delta, sys_scaled, stolen; 358 unsigned long delta, sys_scaled, stolen;
349 359
350 delta = vtime_delta(tsk, &sys_scaled, &stolen); 360 delta = vtime_delta(tsk, &sys_scaled, &stolen);
351 account_system_time(tsk, 0, delta, sys_scaled); 361 account_system_time(tsk, 0, delta, sys_scaled);
@@ -356,7 +366,7 @@ EXPORT_SYMBOL_GPL(vtime_account_system);
356 366
357void vtime_account_idle(struct task_struct *tsk) 367void vtime_account_idle(struct task_struct *tsk)
358{ 368{
359 u64 delta, sys_scaled, stolen; 369 unsigned long delta, sys_scaled, stolen;
360 370
361 delta = vtime_delta(tsk, &sys_scaled, &stolen); 371 delta = vtime_delta(tsk, &sys_scaled, &stolen);
362 account_idle_time(delta + stolen); 372 account_idle_time(delta + stolen);
@@ -374,15 +384,32 @@ void vtime_account_idle(struct task_struct *tsk)
374void vtime_account_user(struct task_struct *tsk) 384void vtime_account_user(struct task_struct *tsk)
375{ 385{
376 cputime_t utime, utimescaled; 386 cputime_t utime, utimescaled;
387 struct cpu_accounting_data *acct = get_accounting(tsk);
377 388
378 utime = get_paca()->user_time; 389 utime = acct->user_time;
379 utimescaled = get_paca()->user_time_scaled; 390 utimescaled = acct->user_time_scaled;
380 get_paca()->user_time = 0; 391 acct->user_time = 0;
381 get_paca()->user_time_scaled = 0; 392 acct->user_time_scaled = 0;
382 get_paca()->utime_sspurr = 0; 393 acct->utime_sspurr = 0;
383 account_user_time(tsk, utime, utimescaled); 394 account_user_time(tsk, utime, utimescaled);
384} 395}
385 396
397#ifdef CONFIG_PPC32
398/*
399 * Called from the context switch with interrupts disabled, to charge all
400 * accumulated times to the current process, and to prepare accounting on
401 * the next process.
402 */
403void arch_vtime_task_switch(struct task_struct *prev)
404{
405 struct cpu_accounting_data *acct = get_accounting(current);
406
407 acct->starttime = get_accounting(prev)->starttime;
408 acct->system_time = 0;
409 acct->user_time = 0;
410}
411#endif /* CONFIG_PPC32 */
412
386#else /* ! CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ 413#else /* ! CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
387#define calc_cputime_factors() 414#define calc_cputime_factors()
388#endif 415#endif
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 77e9b8d591fb..f32edec13fd1 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -1,7 +1,6 @@
1config PPC64 1config PPC64
2 bool "64-bit kernel" 2 bool "64-bit kernel"
3 default n 3 default n
4 select HAVE_VIRT_CPU_ACCOUNTING
5 select ZLIB_DEFLATE 4 select ZLIB_DEFLATE
6 help 5 help
7 This option selects whether a 32-bit or a 64-bit kernel 6 This option selects whether a 32-bit or a 64-bit kernel
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index c5e155108be5..4f7c29d87ec3 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2213,13 +2213,13 @@ static void dump_one_paca(int cpu)
2213 DUMP(p, subcore_sibling_mask, "x"); 2213 DUMP(p, subcore_sibling_mask, "x");
2214#endif 2214#endif
2215 2215
2216 DUMP(p, user_time, "llx"); 2216 DUMP(p, accounting.user_time, "llx");
2217 DUMP(p, system_time, "llx"); 2217 DUMP(p, accounting.system_time, "llx");
2218 DUMP(p, user_time_scaled, "llx"); 2218 DUMP(p, accounting.user_time_scaled, "llx");
2219 DUMP(p, starttime, "llx"); 2219 DUMP(p, accounting.starttime, "llx");
2220 DUMP(p, starttime_user, "llx"); 2220 DUMP(p, accounting.starttime_user, "llx");
2221 DUMP(p, startspurr, "llx"); 2221 DUMP(p, accounting.startspurr, "llx");
2222 DUMP(p, utime_sspurr, "llx"); 2222 DUMP(p, accounting.utime_sspurr, "llx");
2223 DUMP(p, stolen_time, "llx"); 2223 DUMP(p, stolen_time, "llx");
2224#undef DUMP 2224#undef DUMP
2225 2225