diff options
author | K.Prasad <prasad@linux.vnet.ibm.com> | 2010-06-15 02:05:19 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2010-06-22 05:40:50 -0400 |
commit | 5aae8a53708025d4e718f0d2e7c2f766779ddc71 (patch) | |
tree | d151e2c29e78248cee620cf5094a15316abd17d2 /arch/powerpc/kernel/process.c | |
parent | f7136c5150c29846d7a1d09109449d96b2f63445 (diff) |
powerpc, hw_breakpoints: Implement hw_breakpoints for 64-bit server processors
Implement perf-events based hw-breakpoint interfaces for PowerPC
64-bit server (Book III S) processors. This allows access to a
given location to be used as an event that can be counted or
profiled by the perf_events subsystem.
This is done using the DABR (data breakpoint register), which can
also be used for process debugging via ptrace. When perf_event
hw_breakpoint support is configured in, the perf_event subsystem
manages the DABR and arbitrates access to it, and ptrace then
creates a perf_event when it is requested to set a data breakpoint.
[Adopted suggestions from Paul Mackerras <paulus@samba.org> to
- emulate_step() all system-wide breakpoints and single-step only the
per-task breakpoints
- perform arch-specific cleanup before unregistration through
arch_unregister_hw_breakpoint()
]
Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r-- | arch/powerpc/kernel/process.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 9d255b4f0a0e..cbf3521d50b6 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,8 +463,14 @@ 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 | ||
@@ -642,7 +649,11 @@ void flush_thread(void) | |||
642 | { | 649 | { |
643 | discard_lazy_cpu_state(); | 650 | discard_lazy_cpu_state(); |
644 | 651 | ||
652 | #ifdef CONFIG_HAVE_HW_BREAKPOINTS | ||
653 | flush_ptrace_hw_breakpoint(current); | ||
654 | #else /* CONFIG_HAVE_HW_BREAKPOINTS */ | ||
645 | set_debug_reg_defaults(¤t->thread); | 655 | set_debug_reg_defaults(¤t->thread); |
656 | #endif /* CONFIG_HAVE_HW_BREAKPOINTS */ | ||
646 | } | 657 | } |
647 | 658 | ||
648 | void | 659 | void |
@@ -660,6 +671,9 @@ void prepare_to_copy(struct task_struct *tsk) | |||
660 | flush_altivec_to_thread(current); | 671 | flush_altivec_to_thread(current); |
661 | flush_vsx_to_thread(current); | 672 | flush_vsx_to_thread(current); |
662 | flush_spe_to_thread(current); | 673 | flush_spe_to_thread(current); |
674 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
675 | flush_ptrace_hw_breakpoint(tsk); | ||
676 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
663 | } | 677 | } |
664 | 678 | ||
665 | /* | 679 | /* |