summaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/ptrace.c
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2012-10-18 16:17:00 +0200
committerCatalin Marinas <catalin.marinas@arm.com>2012-10-18 21:15:34 +0200
commit8f34a1da35aed7b438a2de8ac27723a5472e8399 (patch)
tree78bd55aae0bcfba26dbedeb93471e13635f90c67 /arch/arm64/kernel/ptrace.c
parentarm64: ptrace: make structure padding explicit for debug registers (diff)
downloadlinux-8f34a1da35aed7b438a2de8ac27723a5472e8399.tar.xz
linux-8f34a1da35aed7b438a2de8ac27723a5472e8399.zip
arm64: ptrace: use HW_BREAKPOINT_EMPTY type for disabled breakpoints
If a debugger tries to zero a hardware debug control register, the kernel will try to infer both the type and length of the breakpoint in order to sanity-check against the requested regset type. This will fail because the encoding will appear as a zero-length breakpoint. This patch changes the control register setting so that disabled breakpoints are treated as HW_BREAKPOINT_EMPTY and no further sanity-checking is required. Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/ptrace.c')
-rw-r--r--arch/arm64/kernel/ptrace.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index c62d39d5c99f..6e1e77f1831c 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -234,28 +234,33 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type,
struct arch_hw_breakpoint_ctrl ctrl,
struct perf_event_attr *attr)
{
- int err, len, type;
+ int err, len, type, disabled = !ctrl.enabled;
- err = arch_bp_generic_fields(ctrl, &len, &type);
- if (err)
- return err;
-
- switch (note_type) {
- case NT_ARM_HW_BREAK:
- if ((type & HW_BREAKPOINT_X) != type)
- return -EINVAL;
- break;
- case NT_ARM_HW_WATCH:
- if ((type & HW_BREAKPOINT_RW) != type)
+ if (disabled) {
+ len = 0;
+ type = HW_BREAKPOINT_EMPTY;
+ } else {
+ err = arch_bp_generic_fields(ctrl, &len, &type);
+ if (err)
+ return err;
+
+ switch (note_type) {
+ case NT_ARM_HW_BREAK:
+ if ((type & HW_BREAKPOINT_X) != type)
+ return -EINVAL;
+ break;
+ case NT_ARM_HW_WATCH:
+ if ((type & HW_BREAKPOINT_RW) != type)
+ return -EINVAL;
+ break;
+ default:
return -EINVAL;
- break;
- default:
- return -EINVAL;
+ }
}
attr->bp_len = len;
attr->bp_type = type;
- attr->disabled = !ctrl.enabled;
+ attr->disabled = disabled;
return 0;
}