Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 322625
b: refs/heads/master
c: bf88011
h: refs/heads/master
i:
  322623: 8b6359d
v: v3
  • Loading branch information
Will Deacon authored and Russell King committed Aug 25, 2012
1 parent 85f6928 commit 4b3c5b2
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a849088aa1552b1a28eea3daff599ee22a734ae3
refs/heads/master: bf8801145c01ab600f8df66e8c879ac642fa5846
55 changes: 40 additions & 15 deletions trunk/arch/arm/kernel/hw_breakpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ static int debug_arch_supported(void)
arch >= ARM_DEBUG_ARCH_V7_1;
}

/* Can we determine the watchpoint access type from the fsr? */
static int debug_exception_updates_fsr(void)
{
return 0;
}

/* Determine number of WRP registers available. */
static int get_num_wrp_resources(void)
{
Expand Down Expand Up @@ -619,18 +625,35 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
info->address &= ~alignment_mask;
info->ctrl.len <<= offset;

/*
* Currently we rely on an overflow handler to take
* care of single-stepping the breakpoint when it fires.
* In the case of userspace breakpoints on a core with V7 debug,
* we can use the mismatch feature as a poor-man's hardware
* single-step, but this only works for per-task breakpoints.
*/
if (!bp->overflow_handler && (arch_check_bp_in_kernelspace(bp) ||
!core_has_mismatch_brps() || !bp->hw.bp_target)) {
pr_warning("overflow handler required but none found\n");
ret = -EINVAL;
if (!bp->overflow_handler) {
/*
* Mismatch breakpoints are required for single-stepping
* breakpoints.
*/
if (!core_has_mismatch_brps())
return -EINVAL;

/* We don't allow mismatch breakpoints in kernel space. */
if (arch_check_bp_in_kernelspace(bp))
return -EPERM;

/*
* Per-cpu breakpoints are not supported by our stepping
* mechanism.
*/
if (!bp->hw.bp_target)
return -EINVAL;

/*
* We only support specific access types if the fsr
* reports them.
*/
if (!debug_exception_updates_fsr() &&
(info->ctrl.type == ARM_BREAKPOINT_LOAD ||
info->ctrl.type == ARM_BREAKPOINT_STORE))
return -EINVAL;
}

out:
return ret;
}
Expand Down Expand Up @@ -706,10 +729,12 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
goto unlock;

/* Check that the access type matches. */
access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W :
HW_BREAKPOINT_R;
if (!(access & hw_breakpoint_type(wp)))
goto unlock;
if (debug_exception_updates_fsr()) {
access = (fsr & ARM_FSR_ACCESS_MASK) ?
HW_BREAKPOINT_W : HW_BREAKPOINT_R;
if (!(access & hw_breakpoint_type(wp)))
goto unlock;
}

/* We have a winner. */
info->trigger = addr;
Expand Down

0 comments on commit 4b3c5b2

Please sign in to comment.