linux/arch/arm64/kernel/debug-monitors.c
<<
>>
Prefs
   1/*
   2 * ARMv8 single-step debug support and mdscr context switching.
   3 *
   4 * Copyright (C) 2012 ARM Limited
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17 *
  18 * Author: Will Deacon <will.deacon@arm.com>
  19 */
  20
  21#include <linux/cpu.h>
  22#include <linux/debugfs.h>
  23#include <linux/hardirq.h>
  24#include <linux/init.h>
  25#include <linux/ptrace.h>
  26#include <linux/stat.h>
  27
  28#include <asm/debug-monitors.h>
  29#include <asm/local.h>
  30#include <asm/cputype.h>
  31#include <asm/system_misc.h>
  32
  33/* Low-level stepping controls. */
  34#define DBG_MDSCR_SS            (1 << 0)
  35#define DBG_SPSR_SS             (1 << 21)
  36
  37/* MDSCR_EL1 enabling bits */
  38#define DBG_MDSCR_KDE           (1 << 13)
  39#define DBG_MDSCR_MDE           (1 << 15)
  40#define DBG_MDSCR_MASK          ~(DBG_MDSCR_KDE | DBG_MDSCR_MDE)
  41
  42/* Determine debug architecture. */
  43u8 debug_monitors_arch(void)
  44{
  45        return read_cpuid(ID_AA64DFR0_EL1) & 0xf;
  46}
  47
  48/*
  49 * MDSCR access routines.
  50 */
  51static void mdscr_write(u32 mdscr)
  52{
  53        unsigned long flags;
  54        local_dbg_save(flags);
  55        asm volatile("msr mdscr_el1, %0" :: "r" (mdscr));
  56        local_dbg_restore(flags);
  57}
  58
  59static u32 mdscr_read(void)
  60{
  61        u32 mdscr;
  62        asm volatile("mrs %0, mdscr_el1" : "=r" (mdscr));
  63        return mdscr;
  64}
  65
  66/*
  67 * Allow root to disable self-hosted debug from userspace.
  68 * This is useful if you want to connect an external JTAG debugger.
  69 */
  70static u32 debug_enabled = 1;
  71
  72static int create_debug_debugfs_entry(void)
  73{
  74        debugfs_create_bool("debug_enabled", 0644, NULL, &debug_enabled);
  75        return 0;
  76}
  77fs_initcall(create_debug_debugfs_entry);
  78
  79static int __init early_debug_disable(char *buf)
  80{
  81        debug_enabled = 0;
  82        return 0;
  83}
  84
  85early_param("nodebugmon", early_debug_disable);
  86
  87/*
  88 * Keep track of debug users on each core.
  89 * The ref counts are per-cpu so we use a local_t type.
  90 */
  91static DEFINE_PER_CPU(local_t, mde_ref_count);
  92static DEFINE_PER_CPU(local_t, kde_ref_count);
  93
  94void enable_debug_monitors(enum debug_el el)
  95{
  96        u32 mdscr, enable = 0;
  97
  98        WARN_ON(preemptible());
  99
 100        if (local_inc_return(&__get_cpu_var(mde_ref_count)) == 1)
 101                enable = DBG_MDSCR_MDE;
 102
 103        if (el == DBG_ACTIVE_EL1 &&
 104            local_inc_return(&__get_cpu_var(kde_ref_count)) == 1)
 105                enable |= DBG_MDSCR_KDE;
 106
 107        if (enable && debug_enabled) {
 108                mdscr = mdscr_read();
 109                mdscr |= enable;
 110                mdscr_write(mdscr);
 111        }
 112}
 113
 114void disable_debug_monitors(enum debug_el el)
 115{
 116        u32 mdscr, disable = 0;
 117
 118        WARN_ON(preemptible());
 119
 120        if (local_dec_and_test(&__get_cpu_var(mde_ref_count)))
 121                disable = ~DBG_MDSCR_MDE;
 122
 123        if (el == DBG_ACTIVE_EL1 &&
 124            local_dec_and_test(&__get_cpu_var(kde_ref_count)))
 125                disable &= ~DBG_MDSCR_KDE;
 126
 127        if (disable) {
 128                mdscr = mdscr_read();
 129                mdscr &= disable;
 130                mdscr_write(mdscr);
 131        }
 132}
 133
 134/*
 135 * OS lock clearing.
 136 */
 137static void clear_os_lock(void *unused)
 138{
 139        asm volatile("msr oslar_el1, %0" : : "r" (0));
 140        isb();
 141}
 142
 143static int __cpuinit os_lock_notify(struct notifier_block *self,
 144                                    unsigned long action, void *data)
 145{
 146        int cpu = (unsigned long)data;
 147        if (action == CPU_ONLINE)
 148                smp_call_function_single(cpu, clear_os_lock, NULL, 1);
 149        return NOTIFY_OK;
 150}
 151
 152static struct notifier_block __cpuinitdata os_lock_nb = {
 153        .notifier_call = os_lock_notify,
 154};
 155
 156static int __cpuinit debug_monitors_init(void)
 157{
 158        /* Clear the OS lock. */
 159        smp_call_function(clear_os_lock, NULL, 1);
 160        clear_os_lock(NULL);
 161
 162        /* Register hotplug handler. */
 163        register_cpu_notifier(&os_lock_nb);
 164        return 0;
 165}
 166postcore_initcall(debug_monitors_init);
 167
 168/*
 169 * Single step API and exception handling.
 170 */
 171static void set_regs_spsr_ss(struct pt_regs *regs)
 172{
 173        unsigned long spsr;
 174
 175        spsr = regs->pstate;
 176        spsr &= ~DBG_SPSR_SS;
 177        spsr |= DBG_SPSR_SS;
 178        regs->pstate = spsr;
 179}
 180
 181static void clear_regs_spsr_ss(struct pt_regs *regs)
 182{
 183        unsigned long spsr;
 184
 185        spsr = regs->pstate;
 186        spsr &= ~DBG_SPSR_SS;
 187        regs->pstate = spsr;
 188}
 189
 190static int single_step_handler(unsigned long addr, unsigned int esr,
 191                               struct pt_regs *regs)
 192{
 193        siginfo_t info;
 194
 195        /*
 196         * If we are stepping a pending breakpoint, call the hw_breakpoint
 197         * handler first.
 198         */
 199        if (!reinstall_suspended_bps(regs))
 200                return 0;
 201
 202        if (user_mode(regs)) {
 203                info.si_signo = SIGTRAP;
 204                info.si_errno = 0;
 205                info.si_code  = TRAP_HWBKPT;
 206                info.si_addr  = (void __user *)instruction_pointer(regs);
 207                force_sig_info(SIGTRAP, &info, current);
 208
 209                /*
 210                 * ptrace will disable single step unless explicitly
 211                 * asked to re-enable it. For other clients, it makes
 212                 * sense to leave it enabled (i.e. rewind the controls
 213                 * to the active-not-pending state).
 214                 */
 215                user_rewind_single_step(current);
 216        } else {
 217                /* TODO: route to KGDB */
 218                pr_warning("Unexpected kernel single-step exception at EL1\n");
 219                /*
 220                 * Re-enable stepping since we know that we will be
 221                 * returning to regs.
 222                 */
 223                set_regs_spsr_ss(regs);
 224        }
 225
 226        return 0;
 227}
 228
 229static int __init single_step_init(void)
 230{
 231        hook_debug_fault_code(DBG_ESR_EVT_HWSS, single_step_handler, SIGTRAP,
 232                              TRAP_HWBKPT, "single-step handler");
 233        return 0;
 234}
 235arch_initcall(single_step_init);
 236
 237/* Re-enable single step for syscall restarting. */
 238void user_rewind_single_step(struct task_struct *task)
 239{
 240        /*
 241         * If single step is active for this thread, then set SPSR.SS
 242         * to 1 to avoid returning to the active-pending state.
 243         */
 244        if (test_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP))
 245                set_regs_spsr_ss(task_pt_regs(task));
 246}
 247
 248void user_fastforward_single_step(struct task_struct *task)
 249{
 250        if (test_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP))
 251                clear_regs_spsr_ss(task_pt_regs(task));
 252}
 253
 254/* Kernel API */
 255void kernel_enable_single_step(struct pt_regs *regs)
 256{
 257        WARN_ON(!irqs_disabled());
 258        set_regs_spsr_ss(regs);
 259        mdscr_write(mdscr_read() | DBG_MDSCR_SS);
 260        enable_debug_monitors(DBG_ACTIVE_EL1);
 261}
 262
 263void kernel_disable_single_step(void)
 264{
 265        WARN_ON(!irqs_disabled());
 266        mdscr_write(mdscr_read() & ~DBG_MDSCR_SS);
 267        disable_debug_monitors(DBG_ACTIVE_EL1);
 268}
 269
 270int kernel_active_single_step(void)
 271{
 272        WARN_ON(!irqs_disabled());
 273        return mdscr_read() & DBG_MDSCR_SS;
 274}
 275
 276/* ptrace API */
 277void user_enable_single_step(struct task_struct *task)
 278{
 279        set_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP);
 280        set_regs_spsr_ss(task_pt_regs(task));
 281}
 282
 283void user_disable_single_step(struct task_struct *task)
 284{
 285        clear_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP);
 286}
 287