aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@hera.kernel.org>2006-03-23 09:39:08 -0500
committerAnton Altaparmakov <aia21@hera.kernel.org>2006-03-23 09:39:08 -0500
commit74293759002aa7db0179158c20676a034614577b (patch)
tree030ef62361042d1a034087ad9a726db3b57bba72 /arch/powerpc/kernel
parentbb8047d3540affd6b8c2adac3fe792e07143be0f (diff)
parent2e6e33bab6e1996a5dec9108fb467b52b841e7a8 (diff)
Merge branch 'master' of /home/aia21/ntfs-2.6/
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/asm-offsets.c4
-rw-r--r--arch/powerpc/kernel/cputable.c21
-rw-r--r--arch/powerpc/kernel/entry_32.S95
-rw-r--r--arch/powerpc/kernel/entry_64.S105
-rw-r--r--arch/powerpc/kernel/firmware.c25
-rw-r--r--arch/powerpc/kernel/head_44x.S2
-rw-r--r--arch/powerpc/kernel/head_64.S14
-rw-r--r--arch/powerpc/kernel/head_8xx.S2
-rw-r--r--arch/powerpc/kernel/head_booke.h363
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S6
-rw-r--r--arch/powerpc/kernel/iomap.c2
-rw-r--r--arch/powerpc/kernel/iommu.c1
-rw-r--r--arch/powerpc/kernel/irq.c32
-rw-r--r--arch/powerpc/kernel/kprobes.c1
-rw-r--r--arch/powerpc/kernel/of_device.c5
-rw-r--r--arch/powerpc/kernel/pci_64.c5
-rw-r--r--arch/powerpc/kernel/pci_iommu.c1
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c11
-rw-r--r--arch/powerpc/kernel/process.c9
-rw-r--r--arch/powerpc/kernel/prom.c58
-rw-r--r--arch/powerpc/kernel/prom_init.c2
-rw-r--r--arch/powerpc/kernel/ptrace-common.h2
-rw-r--r--arch/powerpc/kernel/ptrace.c5
-rw-r--r--arch/powerpc/kernel/rtas-proc.c1
-rw-r--r--arch/powerpc/kernel/rtas-rtc.c2
-rw-r--r--arch/powerpc/kernel/rtas_pci.c26
-rw-r--r--arch/powerpc/kernel/setup_64.c2
-rw-r--r--arch/powerpc/kernel/signal_32.c19
-rw-r--r--arch/powerpc/kernel/signal_64.c11
-rw-r--r--arch/powerpc/kernel/smp.c4
-rw-r--r--arch/powerpc/kernel/systbl.S2
-rw-r--r--arch/powerpc/kernel/time.c289
-rw-r--r--arch/powerpc/kernel/traps.c2
-rw-r--r--arch/powerpc/kernel/vdso.c6
-rw-r--r--arch/powerpc/kernel/vdso64/gettimeofday.S4
35 files changed, 812 insertions, 327 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 840aad43a98b..882889b15926 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -92,7 +92,6 @@ int main(void)
92 92
93 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); 93 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
94 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); 94 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
95 DEFINE(TI_SIGFRAME, offsetof(struct thread_info, nvgprs_frame));
96 DEFINE(TI_TASK, offsetof(struct thread_info, task)); 95 DEFINE(TI_TASK, offsetof(struct thread_info, task));
97#ifdef CONFIG_PPC32 96#ifdef CONFIG_PPC32
98 DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); 97 DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
@@ -137,6 +136,9 @@ int main(void)
137 DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp)); 136 DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
138 DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr)); 137 DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr));
139 DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); 138 DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
139 DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
140 DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
141 DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
140 142
141 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); 143 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
142 DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1)); 144 DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 10696456a4c6..39e348a3ade2 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -53,8 +53,10 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
53 PPC_FEATURE_HAS_MMU) 53 PPC_FEATURE_HAS_MMU)
54#define COMMON_USER_PPC64 (COMMON_USER | PPC_FEATURE_64) 54#define COMMON_USER_PPC64 (COMMON_USER | PPC_FEATURE_64)
55#define COMMON_USER_POWER4 (COMMON_USER_PPC64 | PPC_FEATURE_POWER4) 55#define COMMON_USER_POWER4 (COMMON_USER_PPC64 | PPC_FEATURE_POWER4)
56#define COMMON_USER_POWER5 (COMMON_USER_PPC64 | PPC_FEATURE_POWER5) 56#define COMMON_USER_POWER5 (COMMON_USER_PPC64 | PPC_FEATURE_POWER5 |\
57#define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS) 57 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
58#define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS|\
59 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
58#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ 60#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
59 PPC_FEATURE_BOOKE) 61 PPC_FEATURE_BOOKE)
60 62
@@ -267,7 +269,8 @@ struct cpu_spec cpu_specs[] = {
267 .cpu_name = "Cell Broadband Engine", 269 .cpu_name = "Cell Broadband Engine",
268 .cpu_features = CPU_FTRS_CELL, 270 .cpu_features = CPU_FTRS_CELL,
269 .cpu_user_features = COMMON_USER_PPC64 | 271 .cpu_user_features = COMMON_USER_PPC64 |
270 PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP, 272 PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP |
273 PPC_FEATURE_SMT,
271 .icache_bsize = 128, 274 .icache_bsize = 128,
272 .dcache_bsize = 128, 275 .dcache_bsize = 128,
273 .cpu_setup = __setup_cpu_be, 276 .cpu_setup = __setup_cpu_be,
@@ -891,7 +894,7 @@ struct cpu_spec cpu_specs[] = {
891 .platform = "ppc405", 894 .platform = "ppc405",
892 }, 895 },
893 { /* Xilinx Virtex-II Pro */ 896 { /* Xilinx Virtex-II Pro */
894 .pvr_mask = 0xffff0000, 897 .pvr_mask = 0xfffff000,
895 .pvr_value = 0x20010000, 898 .pvr_value = 0x20010000,
896 .cpu_name = "Virtex-II Pro", 899 .cpu_name = "Virtex-II Pro",
897 .cpu_features = CPU_FTRS_40X, 900 .cpu_features = CPU_FTRS_40X,
@@ -901,6 +904,16 @@ struct cpu_spec cpu_specs[] = {
901 .dcache_bsize = 32, 904 .dcache_bsize = 32,
902 .platform = "ppc405", 905 .platform = "ppc405",
903 }, 906 },
907 { /* Xilinx Virtex-4 FX */
908 .pvr_mask = 0xfffff000,
909 .pvr_value = 0x20011000,
910 .cpu_name = "Virtex-4 FX",
911 .cpu_features = CPU_FTRS_40X,
912 .cpu_user_features = PPC_FEATURE_32 |
913 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
914 .icache_bsize = 32,
915 .dcache_bsize = 32,
916 },
904 { /* 405EP */ 917 { /* 405EP */
905 .pvr_mask = 0xffff0000, 918 .pvr_mask = 0xffff0000,
906 .pvr_value = 0x51210000, 919 .pvr_value = 0x51210000,
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index f20a67261ec7..4827ca1ec89b 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -227,7 +227,7 @@ ret_from_syscall:
227 MTMSRD(r10) 227 MTMSRD(r10)
228 lwz r9,TI_FLAGS(r12) 228 lwz r9,TI_FLAGS(r12)
229 li r8,-_LAST_ERRNO 229 li r8,-_LAST_ERRNO
230 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK) 230 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
231 bne- syscall_exit_work 231 bne- syscall_exit_work
232 cmplw 0,r3,r8 232 cmplw 0,r3,r8
233 blt+ syscall_exit_cont 233 blt+ syscall_exit_cont
@@ -287,8 +287,10 @@ syscall_dotrace:
287 287
288syscall_exit_work: 288syscall_exit_work:
289 andi. r0,r9,_TIF_RESTOREALL 289 andi. r0,r9,_TIF_RESTOREALL
290 bne- 2f 290 beq+ 0f
291 cmplw 0,r3,r8 291 REST_NVGPRS(r1)
292 b 2f
2930: cmplw 0,r3,r8
292 blt+ 1f 294 blt+ 1f
293 andi. r0,r9,_TIF_NOERROR 295 andi. r0,r9,_TIF_NOERROR
294 bne- 1f 296 bne- 1f
@@ -302,9 +304,7 @@ syscall_exit_work:
3022: andi. r0,r9,(_TIF_PERSYSCALL_MASK) 3042: andi. r0,r9,(_TIF_PERSYSCALL_MASK)
303 beq 4f 305 beq 4f
304 306
305 /* Clear per-syscall TIF flags if any are set, but _leave_ 307 /* Clear per-syscall TIF flags if any are set. */
306 _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
307 yet. */
308 308
309 li r11,_TIF_PERSYSCALL_MASK 309 li r11,_TIF_PERSYSCALL_MASK
310 addi r12,r12,TI_FLAGS 310 addi r12,r12,TI_FLAGS
@@ -318,8 +318,13 @@ syscall_exit_work:
318 subi r12,r12,TI_FLAGS 318 subi r12,r12,TI_FLAGS
319 319
3204: /* Anything which requires enabling interrupts? */ 3204: /* Anything which requires enabling interrupts? */
321 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS) 321 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
322 beq 7f 322 beq ret_from_except
323
324 /* Re-enable interrupts */
325 ori r10,r10,MSR_EE
326 SYNC
327 MTMSRD(r10)
323 328
324 /* Save NVGPRS if they're not saved already */ 329 /* Save NVGPRS if they're not saved already */
325 lwz r4,_TRAP(r1) 330 lwz r4,_TRAP(r1)
@@ -328,71 +333,11 @@ syscall_exit_work:
328 SAVE_NVGPRS(r1) 333 SAVE_NVGPRS(r1)
329 li r4,0xc00 334 li r4,0xc00
330 stw r4,_TRAP(r1) 335 stw r4,_TRAP(r1)
331 3365:
332 /* Re-enable interrupts */
3335: ori r10,r10,MSR_EE
334 SYNC
335 MTMSRD(r10)
336
337 andi. r0,r9,_TIF_SAVE_NVGPRS
338 bne save_user_nvgprs
339
340save_user_nvgprs_cont:
341 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
342 beq 7f
343
344 addi r3,r1,STACK_FRAME_OVERHEAD 337 addi r3,r1,STACK_FRAME_OVERHEAD
345 bl do_syscall_trace_leave 338 bl do_syscall_trace_leave
346 REST_NVGPRS(r1) 339 b ret_from_except_full
347
3486: lwz r3,GPR3(r1)
349 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
350 SYNC
351 MTMSRD(r10) /* disable interrupts again */
352 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
353 lwz r9,TI_FLAGS(r12)
3547:
355 andi. r0,r9,_TIF_NEED_RESCHED
356 bne 8f
357 lwz r5,_MSR(r1)
358 andi. r5,r5,MSR_PR
359 beq ret_from_except
360 andi. r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK
361 beq ret_from_except
362 b do_user_signal
3638:
364 ori r10,r10,MSR_EE
365 SYNC
366 MTMSRD(r10) /* re-enable interrupts */
367 bl schedule
368 b 6b
369
370save_user_nvgprs:
371 lwz r8,TI_SIGFRAME(r12)
372
373.macro savewords start, end
374 1: stw \start,4*(\start)(r8)
375 .section __ex_table,"a"
376 .align 2
377 .long 1b,save_user_nvgprs_fault
378 .previous
379 .if \end - \start
380 savewords "(\start+1)",\end
381 .endif
382.endm
383 savewords 14,31
384 b save_user_nvgprs_cont
385
386
387save_user_nvgprs_fault:
388 li r3,11 /* SIGSEGV */
389 lwz r4,TI_TASK(r12)
390 bl force_sigsegv
391 340
392 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
393 lwz r9,TI_FLAGS(r12)
394 b save_user_nvgprs_cont
395
396#ifdef SHOW_SYSCALLS 341#ifdef SHOW_SYSCALLS
397do_show_syscall: 342do_show_syscall:
398#ifdef SHOW_SYSCALLS_TASK 343#ifdef SHOW_SYSCALLS_TASK
@@ -490,6 +435,14 @@ ppc_clone:
490 stw r0,_TRAP(r1) /* register set saved */ 435 stw r0,_TRAP(r1) /* register set saved */
491 b sys_clone 436 b sys_clone
492 437
438 .globl ppc_swapcontext
439ppc_swapcontext:
440 SAVE_NVGPRS(r1)
441 lwz r0,_TRAP(r1)
442 rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
443 stw r0,_TRAP(r1) /* register set saved */
444 b sys_swapcontext
445
493/* 446/*
494 * Top-level page fault handling. 447 * Top-level page fault handling.
495 * This is in assembler because if do_page_fault tells us that 448 * This is in assembler because if do_page_fault tells us that
@@ -683,7 +636,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */
683 /* Check current_thread_info()->flags */ 636 /* Check current_thread_info()->flags */
684 rlwinm r9,r1,0,0,(31-THREAD_SHIFT) 637 rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
685 lwz r9,TI_FLAGS(r9) 638 lwz r9,TI_FLAGS(r9)
686 andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK) 639 andi. r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED)
687 bne do_work 640 bne do_work
688 641
689restore_user: 642restore_user:
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 388f861b8ed1..1060155d84c3 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/entry.S
3 *
4 * PowerPC version 2 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP 4 * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
@@ -63,6 +61,7 @@ system_call_common:
63 std r12,_MSR(r1) 61 std r12,_MSR(r1)
64 std r0,GPR0(r1) 62 std r0,GPR0(r1)
65 std r10,GPR1(r1) 63 std r10,GPR1(r1)
64 ACCOUNT_CPU_USER_ENTRY(r10, r11)
66 std r2,GPR2(r1) 65 std r2,GPR2(r1)
67 std r3,GPR3(r1) 66 std r3,GPR3(r1)
68 std r4,GPR4(r1) 67 std r4,GPR4(r1)
@@ -160,7 +159,7 @@ syscall_exit:
160 mtmsrd r10,1 159 mtmsrd r10,1
161 ld r9,TI_FLAGS(r12) 160 ld r9,TI_FLAGS(r12)
162 li r11,-_LAST_ERRNO 161 li r11,-_LAST_ERRNO
163 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR|_TIF_RESTORE_SIGMASK) 162 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
164 bne- syscall_exit_work 163 bne- syscall_exit_work
165 cmpld r3,r11 164 cmpld r3,r11
166 ld r5,_CCR(r1) 165 ld r5,_CCR(r1)
@@ -170,8 +169,9 @@ syscall_error_cont:
170 stdcx. r0,0,r1 /* to clear the reservation */ 169 stdcx. r0,0,r1 /* to clear the reservation */
171 andi. r6,r8,MSR_PR 170 andi. r6,r8,MSR_PR
172 ld r4,_LINK(r1) 171 ld r4,_LINK(r1)
173 beq- 1f /* only restore r13 if */ 172 beq- 1f
174 ld r13,GPR13(r1) /* returning to usermode */ 173 ACCOUNT_CPU_USER_EXIT(r11, r12)
174 ld r13,GPR13(r1) /* only restore r13 if returning to usermode */
1751: ld r2,GPR2(r1) 1751: ld r2,GPR2(r1)
176 li r12,MSR_RI 176 li r12,MSR_RI
177 andc r11,r10,r12 177 andc r11,r10,r12
@@ -216,8 +216,10 @@ syscall_exit_work:
216 If TIF_NOERROR is set, just save r3 as it is. */ 216 If TIF_NOERROR is set, just save r3 as it is. */
217 217
218 andi. r0,r9,_TIF_RESTOREALL 218 andi. r0,r9,_TIF_RESTOREALL
219 bne- 2f 219 beq+ 0f
220 cmpld r3,r11 /* r10 is -LAST_ERRNO */ 220 REST_NVGPRS(r1)
221 b 2f
2220: cmpld r3,r11 /* r10 is -LAST_ERRNO */
221 blt+ 1f 223 blt+ 1f
222 andi. r0,r9,_TIF_NOERROR 224 andi. r0,r9,_TIF_NOERROR
223 bne- 1f 225 bne- 1f
@@ -229,9 +231,7 @@ syscall_exit_work:
2292: andi. r0,r9,(_TIF_PERSYSCALL_MASK) 2312: andi. r0,r9,(_TIF_PERSYSCALL_MASK)
230 beq 4f 232 beq 4f
231 233
232 /* Clear per-syscall TIF flags if any are set, but _leave_ 234 /* Clear per-syscall TIF flags if any are set. */
233 _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
234 yet. */
235 235
236 li r11,_TIF_PERSYSCALL_MASK 236 li r11,_TIF_PERSYSCALL_MASK
237 addi r12,r12,TI_FLAGS 237 addi r12,r12,TI_FLAGS
@@ -240,10 +240,9 @@ syscall_exit_work:
240 stdcx. r10,0,r12 240 stdcx. r10,0,r12
241 bne- 3b 241 bne- 3b
242 subi r12,r12,TI_FLAGS 242 subi r12,r12,TI_FLAGS
243 243
2444: bl .save_nvgprs 2444: /* Anything else left to do? */
245 /* Anything else left to do? */ 245 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
246 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
247 beq .ret_from_except_lite 246 beq .ret_from_except_lite
248 247
249 /* Re-enable interrupts */ 248 /* Re-enable interrupts */
@@ -251,26 +250,10 @@ syscall_exit_work:
251 ori r10,r10,MSR_EE 250 ori r10,r10,MSR_EE
252 mtmsrd r10,1 251 mtmsrd r10,1
253 252
254 andi. r0,r9,_TIF_SAVE_NVGPRS 253 bl .save_nvgprs
255 bne save_user_nvgprs
256
257 /* If tracing, re-enable interrupts and do it */
258save_user_nvgprs_cont:
259 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
260 beq 5f
261
262 addi r3,r1,STACK_FRAME_OVERHEAD 254 addi r3,r1,STACK_FRAME_OVERHEAD
263 bl .do_syscall_trace_leave 255 bl .do_syscall_trace_leave
264 REST_NVGPRS(r1) 256 b .ret_from_except
265 clrrdi r12,r1,THREAD_SHIFT
266
267 /* Disable interrupts again and handle other work if any */
2685: mfmsr r10
269 rldicl r10,r10,48,1
270 rotldi r10,r10,16
271 mtmsrd r10,1
272
273 b .ret_from_except_lite
274 257
275/* Save non-volatile GPRs, if not already saved. */ 258/* Save non-volatile GPRs, if not already saved. */
276_GLOBAL(save_nvgprs) 259_GLOBAL(save_nvgprs)
@@ -282,51 +265,6 @@ _GLOBAL(save_nvgprs)
282 std r0,_TRAP(r1) 265 std r0,_TRAP(r1)
283 blr 266 blr
284 267
285
286save_user_nvgprs:
287 ld r10,TI_SIGFRAME(r12)
288 andi. r0,r9,_TIF_32BIT
289 beq- save_user_nvgprs_64
290
291 /* 32-bit save to userspace */
292
293.macro savewords start, end
294 1: stw \start,4*(\start)(r10)
295 .section __ex_table,"a"
296 .align 3
297 .llong 1b,save_user_nvgprs_fault
298 .previous
299 .if \end - \start
300 savewords "(\start+1)",\end
301 .endif
302.endm
303 savewords 14,31
304 b save_user_nvgprs_cont
305
306save_user_nvgprs_64:
307 /* 64-bit save to userspace */
308
309.macro savelongs start, end
310 1: std \start,8*(\start)(r10)
311 .section __ex_table,"a"
312 .align 3
313 .llong 1b,save_user_nvgprs_fault
314 .previous
315 .if \end - \start
316 savelongs "(\start+1)",\end
317 .endif
318.endm
319 savelongs 14,31
320 b save_user_nvgprs_cont
321
322save_user_nvgprs_fault:
323 li r3,11 /* SIGSEGV */
324 ld r4,TI_TASK(r12)
325 bl .force_sigsegv
326
327 clrrdi r12,r1,THREAD_SHIFT
328 ld r9,TI_FLAGS(r12)
329 b save_user_nvgprs_cont
330 268
331/* 269/*
332 * The sigsuspend and rt_sigsuspend system calls can call do_signal 270 * The sigsuspend and rt_sigsuspend system calls can call do_signal
@@ -352,6 +290,16 @@ _GLOBAL(ppc_clone)
352 bl .sys_clone 290 bl .sys_clone
353 b syscall_exit 291 b syscall_exit
354 292
293_GLOBAL(ppc32_swapcontext)
294 bl .save_nvgprs
295 bl .compat_sys_swapcontext
296 b syscall_exit
297
298_GLOBAL(ppc64_swapcontext)
299 bl .save_nvgprs
300 bl .sys_swapcontext
301 b syscall_exit
302
355_GLOBAL(ret_from_fork) 303_GLOBAL(ret_from_fork)
356 bl .schedule_tail 304 bl .schedule_tail
357 REST_NVGPRS(r1) 305 REST_NVGPRS(r1)
@@ -374,7 +322,7 @@ _GLOBAL(ret_from_fork)
374 * the fork code also. 322 * the fork code also.
375 * 323 *
376 * The code which creates the new task context is in 'copy_thread' 324 * The code which creates the new task context is in 'copy_thread'
377 * in arch/ppc64/kernel/process.c 325 * in arch/powerpc/kernel/process.c
378 */ 326 */
379 .align 7 327 .align 7
380_GLOBAL(_switch) 328_GLOBAL(_switch)
@@ -538,6 +486,7 @@ restore:
538 * userspace 486 * userspace
539 */ 487 */
540 beq 1f 488 beq 1f
489 ACCOUNT_CPU_USER_EXIT(r3, r4)
541 REST_GPR(13, r1) 490 REST_GPR(13, r1)
5421: 4911:
543 ld r3,_CTR(r1) 492 ld r3,_CTR(r1)
diff --git a/arch/powerpc/kernel/firmware.c b/arch/powerpc/kernel/firmware.c
index 65eae752a527..4d37a3cb80f6 100644
--- a/arch/powerpc/kernel/firmware.c
+++ b/arch/powerpc/kernel/firmware.c
@@ -18,28 +18,3 @@
18#include <asm/firmware.h> 18#include <asm/firmware.h>
19 19
20unsigned long ppc64_firmware_features; 20unsigned long ppc64_firmware_features;
21
22#ifdef CONFIG_PPC_PSERIES
23firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = {
24 {FW_FEATURE_PFT, "hcall-pft"},
25 {FW_FEATURE_TCE, "hcall-tce"},
26 {FW_FEATURE_SPRG0, "hcall-sprg0"},
27 {FW_FEATURE_DABR, "hcall-dabr"},
28 {FW_FEATURE_COPY, "hcall-copy"},
29 {FW_FEATURE_ASR, "hcall-asr"},
30 {FW_FEATURE_DEBUG, "hcall-debug"},
31 {FW_FEATURE_PERF, "hcall-perf"},
32 {FW_FEATURE_DUMP, "hcall-dump"},
33 {FW_FEATURE_INTERRUPT, "hcall-interrupt"},
34 {FW_FEATURE_MIGRATE, "hcall-migrate"},
35 {FW_FEATURE_PERFMON, "hcall-perfmon"},
36 {FW_FEATURE_CRQ, "hcall-crq"},
37 {FW_FEATURE_VIO, "hcall-vio"},
38 {FW_FEATURE_RDMA, "hcall-rdma"},
39 {FW_FEATURE_LLAN, "hcall-lLAN"},
40 {FW_FEATURE_BULK, "hcall-bulk"},
41 {FW_FEATURE_XDABR, "hcall-xdabr"},
42 {FW_FEATURE_MULTITCE, "hcall-multi-tce"},
43 {FW_FEATURE_SPLPAR, "hcall-splpar"},
44};
45#endif
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 8b49679fad54..47c7fa148c9a 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/kernel/head_44x.S
3 *
4 * Kernel execution entry point code. 2 * Kernel execution entry point code.
5 * 3 *
6 * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org> 4 * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 11f2cd5af7dc..35084f3a841b 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/head.S
3 *
4 * PowerPC version 2 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 * 4 *
@@ -279,6 +277,7 @@ exception_marker:
279 std r10,0(r1); /* make stack chain pointer */ \ 277 std r10,0(r1); /* make stack chain pointer */ \
280 std r0,GPR0(r1); /* save r0 in stackframe */ \ 278 std r0,GPR0(r1); /* save r0 in stackframe */ \
281 std r10,GPR1(r1); /* save r1 in stackframe */ \ 279 std r10,GPR1(r1); /* save r1 in stackframe */ \
280 ACCOUNT_CPU_USER_ENTRY(r9, r10); \
282 std r2,GPR2(r1); /* save r2 in stackframe */ \ 281 std r2,GPR2(r1); /* save r2 in stackframe */ \
283 SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \ 282 SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
284 SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \ 283 SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
@@ -846,6 +845,14 @@ fast_exception_return:
846 ld r11,_NIP(r1) 845 ld r11,_NIP(r1)
847 andi. r3,r12,MSR_RI /* check if RI is set */ 846 andi. r3,r12,MSR_RI /* check if RI is set */
848 beq- unrecov_fer 847 beq- unrecov_fer
848
849#ifdef CONFIG_VIRT_CPU_ACCOUNTING
850 andi. r3,r12,MSR_PR
851 beq 2f
852 ACCOUNT_CPU_USER_EXIT(r3, r4)
8532:
854#endif
855
849 ld r3,_CCR(r1) 856 ld r3,_CCR(r1)
850 ld r4,_LINK(r1) 857 ld r4,_LINK(r1)
851 ld r5,_CTR(r1) 858 ld r5,_CTR(r1)
@@ -1537,6 +1544,9 @@ _STATIC(__boot_from_prom)
1537 mr r28,r6 1544 mr r28,r6
1538 mr r27,r7 1545 mr r27,r7
1539 1546
1547 /* Align the stack to 16-byte boundary for broken yaboot */
1548 rldicr r1,r1,0,59
1549
1540 /* Make sure we are running in 64 bits mode */ 1550 /* Make sure we are running in 64 bits mode */
1541 bl .enable_64b_mode 1551 bl .enable_64b_mode
1542 1552
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index bc6d1ac55235..28941f5ce673 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/kernel/except_8xx.S
3 *
4 * PowerPC version 2 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP 4 * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
new file mode 100644
index 000000000000..8536e7676160
--- /dev/null
+++ b/arch/powerpc/kernel/head_booke.h
@@ -0,0 +1,363 @@
1#ifndef __HEAD_BOOKE_H__
2#define __HEAD_BOOKE_H__
3
4/*
5 * Macros used for common Book-e exception handling
6 */
7
8#define SET_IVOR(vector_number, vector_label) \
9 li r26,vector_label@l; \
10 mtspr SPRN_IVOR##vector_number,r26; \
11 sync
12
13#define NORMAL_EXCEPTION_PROLOG \
14 mtspr SPRN_SPRG0,r10; /* save two registers to work with */\
15 mtspr SPRN_SPRG1,r11; \
16 mtspr SPRN_SPRG4W,r1; \
17 mfcr r10; /* save CR in r10 for now */\
18 mfspr r11,SPRN_SRR1; /* check whether user or kernel */\
19 andi. r11,r11,MSR_PR; \
20 beq 1f; \
21 mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\
22 lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\
23 addi r1,r1,THREAD_SIZE; \
241: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
25 mr r11,r1; \
26 stw r10,_CCR(r11); /* save various registers */\
27 stw r12,GPR12(r11); \
28 stw r9,GPR9(r11); \
29 mfspr r10,SPRN_SPRG0; \
30 stw r10,GPR10(r11); \
31 mfspr r12,SPRN_SPRG1; \
32 stw r12,GPR11(r11); \
33 mflr r10; \
34 stw r10,_LINK(r11); \
35 mfspr r10,SPRN_SPRG4R; \
36 mfspr r12,SPRN_SRR0; \
37 stw r10,GPR1(r11); \
38 mfspr r9,SPRN_SRR1; \
39 stw r10,0(r11); \
40 rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
41 stw r0,GPR0(r11); \
42 SAVE_4GPRS(3, r11); \
43 SAVE_2GPRS(7, r11)
44
45/* To handle the additional exception priority levels on 40x and Book-E
46 * processors we allocate a 4k stack per additional priority level. The various
47 * head_xxx.S files allocate space (exception_stack_top) for each priority's
48 * stack times the number of CPUs
49 *
50 * On 40x critical is the only additional level
51 * On 44x/e500 we have critical and machine check
52 * On e200 we have critical and debug (machine check occurs via critical)
53 *
54 * Additionally we reserve a SPRG for each priority level so we can free up a
55 * GPR to use as the base for indirect access to the exception stacks. This
56 * is necessary since the MMU is always on, for Book-E parts, and the stacks
57 * are offset from KERNELBASE.
58 *
59 */
60#define BOOKE_EXCEPTION_STACK_SIZE (8192)
61
62/* CRIT_SPRG only used in critical exception handling */
63#define CRIT_SPRG SPRN_SPRG2
64/* MCHECK_SPRG only used in machine check exception handling */
65#define MCHECK_SPRG SPRN_SPRG6W
66
67#define MCHECK_STACK_TOP (exception_stack_top - 4096)
68#define CRIT_STACK_TOP (exception_stack_top)
69
70/* only on e200 for now */
71#define DEBUG_STACK_TOP (exception_stack_top - 4096)
72#define DEBUG_SPRG SPRN_SPRG6W
73
74#ifdef CONFIG_SMP
75#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
76 mfspr r8,SPRN_PIR; \
77 mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \
78 neg r8,r8; \
79 addis r8,r8,level##_STACK_TOP@ha; \
80 addi r8,r8,level##_STACK_TOP@l
81#else
82#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
83 lis r8,level##_STACK_TOP@h; \
84 ori r8,r8,level##_STACK_TOP@l
85#endif
86
87/*
88 * Exception prolog for critical/machine check exceptions. This is a
89 * little different from the normal exception prolog above since a
90 * critical/machine check exception can potentially occur at any point
91 * during normal exception processing. Thus we cannot use the same SPRG
92 * registers as the normal prolog above. Instead we use a portion of the
93 * critical/machine check exception stack at low physical addresses.
94 */
95#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \
96 mtspr exc_level##_SPRG,r8; \
97 BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \
98 stw r10,GPR10-INT_FRAME_SIZE(r8); \
99 stw r11,GPR11-INT_FRAME_SIZE(r8); \
100 mfcr r10; /* save CR in r10 for now */\
101 mfspr r11,exc_level_srr1; /* check whether user or kernel */\
102 andi. r11,r11,MSR_PR; \
103 mr r11,r8; \
104 mfspr r8,exc_level##_SPRG; \
105 beq 1f; \
106 /* COMING FROM USER MODE */ \
107 mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
108 lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
109 addi r11,r11,THREAD_SIZE; \
1101: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
111 stw r10,_CCR(r11); /* save various registers */\
112 stw r12,GPR12(r11); \
113 stw r9,GPR9(r11); \
114 mflr r10; \
115 stw r10,_LINK(r11); \
116 mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
117 stw r12,_DEAR(r11); /* since they may have had stuff */\
118 mfspr r9,SPRN_ESR; /* in them at the point where the */\
119 stw r9,_ESR(r11); /* exception was taken */\
120 mfspr r12,exc_level_srr0; \
121 stw r1,GPR1(r11); \
122 mfspr r9,exc_level_srr1; \
123 stw r1,0(r11); \
124 mr r1,r11; \
125 rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
126 stw r0,GPR0(r11); \
127 SAVE_4GPRS(3, r11); \
128 SAVE_2GPRS(7, r11)
129
130#define CRITICAL_EXCEPTION_PROLOG \
131 EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1)
132#define DEBUG_EXCEPTION_PROLOG \
133 EXC_LEVEL_EXCEPTION_PROLOG(DEBUG, SPRN_DSRR0, SPRN_DSRR1)
134#define MCHECK_EXCEPTION_PROLOG \
135 EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1)
136
137/*
138 * Exception vectors.
139 */
140#define START_EXCEPTION(label) \
141 .align 5; \
142label:
143
144#define FINISH_EXCEPTION(func) \
145 bl transfer_to_handler_full; \
146 .long func; \
147 .long ret_from_except_full
148
149#define EXCEPTION(n, label, hdlr, xfer) \
150 START_EXCEPTION(label); \
151 NORMAL_EXCEPTION_PROLOG; \
152 addi r3,r1,STACK_FRAME_OVERHEAD; \
153 xfer(n, hdlr)
154
155#define CRITICAL_EXCEPTION(n, label, hdlr) \
156 START_EXCEPTION(label); \
157 CRITICAL_EXCEPTION_PROLOG; \
158 addi r3,r1,STACK_FRAME_OVERHEAD; \
159 EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
160 NOCOPY, crit_transfer_to_handler, \
161 ret_from_crit_exc)
162
163#define MCHECK_EXCEPTION(n, label, hdlr) \
164 START_EXCEPTION(label); \
165 MCHECK_EXCEPTION_PROLOG; \
166 mfspr r5,SPRN_ESR; \
167 stw r5,_ESR(r11); \
168 addi r3,r1,STACK_FRAME_OVERHEAD; \
169 EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
170 NOCOPY, mcheck_transfer_to_handler, \
171 ret_from_mcheck_exc)
172
173#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \
174 li r10,trap; \
175 stw r10,_TRAP(r11); \
176 lis r10,msr@h; \
177 ori r10,r10,msr@l; \
178 copyee(r10, r9); \
179 bl tfer; \
180 .long hdlr; \
181 .long ret
182
183#define COPY_EE(d, s) rlwimi d,s,0,16,16
184#define NOCOPY(d, s)
185
186#define EXC_XFER_STD(n, hdlr) \
187 EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \
188 ret_from_except_full)
189
190#define EXC_XFER_LITE(n, hdlr) \
191 EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \
192 ret_from_except)
193
194#define EXC_XFER_EE(n, hdlr) \
195 EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \
196 ret_from_except_full)
197
198#define EXC_XFER_EE_LITE(n, hdlr) \
199 EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
200 ret_from_except)
201
202/* Check for a single step debug exception while in an exception
203 * handler before state has been saved. This is to catch the case
204 * where an instruction that we are trying to single step causes
205 * an exception (eg ITLB/DTLB miss) and thus the first instruction of
206 * the exception handler generates a single step debug exception.
207 *
208 * If we get a debug trap on the first instruction of an exception handler,
209 * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is
210 * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR).
211 * The exception handler was handling a non-critical interrupt, so it will
212 * save (and later restore) the MSR via SPRN_CSRR1, which will still have
213 * the MSR_DE bit set.
214 */
215#ifdef CONFIG_E200
216#define DEBUG_EXCEPTION \
217 START_EXCEPTION(Debug); \
218 DEBUG_EXCEPTION_PROLOG; \
219 \
220 /* \
221 * If there is a single step or branch-taken exception in an \
222 * exception entry sequence, it was probably meant to apply to \
223 * the code where the exception occurred (since exception entry \
224 * doesn't turn off DE automatically). We simulate the effect \
225 * of turning off DE on entry to an exception handler by turning \
226 * off DE in the CSRR1 value and clearing the debug status. \
227 */ \
228 mfspr r10,SPRN_DBSR; /* check single-step/branch taken */ \
229 andis. r10,r10,DBSR_IC@h; \
230 beq+ 2f; \
231 \
232 lis r10,KERNELBASE@h; /* check if exception in vectors */ \
233 ori r10,r10,KERNELBASE@l; \
234 cmplw r12,r10; \
235 blt+ 2f; /* addr below exception vectors */ \
236 \
237 lis r10,Debug@h; \
238 ori r10,r10,Debug@l; \
239 cmplw r12,r10; \
240 bgt+ 2f; /* addr above exception vectors */ \
241 \
242 /* here it looks like we got an inappropriate debug exception. */ \
2431: rlwinm r9,r9,0,~MSR_DE; /* clear DE in the CDRR1 value */ \
244 lis r10,DBSR_IC@h; /* clear the IC event */ \
245 mtspr SPRN_DBSR,r10; \
246 /* restore state and get out */ \
247 lwz r10,_CCR(r11); \
248 lwz r0,GPR0(r11); \
249 lwz r1,GPR1(r11); \
250 mtcrf 0x80,r10; \
251 mtspr SPRN_DSRR0,r12; \
252 mtspr SPRN_DSRR1,r9; \
253 lwz r9,GPR9(r11); \
254 lwz r12,GPR12(r11); \
255 mtspr DEBUG_SPRG,r8; \
256 BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \
257 lwz r10,GPR10-INT_FRAME_SIZE(r8); \
258 lwz r11,GPR11-INT_FRAME_SIZE(r8); \
259 mfspr r8,DEBUG_SPRG; \
260 \
261 RFDI; \
262 b .; \
263 \
264 /* continue normal handling for a critical exception... */ \
2652: mfspr r4,SPRN_DBSR; \
266 addi r3,r1,STACK_FRAME_OVERHEAD; \
267 EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc)
268#else
269#define DEBUG_EXCEPTION \
270 START_EXCEPTION(Debug); \
271 CRITICAL_EXCEPTION_PROLOG; \
272 \
273 /* \
274 * If there is a single step or branch-taken exception in an \
275 * exception entry sequence, it was probably meant to apply to \
276 * the code where the exception occurred (since exception entry \
277 * doesn't turn off DE automatically). We simulate the effect \
278 * of turning off DE on entry to an exception handler by turning \
279 * off DE in the CSRR1 value and clearing the debug status. \
280 */ \
281 mfspr r10,SPRN_DBSR; /* check single-step/branch taken */ \
282 andis. r10,r10,DBSR_IC@h; \
283 beq+ 2f; \
284 \
285 lis r10,KERNELBASE@h; /* check if exception in vectors */ \
286 ori r10,r10,KERNELBASE@l; \
287 cmplw r12,r10; \
288 blt+ 2f; /* addr below exception vectors */ \
289 \
290 lis r10,Debug@h; \
291 ori r10,r10,Debug@l; \
292 cmplw r12,r10; \
293 bgt+ 2f; /* addr above exception vectors */ \
294 \
295 /* here it looks like we got an inappropriate debug exception. */ \
2961: rlwinm r9,r9,0,~MSR_DE; /* clear DE in the CSRR1 value */ \
297 lis r10,DBSR_IC@h; /* clear the IC event */ \
298 mtspr SPRN_DBSR,r10; \
299 /* restore state and get out */ \
300 lwz r10,_CCR(r11); \
301 lwz r0,GPR0(r11); \
302 lwz r1,GPR1(r11); \
303 mtcrf 0x80,r10; \
304 mtspr SPRN_CSRR0,r12; \
305 mtspr SPRN_CSRR1,r9; \
306 lwz r9,GPR9(r11); \
307 lwz r12,GPR12(r11); \
308 mtspr CRIT_SPRG,r8; \
309 BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */ \
310 lwz r10,GPR10-INT_FRAME_SIZE(r8); \
311 lwz r11,GPR11-INT_FRAME_SIZE(r8); \
312 mfspr r8,CRIT_SPRG; \
313 \
314 rfci; \
315 b .; \
316 \
317 /* continue normal handling for a critical exception... */ \
3182: mfspr r4,SPRN_DBSR; \
319 addi r3,r1,STACK_FRAME_OVERHEAD; \
320 EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)
321#endif
322
323#define INSTRUCTION_STORAGE_EXCEPTION \
324 START_EXCEPTION(InstructionStorage) \
325 NORMAL_EXCEPTION_PROLOG; \
326 mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \
327 stw r5,_ESR(r11); \
328 mr r4,r12; /* Pass SRR0 as arg2 */ \
329 li r5,0; /* Pass zero as arg3 */ \
330 EXC_XFER_EE_LITE(0x0400, handle_page_fault)
331
332#define ALIGNMENT_EXCEPTION \
333 START_EXCEPTION(Alignment) \
334 NORMAL_EXCEPTION_PROLOG; \
335 mfspr r4,SPRN_DEAR; /* Grab the DEAR and save it */ \
336 stw r4,_DEAR(r11); \
337 addi r3,r1,STACK_FRAME_OVERHEAD; \
338 EXC_XFER_EE(0x0600, alignment_exception)
339
340#define PROGRAM_EXCEPTION \
341 START_EXCEPTION(Program) \
342 NORMAL_EXCEPTION_PROLOG; \
343 mfspr r4,SPRN_ESR; /* Grab the ESR and save it */ \
344 stw r4,_ESR(r11); \
345 addi r3,r1,STACK_FRAME_OVERHEAD; \
346 EXC_XFER_STD(0x0700, program_check_exception)
347
348#define DECREMENTER_EXCEPTION \
349 START_EXCEPTION(Decrementer) \
350 NORMAL_EXCEPTION_PROLOG; \
351 lis r0,TSR_DIS@h; /* Setup the DEC interrupt mask */ \
352 mtspr SPRN_TSR,r0; /* Clear the DEC interrupt */ \
353 addi r3,r1,STACK_FRAME_OVERHEAD; \
354 EXC_XFER_LITE(0x0900, timer_interrupt)
355
356#define FP_UNAVAILABLE_EXCEPTION \
357 START_EXCEPTION(FloatingPointUnavailable) \
358 NORMAL_EXCEPTION_PROLOG; \
359 bne load_up_fpu; /* if from user, just load it up */ \
360 addi r3,r1,STACK_FRAME_OVERHEAD; \
361 EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
362
363#endif /* __HEAD_BOOKE_H__ */
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 8d60fa99fc4b..dd86bbed7627 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/kernel/head_fsl_booke.S
3 *
4 * Kernel execution entry point code. 2 * Kernel execution entry point code.
5 * 3 *
6 * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org> 4 * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
@@ -316,6 +314,7 @@ skpinv: addi r6,r6,1 /* Increment */
316 */ 314 */
317 lis r2,DBCR0_IDM@h 315 lis r2,DBCR0_IDM@h
318 mtspr SPRN_DBCR0,r2 316 mtspr SPRN_DBCR0,r2
317 isync
319 /* clear any residual debug events */ 318 /* clear any residual debug events */
320 li r2,-1 319 li r2,-1
321 mtspr SPRN_DBSR,r2 320 mtspr SPRN_DBSR,r2
@@ -1002,12 +1001,15 @@ _GLOBAL(giveup_fpu)
1002_GLOBAL(abort) 1001_GLOBAL(abort)
1003 li r13,0 1002 li r13,0
1004 mtspr SPRN_DBCR0,r13 /* disable all debug events */ 1003 mtspr SPRN_DBCR0,r13 /* disable all debug events */
1004 isync
1005 mfmsr r13 1005 mfmsr r13
1006 ori r13,r13,MSR_DE@l /* Enable Debug Events */ 1006 ori r13,r13,MSR_DE@l /* Enable Debug Events */
1007 mtmsr r13 1007 mtmsr r13
1008 isync
1008 mfspr r13,SPRN_DBCR0 1009 mfspr r13,SPRN_DBCR0
1009 lis r13,(DBCR0_IDM|DBCR0_RST_CHIP)@h 1010 lis r13,(DBCR0_IDM|DBCR0_RST_CHIP)@h
1010 mtspr SPRN_DBCR0,r13 1011 mtspr SPRN_DBCR0,r13
1012 isync
1011 1013
1012_GLOBAL(set_context) 1014_GLOBAL(set_context)
1013 1015
diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c
index 6160c8dbb7c5..fd8214caedee 100644
--- a/arch/powerpc/kernel/iomap.c
+++ b/arch/powerpc/kernel/iomap.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/iomap.c
3 *
4 * ppc64 "iomap" interface implementation. 2 * ppc64 "iomap" interface implementation.
5 * 3 *
6 * (C) Copyright 2004 Linus Torvalds 4 * (C) Copyright 2004 Linus Torvalds
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 946f3219fd29..d9a7fdef59b9 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/iommu.c
3 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation 2 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
4 * 3 *
5 * Rewrite, cleanup, new allocation schemes, virtual merging: 4 * Rewrite, cleanup, new allocation schemes, virtual merging:
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index d1fffce86df9..24dc8117b822 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/kernel/irq.c
3 *
4 * Derived from arch/i386/kernel/irq.c 2 * Derived from arch/i386/kernel/irq.c
5 * Copyright (C) 1992 Linus Torvalds 3 * Copyright (C) 1992 Linus Torvalds
6 * Adapted from arch/i386 by Gary Thomas 4 * Adapted from arch/i386 by Gary Thomas
@@ -371,6 +369,7 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq)
371 return NO_IRQ; 369 return NO_IRQ;
372 370
373} 371}
372#endif /* CONFIG_PPC64 */
374 373
375#ifdef CONFIG_IRQSTACKS 374#ifdef CONFIG_IRQSTACKS
376struct thread_info *softirq_ctx[NR_CPUS]; 375struct thread_info *softirq_ctx[NR_CPUS];
@@ -394,10 +393,24 @@ void irq_ctx_init(void)
394 } 393 }
395} 394}
396 395
396static inline void do_softirq_onstack(void)
397{
398 struct thread_info *curtp, *irqtp;
399
400 curtp = current_thread_info();
401 irqtp = softirq_ctx[smp_processor_id()];
402 irqtp->task = curtp->task;
403 call_do_softirq(irqtp);
404 irqtp->task = NULL;
405}
406
407#else
408#define do_softirq_onstack() __do_softirq()
409#endif /* CONFIG_IRQSTACKS */
410
397void do_softirq(void) 411void do_softirq(void)
398{ 412{
399 unsigned long flags; 413 unsigned long flags;
400 struct thread_info *curtp, *irqtp;
401 414
402 if (in_interrupt()) 415 if (in_interrupt())
403 return; 416 return;
@@ -405,19 +418,18 @@ void do_softirq(void)
405 local_irq_save(flags); 418 local_irq_save(flags);
406 419
407 if (local_softirq_pending()) { 420 if (local_softirq_pending()) {
408 curtp = current_thread_info(); 421 account_system_vtime(current);
409 irqtp = softirq_ctx[smp_processor_id()]; 422 local_bh_disable();
410 irqtp->task = curtp->task; 423 do_softirq_onstack();
411 call_do_softirq(irqtp); 424 account_system_vtime(current);
412 irqtp->task = NULL; 425 __local_bh_enable();
413 } 426 }
414 427
415 local_irq_restore(flags); 428 local_irq_restore(flags);
416} 429}
417EXPORT_SYMBOL(do_softirq); 430EXPORT_SYMBOL(do_softirq);
418 431
419#endif /* CONFIG_IRQSTACKS */ 432#ifdef CONFIG_PPC64
420
421static int __init setup_noirqdistrib(char *str) 433static int __init setup_noirqdistrib(char *str)
422{ 434{
423 distribute_irqs = 0; 435 distribute_irqs = 0;
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index cfab48566db1..258039fb3016 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Kernel Probes (KProbes) 2 * Kernel Probes (KProbes)
3 * arch/ppc64/kernel/kprobes.c
4 * 3 *
5 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 22d83d4d1af5..9feeeef5a875 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -147,15 +147,12 @@ postcore_initcall(of_bus_driver_init);
147 147
148int of_register_driver(struct of_platform_driver *drv) 148int of_register_driver(struct of_platform_driver *drv)
149{ 149{
150 int count = 0;
151
152 /* initialize common driver fields */ 150 /* initialize common driver fields */
153 drv->driver.name = drv->name; 151 drv->driver.name = drv->name;
154 drv->driver.bus = &of_platform_bus_type; 152 drv->driver.bus = &of_platform_bus_type;
155 153
156 /* register with core */ 154 /* register with core */
157 count = driver_register(&drv->driver); 155 return driver_register(&drv->driver);
158 return count ? count : 1;
159} 156}
160 157
161void of_unregister_driver(struct of_platform_driver *drv) 158void of_unregister_driver(struct of_platform_driver *drv)
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index c367520bc1c3..ba92bab7cc2c 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -589,7 +589,6 @@ void __devinit scan_phb(struct pci_controller *hose)
589#endif /* CONFIG_PPC_MULTIPLATFORM */ 589#endif /* CONFIG_PPC_MULTIPLATFORM */
590 if (mode == PCI_PROBE_NORMAL) 590 if (mode == PCI_PROBE_NORMAL)
591 hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); 591 hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
592 pci_bus_add_devices(bus);
593} 592}
594 593
595static int __init pcibios_init(void) 594static int __init pcibios_init(void)
@@ -608,8 +607,10 @@ static int __init pcibios_init(void)
608 printk("PCI: Probing PCI hardware\n"); 607 printk("PCI: Probing PCI hardware\n");
609 608
610 /* Scan all of the recorded PCI controllers. */ 609 /* Scan all of the recorded PCI controllers. */
611 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) 610 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
612 scan_phb(hose); 611 scan_phb(hose);
612 pci_bus_add_devices(hose->bus);
613 }
613 614
614#ifndef CONFIG_PPC_ISERIES 615#ifndef CONFIG_PPC_ISERIES
615 if (pci_probe_only) 616 if (pci_probe_only)
diff --git a/arch/powerpc/kernel/pci_iommu.c b/arch/powerpc/kernel/pci_iommu.c
index bdf15dbbf4f0..c336f3e31cff 100644
--- a/arch/powerpc/kernel/pci_iommu.c
+++ b/arch/powerpc/kernel/pci_iommu.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/pci_iommu.c
3 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation 2 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
4 * 3 *
5 * Rewrite, cleanup, new allocation schemes: 4 * Rewrite, cleanup, new allocation schemes:
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 8a731ea877b7..dfa5398ab3c8 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -57,7 +57,6 @@ extern void machine_check_exception(struct pt_regs *regs);
57extern void alignment_exception(struct pt_regs *regs); 57extern void alignment_exception(struct pt_regs *regs);
58extern void program_check_exception(struct pt_regs *regs); 58extern void program_check_exception(struct pt_regs *regs);
59extern void single_step_exception(struct pt_regs *regs); 59extern void single_step_exception(struct pt_regs *regs);
60extern int pmac_newworld;
61extern int sys_sigreturn(struct pt_regs *regs); 60extern int sys_sigreturn(struct pt_regs *regs);
62 61
63EXPORT_SYMBOL(clear_pages); 62EXPORT_SYMBOL(clear_pages);
@@ -110,15 +109,6 @@ EXPORT_SYMBOL(_insw_ns);
110EXPORT_SYMBOL(_outsw_ns); 109EXPORT_SYMBOL(_outsw_ns);
111EXPORT_SYMBOL(_insl_ns); 110EXPORT_SYMBOL(_insl_ns);
112EXPORT_SYMBOL(_outsl_ns); 111EXPORT_SYMBOL(_outsl_ns);
113EXPORT_SYMBOL(ioremap);
114#ifdef CONFIG_44x
115EXPORT_SYMBOL(ioremap64);
116#endif
117EXPORT_SYMBOL(__ioremap);
118EXPORT_SYMBOL(iounmap);
119#ifdef CONFIG_PPC32
120EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
121#endif
122 112
123#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)) 113#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE))
124EXPORT_SYMBOL(ppc_ide_md); 114EXPORT_SYMBOL(ppc_ide_md);
@@ -161,7 +151,6 @@ EXPORT_SYMBOL(__flush_icache_range);
161EXPORT_SYMBOL(flush_dcache_range); 151EXPORT_SYMBOL(flush_dcache_range);
162 152
163#ifdef CONFIG_SMP 153#ifdef CONFIG_SMP
164EXPORT_SYMBOL(smp_call_function);
165#ifdef CONFIG_PPC32 154#ifdef CONFIG_PPC32
166EXPORT_SYMBOL(smp_hw_index); 155EXPORT_SYMBOL(smp_hw_index);
167#endif 156#endif
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index c225cf154bfe..1770a066c217 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc/kernel/process.c
3 *
4 * Derived from "arch/i386/kernel/process.c" 2 * Derived from "arch/i386/kernel/process.c"
5 * Copyright (C) 1995 Linus Torvalds 3 * Copyright (C) 1995 Linus Torvalds
6 * 4 *
@@ -47,9 +45,9 @@
47#include <asm/mmu.h> 45#include <asm/mmu.h>
48#include <asm/prom.h> 46#include <asm/prom.h>
49#include <asm/machdep.h> 47#include <asm/machdep.h>
48#include <asm/time.h>
50#ifdef CONFIG_PPC64 49#ifdef CONFIG_PPC64
51#include <asm/firmware.h> 50#include <asm/firmware.h>
52#include <asm/time.h>
53#endif 51#endif
54 52
55extern unsigned long _get_SP(void); 53extern unsigned long _get_SP(void);
@@ -330,6 +328,11 @@ struct task_struct *__switch_to(struct task_struct *prev,
330#endif 328#endif
331 329
332 local_irq_save(flags); 330 local_irq_save(flags);
331
332 account_system_vtime(current);
333 account_process_vtime(current);
334 calculate_steal_time();
335
333 last = _switch(old_thread, new_thread); 336 last = _switch(old_thread, new_thread);
334 337
335 local_irq_restore(flags); 338 local_irq_restore(flags);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 294832a7e0a6..d63cd562d9d5 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -816,8 +816,6 @@ void __init unflatten_device_tree(void)
816{ 816{
817 unsigned long start, mem, size; 817 unsigned long start, mem, size;
818 struct device_node **allnextp = &allnodes; 818 struct device_node **allnextp = &allnodes;
819 char *p = NULL;
820 int l = 0;
821 819
822 DBG(" -> unflatten_device_tree()\n"); 820 DBG(" -> unflatten_device_tree()\n");
823 821
@@ -831,10 +829,6 @@ void __init unflatten_device_tree(void)
831 829
832 /* Allocate memory for the expanded device tree */ 830 /* Allocate memory for the expanded device tree */
833 mem = lmb_alloc(size + 4, __alignof__(struct device_node)); 831 mem = lmb_alloc(size + 4, __alignof__(struct device_node));
834 if (!mem) {
835 DBG("Couldn't allocate memory with lmb_alloc()!\n");
836 panic("Couldn't allocate memory with lmb_alloc()!\n");
837 }
838 mem = (unsigned long) __va(mem); 832 mem = (unsigned long) __va(mem);
839 833
840 ((u32 *)mem)[size / 4] = 0xdeadbeef; 834 ((u32 *)mem)[size / 4] = 0xdeadbeef;
@@ -857,19 +851,6 @@ void __init unflatten_device_tree(void)
857 if (of_chosen == NULL) 851 if (of_chosen == NULL)
858 of_chosen = of_find_node_by_path("/chosen@0"); 852 of_chosen = of_find_node_by_path("/chosen@0");
859 853
860 /* Retreive command line */
861 if (of_chosen != NULL) {
862 p = (char *)get_property(of_chosen, "bootargs", &l);
863 if (p != NULL && l > 0)
864 strlcpy(cmd_line, p, min(l, COMMAND_LINE_SIZE));
865 }
866#ifdef CONFIG_CMDLINE
867 if (l == 0 || (l == 1 && (*p) == 0))
868 strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
869#endif /* CONFIG_CMDLINE */
870
871 DBG("Command line is: %s\n", cmd_line);
872
873 DBG(" <- unflatten_device_tree()\n"); 854 DBG(" <- unflatten_device_tree()\n");
874} 855}
875 856
@@ -940,6 +921,8 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
940{ 921{
941 u32 *prop; 922 u32 *prop;
942 unsigned long *lprop; 923 unsigned long *lprop;
924 unsigned long l;
925 char *p;
943 926
944 DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname); 927 DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
945 928
@@ -1004,6 +987,41 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
1004 crashk_res.end = crashk_res.start + *lprop - 1; 987 crashk_res.end = crashk_res.start + *lprop - 1;
1005#endif 988#endif
1006 989
990 /* Retreive command line */
991 p = of_get_flat_dt_prop(node, "bootargs", &l);
992 if (p != NULL && l > 0)
993 strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE));
994
995#ifdef CONFIG_CMDLINE
996 if (l == 0 || (l == 1 && (*p) == 0))
997 strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
998#endif /* CONFIG_CMDLINE */
999
1000 DBG("Command line is: %s\n", cmd_line);
1001
1002 if (strstr(cmd_line, "mem=")) {
1003 char *p, *q;
1004 unsigned long maxmem = 0;
1005
1006 for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) {
1007 q = p + 4;
1008 if (p > cmd_line && p[-1] != ' ')
1009 continue;
1010 maxmem = simple_strtoul(q, &q, 0);
1011 if (*q == 'k' || *q == 'K') {
1012 maxmem <<= 10;
1013 ++q;
1014 } else if (*q == 'm' || *q == 'M') {
1015 maxmem <<= 20;
1016 ++q;
1017 } else if (*q == 'g' || *q == 'G') {
1018 maxmem <<= 30;
1019 ++q;
1020 }
1021 }
1022 memory_limit = maxmem;
1023 }
1024
1007 /* break now */ 1025 /* break now */
1008 return 1; 1026 return 1;
1009} 1027}
@@ -1124,7 +1142,7 @@ static void __init early_reserve_mem(void)
1124 size_32 = *(reserve_map_32++); 1142 size_32 = *(reserve_map_32++);
1125 if (size_32 == 0) 1143 if (size_32 == 0)
1126 break; 1144 break;
1127 DBG("reserving: %lx -> %lx\n", base_32, size_32); 1145 DBG("reserving: %x -> %x\n", base_32, size_32);
1128 lmb_reserve(base_32, size_32); 1146 lmb_reserve(base_32, size_32);
1129 } 1147 }
1130 return; 1148 return;
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index d34fe537400e..813c2cd194c2 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -978,7 +978,7 @@ static void __init prom_init_mem(void)
978 if (size == 0) 978 if (size == 0)
979 continue; 979 continue;
980 prom_debug(" %x %x\n", base, size); 980 prom_debug(" %x %x\n", base, size);
981 if (base == 0) 981 if (base == 0 && (RELOC(of_platform) & PLATFORM_LPAR))
982 RELOC(rmo_top) = size; 982 RELOC(rmo_top) = size;
983 if ((base + size) > RELOC(ram_top)) 983 if ((base + size) > RELOC(ram_top))
984 RELOC(ram_top) = base + size; 984 RELOC(ram_top) = base + size;
diff --git a/arch/powerpc/kernel/ptrace-common.h b/arch/powerpc/kernel/ptrace-common.h
index 5ccbdbe0d5c9..c42a860c8d25 100644
--- a/arch/powerpc/kernel/ptrace-common.h
+++ b/arch/powerpc/kernel/ptrace-common.h
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/ppc64/kernel/ptrace-common.h
3 *
4 * Copyright (c) 2002 Stephen Rothwell, IBM Coproration 2 * Copyright (c) 2002 Stephen Rothwell, IBM Coproration
5 * Extracted from ptrace.c and ptrace32.c 3 * Extracted from ptrace.c and ptrace32.c
6 * 4 *
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 400793c71304..bcb83574335b 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -561,10 +561,7 @@ void do_syscall_trace_leave(struct pt_regs *regs)
561 regs->result); 561 regs->result);
562 562
563 if ((test_thread_flag(TIF_SYSCALL_TRACE) 563 if ((test_thread_flag(TIF_SYSCALL_TRACE)
564#ifdef CONFIG_PPC64 564 || test_thread_flag(TIF_SINGLESTEP))
565 || test_thread_flag(TIF_SINGLESTEP)
566#endif
567 )
568 && (current->ptrace & PT_PTRACED)) 565 && (current->ptrace & PT_PTRACED))
569 do_syscall_trace(); 566 do_syscall_trace();
570} 567}
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
index 7a95b8a28354..1f03fb28cc0a 100644
--- a/arch/powerpc/kernel/rtas-proc.c
+++ b/arch/powerpc/kernel/rtas-proc.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/rtas-proc.c
3 * Copyright (C) 2000 Tilmann Bitterberg 2 * Copyright (C) 2000 Tilmann Bitterberg
4 * (tilmann@bitterberg.de) 3 * (tilmann@bitterberg.de)
5 * 4 *
diff --git a/arch/powerpc/kernel/rtas-rtc.c b/arch/powerpc/kernel/rtas-rtc.c
index 635d3b9a8811..34d073fb6091 100644
--- a/arch/powerpc/kernel/rtas-rtc.c
+++ b/arch/powerpc/kernel/rtas-rtc.c
@@ -52,7 +52,7 @@ void rtas_get_rtc_time(struct rtc_time *rtc_tm)
52 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); 52 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
53 if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { 53 if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
54 if (in_interrupt() && printk_ratelimit()) { 54 if (in_interrupt() && printk_ratelimit()) {
55 memset(&rtc_tm, 0, sizeof(struct rtc_time)); 55 memset(rtc_tm, 0, sizeof(struct rtc_time));
56 printk(KERN_WARNING "error: reading clock" 56 printk(KERN_WARNING "error: reading clock"
57 " would delay interrupt\n"); 57 " would delay interrupt\n");
58 return; /* delay not allowed */ 58 return; /* delay not allowed */
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 5579f6559912..57b539a03fa9 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/ppc64/kernel/rtas_pci.c
3 *
4 * Copyright (C) 2001 Dave Engebretsen, IBM Corporation 2 * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
5 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM 3 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
6 * 4 *
@@ -280,8 +278,7 @@ static int phb_set_bus_ranges(struct device_node *dev,
280 return 0; 278 return 0;
281} 279}
282 280
283static int __devinit setup_phb(struct device_node *dev, 281int __devinit setup_phb(struct device_node *dev, struct pci_controller *phb)
284 struct pci_controller *phb)
285{ 282{
286 if (is_python(dev)) 283 if (is_python(dev))
287 python_countermeasures(dev); 284 python_countermeasures(dev);
@@ -359,27 +356,6 @@ unsigned long __init find_and_init_phbs(void)
359 return 0; 356 return 0;
360} 357}
361 358
362struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
363{
364 struct pci_controller *phb;
365 int primary;
366
367 primary = list_empty(&hose_list);
368 phb = pcibios_alloc_controller(dn);
369 if (!phb)
370 return NULL;
371 setup_phb(dn, phb);
372 pci_process_bridge_OF_ranges(phb, dn, primary);
373
374 pci_setup_phb_io_dynamic(phb, primary);
375
376 pci_devs_phb_init_dynamic(phb);
377 scan_phb(phb);
378
379 return phb;
380}
381EXPORT_SYMBOL(init_phb_dynamic);
382
383/* RPA-specific bits for removing PHBs */ 359/* RPA-specific bits for removing PHBs */
384int pcibios_remove_root_bus(struct pci_controller *phb) 360int pcibios_remove_root_bus(struct pci_controller *phb)
385{ 361{
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index f96c49b03ba0..2f3fdad35594 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -497,8 +497,6 @@ void __init setup_system(void)
497#endif 497#endif
498 printk("-----------------------------------------------------\n"); 498 printk("-----------------------------------------------------\n");
499 499
500 mm_init_ppc64();
501
502 DBG(" <- setup_system()\n"); 500 DBG(" <- setup_system()\n");
503} 501}
504 502
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index bd837b5dbf06..d7a4e814974d 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -151,10 +151,7 @@ static inline int save_general_regs(struct pt_regs *regs,
151 elf_greg_t64 *gregs = (elf_greg_t64 *)regs; 151 elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
152 int i; 152 int i;
153 153
154 if (!FULL_REGS(regs)) { 154 WARN_ON(!FULL_REGS(regs));
155 set_thread_flag(TIF_SAVE_NVGPRS);
156 current_thread_info()->nvgprs_frame = frame->mc_gregs;
157 }
158 155
159 for (i = 0; i <= PT_RESULT; i ++) { 156 for (i = 0; i <= PT_RESULT; i ++) {
160 if (i == 14 && !FULL_REGS(regs)) 157 if (i == 14 && !FULL_REGS(regs))
@@ -215,15 +212,7 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka,
215static inline int save_general_regs(struct pt_regs *regs, 212static inline int save_general_regs(struct pt_regs *regs,
216 struct mcontext __user *frame) 213 struct mcontext __user *frame)
217{ 214{
218 if (!FULL_REGS(regs)) { 215 WARN_ON(!FULL_REGS(regs));
219 /* Zero out the unsaved GPRs to avoid information
220 leak, and set TIF_SAVE_NVGPRS to ensure that the
221 registers do actually get saved later. */
222 memset(&regs->gpr[14], 0, 18 * sizeof(unsigned long));
223 current_thread_info()->nvgprs_frame = &frame->mc_gregs;
224 set_thread_flag(TIF_SAVE_NVGPRS);
225 }
226
227 return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE); 216 return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE);
228} 217}
229 218
@@ -826,8 +815,8 @@ static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int
826} 815}
827 816
828long sys_swapcontext(struct ucontext __user *old_ctx, 817long sys_swapcontext(struct ucontext __user *old_ctx,
829 struct ucontext __user *new_ctx, 818 struct ucontext __user *new_ctx,
830 int ctx_size, int r6, int r7, int r8, struct pt_regs *regs) 819 int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
831{ 820{
832 unsigned char tmp; 821 unsigned char tmp;
833 822
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 497a5d3df359..47f910380a6a 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/ppc64/kernel/signal.c
3 *
4 * PowerPC version 2 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 * 4 *
@@ -118,14 +116,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
118 err |= __put_user(0, &sc->v_regs); 116 err |= __put_user(0, &sc->v_regs);
119#endif /* CONFIG_ALTIVEC */ 117#endif /* CONFIG_ALTIVEC */
120 err |= __put_user(&sc->gp_regs, &sc->regs); 118 err |= __put_user(&sc->gp_regs, &sc->regs);
121 if (!FULL_REGS(regs)) { 119 WARN_ON(!FULL_REGS(regs));
122 /* Zero out the unsaved GPRs to avoid information
123 leak, and set TIF_SAVE_NVGPRS to ensure that the
124 registers do actually get saved later. */
125 memset(&regs->gpr[14], 0, 18 * sizeof(unsigned long));
126 set_thread_flag(TIF_SAVE_NVGPRS);
127 current_thread_info()->nvgprs_frame = &sc->gp_regs;
128 }
129 err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE); 120 err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
130 err |= __copy_to_user(&sc->fp_regs, &current->thread.fpr, FP_REGS_SIZE); 121 err |= __copy_to_user(&sc->fp_regs, &current->thread.fpr, FP_REGS_SIZE);
131 err |= __put_user(signr, &sc->signal); 122 err |= __put_user(signr, &sc->signal);
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 13595a64f013..805eaedbc308 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -541,7 +541,7 @@ int __devinit start_secondary(void *unused)
541 smp_ops->take_timebase(); 541 smp_ops->take_timebase();
542 542
543 if (system_state > SYSTEM_BOOTING) 543 if (system_state > SYSTEM_BOOTING)
544 per_cpu(last_jiffy, cpu) = get_tb(); 544 snapshot_timebase();
545 545
546 spin_lock(&call_lock); 546 spin_lock(&call_lock);
547 cpu_set(cpu, cpu_online_map); 547 cpu_set(cpu, cpu_online_map);
@@ -573,6 +573,8 @@ void __init smp_cpus_done(unsigned int max_cpus)
573 573
574 set_cpus_allowed(current, old_mask); 574 set_cpus_allowed(current, old_mask);
575 575
576 snapshot_timebases();
577
576 dump_numa_cpu_topology(); 578 dump_numa_cpu_topology();
577} 579}
578 580
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 8a9f994ed917..1ad55f0466fd 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -288,7 +288,7 @@ COMPAT_SYS(clock_settime)
288COMPAT_SYS(clock_gettime) 288COMPAT_SYS(clock_gettime)
289COMPAT_SYS(clock_getres) 289COMPAT_SYS(clock_getres)
290COMPAT_SYS(clock_nanosleep) 290COMPAT_SYS(clock_nanosleep)
291COMPAT_SYS(swapcontext) 291SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext)
292COMPAT_SYS(tgkill) 292COMPAT_SYS(tgkill)
293COMPAT_SYS(utimes) 293COMPAT_SYS(utimes)
294COMPAT_SYS(statfs64) 294COMPAT_SYS(statfs64)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 2a7ddc579379..4a27218a086c 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -51,6 +51,7 @@
51#include <linux/percpu.h> 51#include <linux/percpu.h>
52#include <linux/rtc.h> 52#include <linux/rtc.h>
53#include <linux/jiffies.h> 53#include <linux/jiffies.h>
54#include <linux/posix-timers.h>
54 55
55#include <asm/io.h> 56#include <asm/io.h>
56#include <asm/processor.h> 57#include <asm/processor.h>
@@ -98,6 +99,7 @@ unsigned long tb_ticks_per_jiffy;
98unsigned long tb_ticks_per_usec = 100; /* sane default */ 99unsigned long tb_ticks_per_usec = 100; /* sane default */
99EXPORT_SYMBOL(tb_ticks_per_usec); 100EXPORT_SYMBOL(tb_ticks_per_usec);
100unsigned long tb_ticks_per_sec; 101unsigned long tb_ticks_per_sec;
102EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime_t conversions */
101u64 tb_to_xs; 103u64 tb_to_xs;
102unsigned tb_to_us; 104unsigned tb_to_us;
103 105
@@ -135,6 +137,224 @@ unsigned long tb_last_stamp;
135 */ 137 */
136DEFINE_PER_CPU(unsigned long, last_jiffy); 138DEFINE_PER_CPU(unsigned long, last_jiffy);
137 139
140#ifdef CONFIG_VIRT_CPU_ACCOUNTING
141/*
142 * Factors for converting from cputime_t (timebase ticks) to
143 * jiffies, milliseconds, seconds, and clock_t (1/USER_HZ seconds).
144 * These are all stored as 0.64 fixed-point binary fractions.
145 */
146u64 __cputime_jiffies_factor;
147EXPORT_SYMBOL(__cputime_jiffies_factor);
148u64 __cputime_msec_factor;
149EXPORT_SYMBOL(__cputime_msec_factor);
150u64 __cputime_sec_factor;
151EXPORT_SYMBOL(__cputime_sec_factor);
152u64 __cputime_clockt_factor;
153EXPORT_SYMBOL(__cputime_clockt_factor);
154
155static void calc_cputime_factors(void)
156{
157 struct div_result res;
158
159 div128_by_32(HZ, 0, tb_ticks_per_sec, &res);
160 __cputime_jiffies_factor = res.result_low;
161 div128_by_32(1000, 0, tb_ticks_per_sec, &res);
162 __cputime_msec_factor = res.result_low;
163 div128_by_32(1, 0, tb_ticks_per_sec, &res);
164 __cputime_sec_factor = res.result_low;
165 div128_by_32(USER_HZ, 0, tb_ticks_per_sec, &res);
166 __cputime_clockt_factor = res.result_low;
167}
168
169/*
170 * Read the PURR on systems that have it, otherwise the timebase.
171 */
172static u64 read_purr(void)
173{
174 if (cpu_has_feature(CPU_FTR_PURR))
175 return mfspr(SPRN_PURR);
176 return mftb();
177}
178
179/*
180 * Account time for a transition between system, hard irq
181 * or soft irq state.
182 */
183void account_system_vtime(struct task_struct *tsk)
184{
185 u64 now, delta;
186 unsigned long flags;
187
188 local_irq_save(flags);
189 now = read_purr();
190 delta = now - get_paca()->startpurr;
191 get_paca()->startpurr = now;
192 if (!in_interrupt()) {
193 delta += get_paca()->system_time;
194 get_paca()->system_time = 0;
195 }
196 account_system_time(tsk, 0, delta);
197 local_irq_restore(flags);
198}
199
200/*
201 * Transfer the user and system times accumulated in the paca
202 * by the exception entry and exit code to the generic process
203 * user and system time records.
204 * Must be called with interrupts disabled.
205 */
206void account_process_vtime(struct task_struct *tsk)
207{
208 cputime_t utime;
209
210 utime = get_paca()->user_time;
211 get_paca()->user_time = 0;
212 account_user_time(tsk, utime);
213}
214
215static void account_process_time(struct pt_regs *regs)
216{
217 int cpu = smp_processor_id();
218
219 account_process_vtime(current);
220 run_local_timers();
221 if (rcu_pending(cpu))
222 rcu_check_callbacks(cpu, user_mode(regs));
223 scheduler_tick();
224 run_posix_cpu_timers(current);
225}
226
227#ifdef CONFIG_PPC_SPLPAR
228/*
229 * Stuff for accounting stolen time.
230 */
231struct cpu_purr_data {
232 int initialized; /* thread is running */
233 u64 tb0; /* timebase at origin time */
234 u64 purr0; /* PURR at origin time */
235 u64 tb; /* last TB value read */
236 u64 purr; /* last PURR value read */
237 u64 stolen; /* stolen time so far */
238 spinlock_t lock;
239};
240
241static DEFINE_PER_CPU(struct cpu_purr_data, cpu_purr_data);
242
243static void snapshot_tb_and_purr(void *data)
244{
245 struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data);
246
247 p->tb0 = mftb();
248 p->purr0 = mfspr(SPRN_PURR);
249 p->tb = p->tb0;
250 p->purr = 0;
251 wmb();
252 p->initialized = 1;
253}
254
255/*
256 * Called during boot when all cpus have come up.
257 */
258void snapshot_timebases(void)
259{
260 int cpu;
261
262 if (!cpu_has_feature(CPU_FTR_PURR))
263 return;
264 for_each_cpu(cpu)
265 spin_lock_init(&per_cpu(cpu_purr_data, cpu).lock);
266 on_each_cpu(snapshot_tb_and_purr, NULL, 0, 1);
267}
268
269void calculate_steal_time(void)
270{
271 u64 tb, purr, t0;
272 s64 stolen;
273 struct cpu_purr_data *p0, *pme, *phim;
274 int cpu;
275
276 if (!cpu_has_feature(CPU_FTR_PURR))
277 return;
278 cpu = smp_processor_id();
279 pme = &per_cpu(cpu_purr_data, cpu);
280 if (!pme->initialized)
281 return; /* this can happen in early boot */
282 p0 = &per_cpu(cpu_purr_data, cpu & ~1);
283 phim = &per_cpu(cpu_purr_data, cpu ^ 1);
284 spin_lock(&p0->lock);
285 tb = mftb();
286 purr = mfspr(SPRN_PURR) - pme->purr0;
287 if (!phim->initialized || !cpu_online(cpu ^ 1)) {
288 stolen = (tb - pme->tb) - (purr - pme->purr);
289 } else {
290 t0 = pme->tb0;
291 if (phim->tb0 < t0)
292 t0 = phim->tb0;
293 stolen = phim->tb - t0 - phim->purr - purr - p0->stolen;
294 }
295 if (stolen > 0) {
296 account_steal_time(current, stolen);
297 p0->stolen += stolen;
298 }
299 pme->tb = tb;
300 pme->purr = purr;
301 spin_unlock(&p0->lock);
302}
303
304/*
305 * Must be called before the cpu is added to the online map when
306 * a cpu is being brought up at runtime.
307 */
308static void snapshot_purr(void)
309{
310 int cpu;
311 u64 purr;
312 struct cpu_purr_data *p0, *pme, *phim;
313 unsigned long flags;
314
315 if (!cpu_has_feature(CPU_FTR_PURR))
316 return;
317 cpu = smp_processor_id();
318 pme = &per_cpu(cpu_purr_data, cpu);
319 p0 = &per_cpu(cpu_purr_data, cpu & ~1);
320 phim = &per_cpu(cpu_purr_data, cpu ^ 1);
321 spin_lock_irqsave(&p0->lock, flags);
322 pme->tb = pme->tb0 = mftb();
323 purr = mfspr(SPRN_PURR);
324 if (!phim->initialized) {
325 pme->purr = 0;
326 pme->purr0 = purr;
327 } else {
328 /* set p->purr and p->purr0 for no change in p0->stolen */
329 pme->purr = phim->tb - phim->tb0 - phim->purr - p0->stolen;
330 pme->purr0 = purr - pme->purr;
331 }
332 pme->initialized = 1;
333 spin_unlock_irqrestore(&p0->lock, flags);
334}
335
336#endif /* CONFIG_PPC_SPLPAR */
337
338#else /* ! CONFIG_VIRT_CPU_ACCOUNTING */
339#define calc_cputime_factors()
340#define account_process_time(regs) update_process_times(user_mode(regs))
341#define calculate_steal_time() do { } while (0)
342#endif
343
344#if !(defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(CONFIG_PPC_SPLPAR))
345#define snapshot_purr() do { } while (0)
346#endif
347
348/*
349 * Called when a cpu comes up after the system has finished booting,
350 * i.e. as a result of a hotplug cpu action.
351 */
352void snapshot_timebase(void)
353{
354 __get_cpu_var(last_jiffy) = get_tb();
355 snapshot_purr();
356}
357
138void __delay(unsigned long loops) 358void __delay(unsigned long loops)
139{ 359{
140 unsigned long start; 360 unsigned long start;
@@ -283,9 +503,9 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
283 * the two values of tb_update_count match and are even then the 503 * the two values of tb_update_count match and are even then the
284 * tb_to_xs and stamp_xsec values are consistent. If not, then it 504 * tb_to_xs and stamp_xsec values are consistent. If not, then it
285 * loops back and reads them again until this criteria is met. 505 * loops back and reads them again until this criteria is met.
506 * We expect the caller to have done the first increment of
507 * vdso_data->tb_update_count already.
286 */ 508 */
287 ++(vdso_data->tb_update_count);
288 smp_wmb();
289 vdso_data->tb_orig_stamp = new_tb_stamp; 509 vdso_data->tb_orig_stamp = new_tb_stamp;
290 vdso_data->stamp_xsec = new_stamp_xsec; 510 vdso_data->stamp_xsec = new_stamp_xsec;
291 vdso_data->tb_to_xs = new_tb_to_xs; 511 vdso_data->tb_to_xs = new_tb_to_xs;
@@ -310,20 +530,15 @@ static __inline__ void timer_recalc_offset(u64 cur_tb)
310 unsigned long offset; 530 unsigned long offset;
311 u64 new_stamp_xsec; 531 u64 new_stamp_xsec;
312 u64 tlen, t2x; 532 u64 tlen, t2x;
533 u64 tb, xsec_old, xsec_new;
534 struct gettimeofday_vars *varp;
313 535
314 if (__USE_RTC()) 536 if (__USE_RTC())
315 return; 537 return;
316 tlen = current_tick_length(); 538 tlen = current_tick_length();
317 offset = cur_tb - do_gtod.varp->tb_orig_stamp; 539 offset = cur_tb - do_gtod.varp->tb_orig_stamp;
318 if (tlen == last_tick_len && offset < 0x80000000u) { 540 if (tlen == last_tick_len && offset < 0x80000000u)
319 /* check that we're still in sync; if not, resync */ 541 return;
320 struct timeval tv;
321 __do_gettimeofday(&tv, cur_tb);
322 if (tv.tv_sec <= xtime.tv_sec &&
323 (tv.tv_sec < xtime.tv_sec ||
324 tv.tv_usec * 1000 <= xtime.tv_nsec))
325 return;
326 }
327 if (tlen != last_tick_len) { 542 if (tlen != last_tick_len) {
328 t2x = mulhdu(tlen << TICKLEN_SHIFT, ticklen_to_xs); 543 t2x = mulhdu(tlen << TICKLEN_SHIFT, ticklen_to_xs);
329 last_tick_len = tlen; 544 last_tick_len = tlen;
@@ -332,6 +547,21 @@ static __inline__ void timer_recalc_offset(u64 cur_tb)
332 new_stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC; 547 new_stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC;
333 do_div(new_stamp_xsec, 1000000000); 548 do_div(new_stamp_xsec, 1000000000);
334 new_stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC; 549 new_stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC;
550
551 ++vdso_data->tb_update_count;
552 smp_mb();
553
554 /*
555 * Make sure time doesn't go backwards for userspace gettimeofday.
556 */
557 tb = get_tb();
558 varp = do_gtod.varp;
559 xsec_old = mulhdu(tb - varp->tb_orig_stamp, varp->tb_to_xs)
560 + varp->stamp_xsec;
561 xsec_new = mulhdu(tb - cur_tb, t2x) + new_stamp_xsec;
562 if (xsec_new < xsec_old)
563 new_stamp_xsec += xsec_old - xsec_new;
564
335 update_gtod(cur_tb, new_stamp_xsec, t2x); 565 update_gtod(cur_tb, new_stamp_xsec, t2x);
336} 566}
337 567
@@ -382,6 +612,7 @@ static void iSeries_tb_recal(void)
382 new_tb_ticks_per_jiffy, sign, tick_diff ); 612 new_tb_ticks_per_jiffy, sign, tick_diff );
383 tb_ticks_per_jiffy = new_tb_ticks_per_jiffy; 613 tb_ticks_per_jiffy = new_tb_ticks_per_jiffy;
384 tb_ticks_per_sec = new_tb_ticks_per_sec; 614 tb_ticks_per_sec = new_tb_ticks_per_sec;
615 calc_cputime_factors();
385 div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres ); 616 div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres );
386 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; 617 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
387 tb_to_xs = divres.result_low; 618 tb_to_xs = divres.result_low;
@@ -430,6 +661,7 @@ void timer_interrupt(struct pt_regs * regs)
430 irq_enter(); 661 irq_enter();
431 662
432 profile_tick(CPU_PROFILING, regs); 663 profile_tick(CPU_PROFILING, regs);
664 calculate_steal_time();
433 665
434#ifdef CONFIG_PPC_ISERIES 666#ifdef CONFIG_PPC_ISERIES
435 get_lppaca()->int_dword.fields.decr_int = 0; 667 get_lppaca()->int_dword.fields.decr_int = 0;
@@ -451,7 +683,7 @@ void timer_interrupt(struct pt_regs * regs)
451 * is the case. 683 * is the case.
452 */ 684 */
453 if (!cpu_is_offline(cpu)) 685 if (!cpu_is_offline(cpu))
454 update_process_times(user_mode(regs)); 686 account_process_time(regs);
455 687
456 /* 688 /*
457 * No need to check whether cpu is offline here; boot_cpuid 689 * No need to check whether cpu is offline here; boot_cpuid
@@ -508,13 +740,27 @@ void wakeup_decrementer(void)
508void __init smp_space_timers(unsigned int max_cpus) 740void __init smp_space_timers(unsigned int max_cpus)
509{ 741{
510 int i; 742 int i;
743 unsigned long half = tb_ticks_per_jiffy / 2;
511 unsigned long offset = tb_ticks_per_jiffy / max_cpus; 744 unsigned long offset = tb_ticks_per_jiffy / max_cpus;
512 unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid); 745 unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid);
513 746
514 /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */ 747 /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */
515 previous_tb -= tb_ticks_per_jiffy; 748 previous_tb -= tb_ticks_per_jiffy;
749 /*
750 * The stolen time calculation for POWER5 shared-processor LPAR
751 * systems works better if the two threads' timebase interrupts
752 * are staggered by half a jiffy with respect to each other.
753 */
516 for_each_cpu(i) { 754 for_each_cpu(i) {
517 if (i != boot_cpuid) { 755 if (i == boot_cpuid)
756 continue;
757 if (i == (boot_cpuid ^ 1))
758 per_cpu(last_jiffy, i) =
759 per_cpu(last_jiffy, boot_cpuid) - half;
760 else if (i & 1)
761 per_cpu(last_jiffy, i) =
762 per_cpu(last_jiffy, i ^ 1) + half;
763 else {
518 previous_tb += offset; 764 previous_tb += offset;
519 per_cpu(last_jiffy, i) = previous_tb; 765 per_cpu(last_jiffy, i) = previous_tb;
520 } 766 }
@@ -564,6 +810,10 @@ int do_settimeofday(struct timespec *tv)
564 } 810 }
565#endif 811#endif
566 812
813 /* Make userspace gettimeofday spin until we're done. */
814 ++vdso_data->tb_update_count;
815 smp_mb();
816
567 /* 817 /*
568 * Subtract off the number of nanoseconds since the 818 * Subtract off the number of nanoseconds since the
569 * beginning of the last tick. 819 * beginning of the last tick.
@@ -706,6 +956,7 @@ void __init time_init(void)
706 tb_ticks_per_sec = ppc_tb_freq; 956 tb_ticks_per_sec = ppc_tb_freq;
707 tb_ticks_per_usec = ppc_tb_freq / 1000000; 957 tb_ticks_per_usec = ppc_tb_freq / 1000000;
708 tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000); 958 tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
959 calc_cputime_factors();
709 960
710 /* 961 /*
711 * Calculate the length of each tick in ns. It will not be 962 * Calculate the length of each tick in ns. It will not be
@@ -724,10 +975,16 @@ void __init time_init(void)
724 * It is computed as: 975 * It is computed as:
725 * ticklen_to_xs = 2^N / (tb_ticks_per_jiffy * 1e9) 976 * ticklen_to_xs = 2^N / (tb_ticks_per_jiffy * 1e9)
726 * where N = 64 + 20 - TICKLEN_SCALE - TICKLEN_SHIFT 977 * where N = 64 + 20 - TICKLEN_SCALE - TICKLEN_SHIFT
727 * so as to give the result as a 0.64 fixed-point fraction. 978 * which turns out to be N = 51 - SHIFT_HZ.
979 * This gives the result as a 0.64 fixed-point fraction.
980 * That value is reduced by an offset amounting to 1 xsec per
981 * 2^31 timebase ticks to avoid problems with time going backwards
982 * by 1 xsec when we do timer_recalc_offset due to losing the
983 * fractional xsec. That offset is equal to ppc_tb_freq/2^51
984 * since there are 2^20 xsec in a second.
728 */ 985 */
729 div128_by_32(1ULL << (64 + 20 - TICKLEN_SCALE - TICKLEN_SHIFT), 0, 986 div128_by_32((1ULL << 51) - ppc_tb_freq, 0,
730 tb_ticks_per_jiffy, &res); 987 tb_ticks_per_jiffy << SHIFT_HZ, &res);
731 div128_by_32(res.result_high, res.result_low, NSEC_PER_SEC, &res); 988 div128_by_32(res.result_high, res.result_low, NSEC_PER_SEC, &res);
732 ticklen_to_xs = res.result_low; 989 ticklen_to_xs = res.result_low;
733 990
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 7509aa6474f2..98660aedeeb7 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -814,6 +814,8 @@ void __kprobes program_check_exception(struct pt_regs *regs)
814 return; 814 return;
815 } 815 }
816 816
817 local_irq_enable();
818
817 /* Try to emulate it if we should. */ 819 /* Try to emulate it if we should. */
818 if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) { 820 if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
819 switch (emulate_instruction(regs)) { 821 switch (emulate_instruction(regs)) {
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index f0c47dab0903..ec8370368423 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/ppc64/kernel/vdso.c
3 *
4 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. 2 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org> 3 * <benh@kernel.crashing.org>
6 * 4 *
@@ -182,8 +180,8 @@ static struct page * vdso_vma_nopage(struct vm_area_struct * vma,
182 unsigned long offset = address - vma->vm_start; 180 unsigned long offset = address - vma->vm_start;
183 struct page *pg; 181 struct page *pg;
184#ifdef CONFIG_PPC64 182#ifdef CONFIG_PPC64
185 void *vbase = test_thread_flag(TIF_32BIT) ? 183 void *vbase = (vma->vm_mm->task_size > TASK_SIZE_USER32) ?
186 vdso32_kbase : vdso64_kbase; 184 vdso64_kbase : vdso32_kbase;
187#else 185#else
188 void *vbase = vdso32_kbase; 186 void *vbase = vdso32_kbase;
189#endif 187#endif
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
index ccaeda5136d1..4ee871f1cadb 100644
--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
@@ -225,9 +225,9 @@ V_FUNCTION_BEGIN(__do_get_xsec)
225 .cfi_startproc 225 .cfi_startproc
226 /* check for update count & load values */ 226 /* check for update count & load values */
2271: ld r8,CFG_TB_UPDATE_COUNT(r3) 2271: ld r8,CFG_TB_UPDATE_COUNT(r3)
228 andi. r0,r4,1 /* pending update ? loop */ 228 andi. r0,r8,1 /* pending update ? loop */
229 bne- 1b 229 bne- 1b
230 xor r0,r4,r4 /* create dependency */ 230 xor r0,r8,r8 /* create dependency */
231 add r3,r3,r0 231 add r3,r3,r0
232 232
233 /* Get TB & offset it */ 233 /* Get TB & offset it */