summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/hw_breakpoint.c
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2013-01-24 16:02:59 +0100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-01-29 01:35:08 +0100
commit4ae7ebe9522a9e3626e28b4d268dae712738573d (patch)
treee71928a561fc2db543e88211b6b0747c10abb9cd /arch/powerpc/kernel/hw_breakpoint.c
parentpowerpc: Add length setting to set_dawr (diff)
downloadlinux-4ae7ebe9522a9e3626e28b4d268dae712738573d.tar.xz
linux-4ae7ebe9522a9e3626e28b4d268dae712738573d.zip
powerpc: Change hardware breakpoint to allow longer ranges
Change the hardware breakpoint code so that we can support wider ranged breakpoints. This means both ptrace and perf hardware breakpoints can use upto 512 byte long breakpoints when using the DAWR and only 8 byte when using the DABR. Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/hw_breakpoint.c')
-rw-r--r--arch/powerpc/kernel/hw_breakpoint.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 2a3e8dd547ec..a949bdfc9623 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -142,7 +142,7 @@ int arch_bp_generic_fields(int type, int *gen_bp_type)
*/
int arch_validate_hwbkpt_settings(struct perf_event *bp)
{
- int ret = -EINVAL;
+ int ret = -EINVAL, length_max;
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
if (!bp)
@@ -171,8 +171,16 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
* HW_BREAKPOINT_ALIGN by rounding off to the lower address, the
* 'symbolsize' should satisfy the check below.
*/
+ length_max = 8; /* DABR */
+ if (cpu_has_feature(CPU_FTR_DAWR)) {
+ length_max = 512 ; /* 64 doublewords */
+ /* DAWR region can't cross 512 boundary */
+ if ((bp->attr.bp_addr >> 10) !=
+ ((bp->attr.bp_addr + bp->attr.bp_len) >> 10))
+ return -EINVAL;
+ }
if (info->len >
- (HW_BREAKPOINT_LEN - (info->address & HW_BREAKPOINT_ALIGN)))
+ (length_max - (info->address & HW_BREAKPOINT_ALIGN)))
return -EINVAL;
return 0;
}