aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r--arch/powerpc/kernel/process.c69
1 files changed, 48 insertions, 21 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index b1c648a36b03..91e52df3d81d 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -353,6 +353,7 @@ static void switch_booke_debug_regs(struct thread_struct *new_thread)
353 prime_debug_regs(new_thread); 353 prime_debug_regs(new_thread);
354} 354}
355#else /* !CONFIG_PPC_ADV_DEBUG_REGS */ 355#else /* !CONFIG_PPC_ADV_DEBUG_REGS */
356#ifndef CONFIG_HAVE_HW_BREAKPOINT
356static void set_debug_reg_defaults(struct thread_struct *thread) 357static void set_debug_reg_defaults(struct thread_struct *thread)
357{ 358{
358 if (thread->dabr) { 359 if (thread->dabr) {
@@ -360,6 +361,7 @@ static void set_debug_reg_defaults(struct thread_struct *thread)
360 set_dabr(0); 361 set_dabr(0);
361 } 362 }
362} 363}
364#endif /* !CONFIG_HAVE_HW_BREAKPOINT */
363#endif /* CONFIG_PPC_ADV_DEBUG_REGS */ 365#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
364 366
365int set_dabr(unsigned long dabr) 367int set_dabr(unsigned long dabr)
@@ -393,6 +395,9 @@ struct task_struct *__switch_to(struct task_struct *prev,
393 struct thread_struct *new_thread, *old_thread; 395 struct thread_struct *new_thread, *old_thread;
394 unsigned long flags; 396 unsigned long flags;
395 struct task_struct *last; 397 struct task_struct *last;
398#ifdef CONFIG_PPC_BOOK3S_64
399 struct ppc64_tlb_batch *batch;
400#endif
396 401
397#ifdef CONFIG_SMP 402#ifdef CONFIG_SMP
398 /* avoid complexity of lazy save/restore of fpu 403 /* avoid complexity of lazy save/restore of fpu
@@ -511,13 +516,22 @@ struct task_struct *__switch_to(struct task_struct *prev,
511 old_thread->accum_tb += (current_tb - start_tb); 516 old_thread->accum_tb += (current_tb - start_tb);
512 new_thread->start_tb = current_tb; 517 new_thread->start_tb = current_tb;
513 } 518 }
514#endif 519#endif /* CONFIG_PPC64 */
520
521#ifdef CONFIG_PPC_BOOK3S_64
522 batch = &__get_cpu_var(ppc64_tlb_batch);
523 if (batch->active) {
524 current_thread_info()->local_flags |= _TLF_LAZY_MMU;
525 if (batch->index)
526 __flush_tlb_pending(batch);
527 batch->active = 0;
528 }
529#endif /* CONFIG_PPC_BOOK3S_64 */
515 530
516 local_irq_save(flags); 531 local_irq_save(flags);
517 532
518 account_system_vtime(current); 533 account_system_vtime(current);
519 account_process_vtime(current); 534 account_process_vtime(current);
520 calculate_steal_time();
521 535
522 /* 536 /*
523 * We can't take a PMU exception inside _switch() since there is a 537 * We can't take a PMU exception inside _switch() since there is a
@@ -527,6 +541,14 @@ struct task_struct *__switch_to(struct task_struct *prev,
527 hard_irq_disable(); 541 hard_irq_disable();
528 last = _switch(old_thread, new_thread); 542 last = _switch(old_thread, new_thread);
529 543
544#ifdef CONFIG_PPC_BOOK3S_64
545 if (current_thread_info()->local_flags & _TLF_LAZY_MMU) {
546 current_thread_info()->local_flags &= ~_TLF_LAZY_MMU;
547 batch = &__get_cpu_var(ppc64_tlb_batch);
548 batch->active = 1;
549 }
550#endif /* CONFIG_PPC_BOOK3S_64 */
551
530 local_irq_restore(flags); 552 local_irq_restore(flags);
531 553
532 return last; 554 return last;
@@ -632,7 +654,7 @@ void show_regs(struct pt_regs * regs)
632#ifdef CONFIG_PPC_ADV_DEBUG_REGS 654#ifdef CONFIG_PPC_ADV_DEBUG_REGS
633 printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr); 655 printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr);
634#else 656#else
635 printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr); 657 printk("DAR: "REG", DSISR: %08lx\n", regs->dar, regs->dsisr);
636#endif 658#endif
637 printk("TASK = %p[%d] '%s' THREAD: %p", 659 printk("TASK = %p[%d] '%s' THREAD: %p",
638 current, task_pid_nr(current), current->comm, task_thread_info(current)); 660 current, task_pid_nr(current), current->comm, task_thread_info(current));
@@ -671,11 +693,11 @@ void flush_thread(void)
671{ 693{
672 discard_lazy_cpu_state(); 694 discard_lazy_cpu_state();
673 695
674#ifdef CONFIG_HAVE_HW_BREAKPOINTS 696#ifdef CONFIG_HAVE_HW_BREAKPOINT
675 flush_ptrace_hw_breakpoint(current); 697 flush_ptrace_hw_breakpoint(current);
676#else /* CONFIG_HAVE_HW_BREAKPOINTS */ 698#else /* CONFIG_HAVE_HW_BREAKPOINT */
677 set_debug_reg_defaults(&current->thread); 699 set_debug_reg_defaults(&current->thread);
678#endif /* CONFIG_HAVE_HW_BREAKPOINTS */ 700#endif /* CONFIG_HAVE_HW_BREAKPOINT */
679} 701}
680 702
681void 703void
@@ -701,6 +723,8 @@ void prepare_to_copy(struct task_struct *tsk)
701/* 723/*
702 * Copy a thread.. 724 * Copy a thread..
703 */ 725 */
726extern unsigned long dscr_default; /* defined in arch/powerpc/kernel/sysfs.c */
727
704int copy_thread(unsigned long clone_flags, unsigned long usp, 728int copy_thread(unsigned long clone_flags, unsigned long usp,
705 unsigned long unused, struct task_struct *p, 729 unsigned long unused, struct task_struct *p,
706 struct pt_regs *regs) 730 struct pt_regs *regs)
@@ -754,11 +778,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
754 _ALIGN_UP(sizeof(struct thread_info), 16); 778 _ALIGN_UP(sizeof(struct thread_info), 16);
755 779
756#ifdef CONFIG_PPC_STD_MMU_64 780#ifdef CONFIG_PPC_STD_MMU_64
757 if (cpu_has_feature(CPU_FTR_SLB)) { 781 if (mmu_has_feature(MMU_FTR_SLB)) {
758 unsigned long sp_vsid; 782 unsigned long sp_vsid;
759 unsigned long llp = mmu_psize_defs[mmu_linear_psize].sllp; 783 unsigned long llp = mmu_psize_defs[mmu_linear_psize].sllp;
760 784
761 if (cpu_has_feature(CPU_FTR_1T_SEGMENT)) 785 if (mmu_has_feature(MMU_FTR_1T_SEGMENT))
762 sp_vsid = get_kernel_vsid(sp, MMU_SEGSIZE_1T) 786 sp_vsid = get_kernel_vsid(sp, MMU_SEGSIZE_1T)
763 << SLB_VSID_SHIFT_1T; 787 << SLB_VSID_SHIFT_1T;
764 else 788 else
@@ -768,6 +792,20 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
768 p->thread.ksp_vsid = sp_vsid; 792 p->thread.ksp_vsid = sp_vsid;
769 } 793 }
770#endif /* CONFIG_PPC_STD_MMU_64 */ 794#endif /* CONFIG_PPC_STD_MMU_64 */
795#ifdef CONFIG_PPC64
796 if (cpu_has_feature(CPU_FTR_DSCR)) {
797 if (current->thread.dscr_inherit) {
798 p->thread.dscr_inherit = 1;
799 p->thread.dscr = current->thread.dscr;
800 } else if (0 != dscr_default) {
801 p->thread.dscr_inherit = 1;
802 p->thread.dscr = dscr_default;
803 } else {
804 p->thread.dscr_inherit = 0;
805 p->thread.dscr = 0;
806 }
807 }
808#endif
771 809
772 /* 810 /*
773 * The PPC64 ABI makes use of a TOC to contain function 811 * The PPC64 ABI makes use of a TOC to contain function
@@ -1217,11 +1255,11 @@ void __ppc64_runlatch_off(void)
1217 1255
1218static struct kmem_cache *thread_info_cache; 1256static struct kmem_cache *thread_info_cache;
1219 1257
1220struct thread_info *alloc_thread_info(struct task_struct *tsk) 1258struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node)
1221{ 1259{
1222 struct thread_info *ti; 1260 struct thread_info *ti;
1223 1261
1224 ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL); 1262 ti = kmem_cache_alloc_node(thread_info_cache, GFP_KERNEL, node);
1225 if (unlikely(ti == NULL)) 1263 if (unlikely(ti == NULL))
1226 return NULL; 1264 return NULL;
1227#ifdef CONFIG_DEBUG_STACK_USAGE 1265#ifdef CONFIG_DEBUG_STACK_USAGE
@@ -1298,14 +1336,3 @@ unsigned long randomize_et_dyn(unsigned long base)
1298 1336
1299 return ret; 1337 return ret;
1300} 1338}
1301
1302#ifdef CONFIG_SMP
1303int arch_sd_sibling_asym_packing(void)
1304{
1305 if (cpu_has_feature(CPU_FTR_ASYM_SMT)) {
1306 printk_once(KERN_INFO "Enabling Asymmetric SMT scheduling\n");
1307 return SD_ASYM_PACKING;
1308 }
1309 return 0;
1310}
1311#endif