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.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 773424df828..551f6713ff4 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -37,6 +37,7 @@
37#include <linux/kernel_stat.h> 37#include <linux/kernel_stat.h>
38#include <linux/personality.h> 38#include <linux/personality.h>
39#include <linux/random.h> 39#include <linux/random.h>
40#include <linux/hw_breakpoint.h>
40 41
41#include <asm/pgtable.h> 42#include <asm/pgtable.h>
42#include <asm/uaccess.h> 43#include <asm/uaccess.h>
@@ -462,14 +463,42 @@ struct task_struct *__switch_to(struct task_struct *prev,
462#ifdef CONFIG_PPC_ADV_DEBUG_REGS 463#ifdef CONFIG_PPC_ADV_DEBUG_REGS
463 switch_booke_debug_regs(&new->thread); 464 switch_booke_debug_regs(&new->thread);
464#else 465#else
466/*
467 * For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would
468 * schedule DABR
469 */
470#ifndef CONFIG_HAVE_HW_BREAKPOINT
465 if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) 471 if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
466 set_dabr(new->thread.dabr); 472 set_dabr(new->thread.dabr);
473#endif /* CONFIG_HAVE_HW_BREAKPOINT */
467#endif 474#endif
468 475
469 476
470 new_thread = &new->thread; 477 new_thread = &new->thread;
471 old_thread = &current->thread; 478 old_thread = &current->thread;
472 479
480#if defined(CONFIG_PPC_BOOK3E_64)
481 /* XXX Current Book3E code doesn't deal with kernel side DBCR0,
482 * we always hold the user values, so we set it now.
483 *
484 * However, we ensure the kernel MSR:DE is appropriately cleared too
485 * to avoid spurrious single step exceptions in the kernel.
486 *
487 * This will have to change to merge with the ppc32 code at some point,
488 * but I don't like much what ppc32 is doing today so there's some
489 * thinking needed there
490 */
491 if ((new_thread->dbcr0 | old_thread->dbcr0) & DBCR0_IDM) {
492 u32 dbcr0;
493
494 mtmsr(mfmsr() & ~MSR_DE);
495 isync();
496 dbcr0 = mfspr(SPRN_DBCR0);
497 dbcr0 = (dbcr0 & DBCR0_EDM) | new_thread->dbcr0;
498 mtspr(SPRN_DBCR0, dbcr0);
499 }
500#endif /* CONFIG_PPC64_BOOK3E */
501
473#ifdef CONFIG_PPC64 502#ifdef CONFIG_PPC64
474 /* 503 /*
475 * Collect processor utilization data per process 504 * Collect processor utilization data per process
@@ -642,7 +671,11 @@ void flush_thread(void)
642{ 671{
643 discard_lazy_cpu_state(); 672 discard_lazy_cpu_state();
644 673
674#ifdef CONFIG_HAVE_HW_BREAKPOINTS
675 flush_ptrace_hw_breakpoint(current);
676#else /* CONFIG_HAVE_HW_BREAKPOINTS */
645 set_debug_reg_defaults(&current->thread); 677 set_debug_reg_defaults(&current->thread);
678#endif /* CONFIG_HAVE_HW_BREAKPOINTS */
646} 679}
647 680
648void 681void
@@ -660,6 +693,9 @@ void prepare_to_copy(struct task_struct *tsk)
660 flush_altivec_to_thread(current); 693 flush_altivec_to_thread(current);
661 flush_vsx_to_thread(current); 694 flush_vsx_to_thread(current);
662 flush_spe_to_thread(current); 695 flush_spe_to_thread(current);
696#ifdef CONFIG_HAVE_HW_BREAKPOINT
697 flush_ptrace_hw_breakpoint(tsk);
698#endif /* CONFIG_HAVE_HW_BREAKPOINT */
663} 699}
664 700
665/* 701/*