Merge branch 'work.splice_read' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / arch / arm64 / kernel / debug-monitors.c
index 91fff48..73ae90e 100644 (file)
@@ -46,16 +46,14 @@ static void mdscr_write(u32 mdscr)
 {
        unsigned long flags;
        local_dbg_save(flags);
-       asm volatile("msr mdscr_el1, %0" :: "r" (mdscr));
+       write_sysreg(mdscr, mdscr_el1);
        local_dbg_restore(flags);
 }
 NOKPROBE_SYMBOL(mdscr_write);
 
 static u32 mdscr_read(void)
 {
-       u32 mdscr;
-       asm volatile("mrs %0, mdscr_el1" : "=r" (mdscr));
-       return mdscr;
+       return read_sysreg(mdscr_el1);
 }
 NOKPROBE_SYMBOL(mdscr_read);
 
@@ -132,36 +130,18 @@ NOKPROBE_SYMBOL(disable_debug_monitors);
 /*
  * OS lock clearing.
  */
-static void clear_os_lock(void *unused)
+static int clear_os_lock(unsigned int cpu)
 {
-       asm volatile("msr oslar_el1, %0" : : "r" (0));
-}
-
-static int os_lock_notify(struct notifier_block *self,
-                                   unsigned long action, void *data)
-{
-       if ((action & ~CPU_TASKS_FROZEN) == CPU_ONLINE)
-               clear_os_lock(NULL);
-       return NOTIFY_OK;
+       write_sysreg(0, oslar_el1);
+       isb();
+       return 0;
 }
 
-static struct notifier_block os_lock_nb = {
-       .notifier_call = os_lock_notify,
-};
-
 static int debug_monitors_init(void)
 {
-       cpu_notifier_register_begin();
-
-       /* Clear the OS lock. */
-       on_each_cpu(clear_os_lock, NULL, 1);
-       isb();
-
-       /* Register hotplug handler. */
-       __register_cpu_notifier(&os_lock_nb);
-
-       cpu_notifier_register_done();
-       return 0;
+       return cpuhp_setup_state(CPUHP_AP_ARM64_DEBUG_MONITORS_STARTING,
+                                "CPUHP_AP_ARM64_DEBUG_MONITORS_STARTING",
+                                clear_os_lock, NULL);
 }
 postcore_initcall(debug_monitors_init);
 
@@ -254,7 +234,7 @@ static int single_step_handler(unsigned long addr, unsigned int esr,
                return 0;
 
        if (user_mode(regs)) {
-               send_user_sigtrap(TRAP_HWBKPT);
+               send_user_sigtrap(TRAP_TRACE);
 
                /*
                 * ptrace will disable single step unless explicitly
@@ -382,7 +362,7 @@ NOKPROBE_SYMBOL(aarch32_break_handler);
 static int __init debug_traps_init(void)
 {
        hook_debug_fault_code(DBG_ESR_EVT_HWSS, single_step_handler, SIGTRAP,
-                             TRAP_HWBKPT, "single-step handler");
+                             TRAP_TRACE, "single-step handler");
        hook_debug_fault_code(DBG_ESR_EVT_BRK, brk_handler, SIGTRAP,
                              TRAP_BRKPT, "ptrace BRK handler");
        return 0;
@@ -435,8 +415,10 @@ NOKPROBE_SYMBOL(kernel_active_single_step);
 /* ptrace API */
 void user_enable_single_step(struct task_struct *task)
 {
-       set_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP);
-       set_regs_spsr_ss(task_pt_regs(task));
+       struct thread_info *ti = task_thread_info(task);
+
+       if (!test_and_set_ti_thread_flag(ti, TIF_SINGLESTEP))
+               set_regs_spsr_ss(task_pt_regs(task));
 }
 NOKPROBE_SYMBOL(user_enable_single_step);