diff options
-rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 983558eb9023..8e9532152bd9 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -228,6 +228,13 @@ static int get_num_brps(void) | |||
228 | * be put into halting debug mode at any time by an external debugger | 228 | * be put into halting debug mode at any time by an external debugger |
229 | * but there is nothing we can do to prevent that. | 229 | * but there is nothing we can do to prevent that. |
230 | */ | 230 | */ |
231 | static int monitor_mode_enabled(void) | ||
232 | { | ||
233 | u32 dscr; | ||
234 | ARM_DBG_READ(c1, 0, dscr); | ||
235 | return !!(dscr & ARM_DSCR_MDBGEN); | ||
236 | } | ||
237 | |||
231 | static int enable_monitor_mode(void) | 238 | static int enable_monitor_mode(void) |
232 | { | 239 | { |
233 | u32 dscr; | 240 | u32 dscr; |
@@ -321,14 +328,9 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
321 | { | 328 | { |
322 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | 329 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); |
323 | struct perf_event **slot, **slots; | 330 | struct perf_event **slot, **slots; |
324 | int i, max_slots, ctrl_base, val_base, ret = 0; | 331 | int i, max_slots, ctrl_base, val_base; |
325 | u32 addr, ctrl; | 332 | u32 addr, ctrl; |
326 | 333 | ||
327 | /* Ensure that we are in monitor mode and halting mode is disabled. */ | ||
328 | ret = enable_monitor_mode(); | ||
329 | if (ret) | ||
330 | goto out; | ||
331 | |||
332 | addr = info->address; | 334 | addr = info->address; |
333 | ctrl = encode_ctrl_reg(info->ctrl) | 0x1; | 335 | ctrl = encode_ctrl_reg(info->ctrl) | 0x1; |
334 | 336 | ||
@@ -355,10 +357,8 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
355 | } | 357 | } |
356 | } | 358 | } |
357 | 359 | ||
358 | if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) { | 360 | if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) |
359 | ret = -EBUSY; | 361 | return -EBUSY; |
360 | goto out; | ||
361 | } | ||
362 | 362 | ||
363 | /* Override the breakpoint data with the step data. */ | 363 | /* Override the breakpoint data with the step data. */ |
364 | if (info->step_ctrl.enabled) { | 364 | if (info->step_ctrl.enabled) { |
@@ -376,9 +376,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
376 | 376 | ||
377 | /* Setup the control register. */ | 377 | /* Setup the control register. */ |
378 | write_wb_reg(ctrl_base + i, ctrl); | 378 | write_wb_reg(ctrl_base + i, ctrl); |
379 | 379 | return 0; | |
380 | out: | ||
381 | return ret; | ||
382 | } | 380 | } |
383 | 381 | ||
384 | void arch_uninstall_hw_breakpoint(struct perf_event *bp) | 382 | void arch_uninstall_hw_breakpoint(struct perf_event *bp) |
@@ -589,6 +587,10 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
589 | int ret = 0; | 587 | int ret = 0; |
590 | u32 offset, alignment_mask = 0x3; | 588 | u32 offset, alignment_mask = 0x3; |
591 | 589 | ||
590 | /* Ensure that we are in monitor debug mode. */ | ||
591 | if (!monitor_mode_enabled()) | ||
592 | return -ENODEV; | ||
593 | |||
592 | /* Build the arch_hw_breakpoint. */ | 594 | /* Build the arch_hw_breakpoint. */ |
593 | ret = arch_build_bp_info(bp); | 595 | ret = arch_build_bp_info(bp); |
594 | if (ret) | 596 | if (ret) |