|
@@ -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;
|
|
|
}
|