diff options
author | Will Deacon <will.deacon@arm.com> | 2010-12-01 17:05:24 +0000 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2010-12-06 11:55:57 +0000 |
commit | 3ce70b2e24cd35cc9f2df8cf5205b8ab4e6178e1 (patch) | |
tree | 2f0939d5d8f2ac9d97932905f0b147b5a5e1891e /arch/arm/kernel/hw_breakpoint.c | |
parent | 9ebb3cbcc39d4e61ae6751167086acfb5c201e6f (diff) | |
download | op-kernel-dev-3ce70b2e24cd35cc9f2df8cf5205b8ab4e6178e1.zip op-kernel-dev-3ce70b2e24cd35cc9f2df8cf5205b8ab4e6178e1.tar.gz |
ARM: hw_breakpoint: disallow per-cpu breakpoints without overflow handler
Single-stepping a breakpoint requires us to disable it temporarily so that
we don't get stuck in a recursive debug trap. With per-cpu breakpoints this
presents a problem where an interrupt can be taken before the single-step has
completed and a new task is eventually scheduled. This new task will not
hit the breakpoint because it will have been disabled during the previous
handling code.
This patch disallows per-cpu breakpoints on ARM when an overflow handler
is not present. A similar effect can be created by placing breakpoints on
a shell and then running applications there.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm/kernel/hw_breakpoint.c')
-rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 36cd768..eef1b1e 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -622,10 +622,12 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) * 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. + * we can use the mismatch feature as a poor-man's hardware + * single-step, but this only works for per-task breakpoints. */ if (WARN_ONCE(!bp->overflow_handler && - (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps()), + (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps() + || !bp->hw.bp_target), "overflow handler required but none found")) { ret = -EINVAL; } |