|
@@ -857,7 +857,7 @@ void hw_breakpoint_thread_switch(struct task_struct *next)
|
|
/*
|
|
/*
|
|
* CPU initialisation.
|
|
* CPU initialisation.
|
|
*/
|
|
*/
|
|
-static void hw_breakpoint_reset(void *unused)
|
|
|
|
|
|
+static int hw_breakpoint_reset(unsigned int cpu)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|
|
struct perf_event **slots;
|
|
struct perf_event **slots;
|
|
@@ -888,28 +888,14 @@ static void hw_breakpoint_reset(void *unused)
|
|
write_wb_reg(AARCH64_DBG_REG_WVR, i, 0UL);
|
|
write_wb_reg(AARCH64_DBG_REG_WVR, i, 0UL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
|
|
-static int hw_breakpoint_reset_notify(struct notifier_block *self,
|
|
|
|
- unsigned long action,
|
|
|
|
- void *hcpu)
|
|
|
|
-{
|
|
|
|
- if ((action & ~CPU_TASKS_FROZEN) == CPU_ONLINE) {
|
|
|
|
- local_irq_disable();
|
|
|
|
- hw_breakpoint_reset(NULL);
|
|
|
|
- local_irq_enable();
|
|
|
|
- }
|
|
|
|
- return NOTIFY_OK;
|
|
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static struct notifier_block hw_breakpoint_reset_nb = {
|
|
|
|
- .notifier_call = hw_breakpoint_reset_notify,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
#ifdef CONFIG_CPU_PM
|
|
#ifdef CONFIG_CPU_PM
|
|
-extern void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *));
|
|
|
|
|
|
+extern void cpu_suspend_set_dbg_restorer(int (*hw_bp_restore)(unsigned int));
|
|
#else
|
|
#else
|
|
-static inline void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
|
|
|
|
|
|
+static inline void cpu_suspend_set_dbg_restorer(int (*hw_bp_restore)(unsigned int))
|
|
{
|
|
{
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
@@ -919,36 +905,34 @@ static inline void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
|
|
*/
|
|
*/
|
|
static int __init arch_hw_breakpoint_init(void)
|
|
static int __init arch_hw_breakpoint_init(void)
|
|
{
|
|
{
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
core_num_brps = get_num_brps();
|
|
core_num_brps = get_num_brps();
|
|
core_num_wrps = get_num_wrps();
|
|
core_num_wrps = get_num_wrps();
|
|
|
|
|
|
pr_info("found %d breakpoint and %d watchpoint registers.\n",
|
|
pr_info("found %d breakpoint and %d watchpoint registers.\n",
|
|
core_num_brps, core_num_wrps);
|
|
core_num_brps, core_num_wrps);
|
|
|
|
|
|
- cpu_notifier_register_begin();
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Reset the breakpoint resources. We assume that a halting
|
|
|
|
- * debugger will leave the world in a nice state for us.
|
|
|
|
- */
|
|
|
|
- smp_call_function(hw_breakpoint_reset, NULL, 1);
|
|
|
|
- hw_breakpoint_reset(NULL);
|
|
|
|
-
|
|
|
|
/* Register debug fault handlers. */
|
|
/* Register debug fault handlers. */
|
|
hook_debug_fault_code(DBG_ESR_EVT_HWBP, breakpoint_handler, SIGTRAP,
|
|
hook_debug_fault_code(DBG_ESR_EVT_HWBP, breakpoint_handler, SIGTRAP,
|
|
TRAP_HWBKPT, "hw-breakpoint handler");
|
|
TRAP_HWBKPT, "hw-breakpoint handler");
|
|
hook_debug_fault_code(DBG_ESR_EVT_HWWP, watchpoint_handler, SIGTRAP,
|
|
hook_debug_fault_code(DBG_ESR_EVT_HWWP, watchpoint_handler, SIGTRAP,
|
|
TRAP_HWBKPT, "hw-watchpoint handler");
|
|
TRAP_HWBKPT, "hw-watchpoint handler");
|
|
|
|
|
|
- /* Register hotplug notifier. */
|
|
|
|
- __register_cpu_notifier(&hw_breakpoint_reset_nb);
|
|
|
|
-
|
|
|
|
- cpu_notifier_register_done();
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Reset the breakpoint resources. We assume that a halting
|
|
|
|
+ * debugger will leave the world in a nice state for us.
|
|
|
|
+ */
|
|
|
|
+ ret = cpuhp_setup_state(CPUHP_AP_PERF_ARM_HW_BREAKPOINT_STARTING,
|
|
|
|
+ "CPUHP_AP_PERF_ARM_HW_BREAKPOINT_STARTING",
|
|
|
|
+ hw_breakpoint_reset, NULL);
|
|
|
|
+ if (ret)
|
|
|
|
+ pr_err("failed to register CPU hotplug notifier: %d\n", ret);
|
|
|
|
|
|
/* Register cpu_suspend hw breakpoint restore hook */
|
|
/* Register cpu_suspend hw breakpoint restore hook */
|
|
cpu_suspend_set_dbg_restorer(hw_breakpoint_reset);
|
|
cpu_suspend_set_dbg_restorer(hw_breakpoint_reset);
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
arch_initcall(arch_hw_breakpoint_init);
|
|
arch_initcall(arch_hw_breakpoint_init);
|
|
|
|
|