1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2012 ARM Ltd. 4*4882a593Smuzhiyun */ 5*4882a593Smuzhiyun #ifndef __ASM_DEBUG_MONITORS_H 6*4882a593Smuzhiyun #define __ASM_DEBUG_MONITORS_H 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #include <linux/errno.h> 9*4882a593Smuzhiyun #include <linux/types.h> 10*4882a593Smuzhiyun #include <asm/brk-imm.h> 11*4882a593Smuzhiyun #include <asm/esr.h> 12*4882a593Smuzhiyun #include <asm/insn.h> 13*4882a593Smuzhiyun #include <asm/ptrace.h> 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun /* Low-level stepping controls. */ 16*4882a593Smuzhiyun #define DBG_MDSCR_SS (1 << 0) 17*4882a593Smuzhiyun #define DBG_SPSR_SS (1 << 21) 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun /* MDSCR_EL1 enabling bits */ 20*4882a593Smuzhiyun #define DBG_MDSCR_KDE (1 << 13) 21*4882a593Smuzhiyun #define DBG_MDSCR_MDE (1 << 15) 22*4882a593Smuzhiyun #define DBG_MDSCR_MASK ~(DBG_MDSCR_KDE | DBG_MDSCR_MDE) 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun #define DBG_ESR_EVT(x) (((x) >> 27) & 0x7) 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun /* AArch64 */ 27*4882a593Smuzhiyun #define DBG_ESR_EVT_HWBP 0x0 28*4882a593Smuzhiyun #define DBG_ESR_EVT_HWSS 0x1 29*4882a593Smuzhiyun #define DBG_ESR_EVT_HWWP 0x2 30*4882a593Smuzhiyun #define DBG_ESR_EVT_BRK 0x6 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun /* 33*4882a593Smuzhiyun * Break point instruction encoding 34*4882a593Smuzhiyun */ 35*4882a593Smuzhiyun #define BREAK_INSTR_SIZE AARCH64_INSN_SIZE 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun /* 38*4882a593Smuzhiyun * BRK instruction encoding 39*4882a593Smuzhiyun * The #imm16 value should be placed at bits[20:5] within BRK ins 40*4882a593Smuzhiyun */ 41*4882a593Smuzhiyun #define AARCH64_BREAK_MON 0xd4200000 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun /* 44*4882a593Smuzhiyun * BRK instruction for provoking a fault on purpose 45*4882a593Smuzhiyun * Unlike kgdb, #imm16 value with unallocated handler is used for faulting. 46*4882a593Smuzhiyun */ 47*4882a593Smuzhiyun #define AARCH64_BREAK_FAULT (AARCH64_BREAK_MON | (FAULT_BRK_IMM << 5)) 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun #define AARCH64_BREAK_KGDB_DYN_DBG \ 50*4882a593Smuzhiyun (AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5)) 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun #define CACHE_FLUSH_IS_SAFE 1 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun /* kprobes BRK opcodes with ESR encoding */ 55*4882a593Smuzhiyun #define BRK64_OPCODE_KPROBES (AARCH64_BREAK_MON | (KPROBES_BRK_IMM << 5)) 56*4882a593Smuzhiyun #define BRK64_OPCODE_KPROBES_SS (AARCH64_BREAK_MON | (KPROBES_BRK_SS_IMM << 5)) 57*4882a593Smuzhiyun /* uprobes BRK opcodes with ESR encoding */ 58*4882a593Smuzhiyun #define BRK64_OPCODE_UPROBES (AARCH64_BREAK_MON | (UPROBES_BRK_IMM << 5)) 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun /* AArch32 */ 61*4882a593Smuzhiyun #define DBG_ESR_EVT_BKPT 0x4 62*4882a593Smuzhiyun #define DBG_ESR_EVT_VECC 0x5 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun #define AARCH32_BREAK_ARM 0x07f001f0 65*4882a593Smuzhiyun #define AARCH32_BREAK_THUMB 0xde01 66*4882a593Smuzhiyun #define AARCH32_BREAK_THUMB2_LO 0xf7f0 67*4882a593Smuzhiyun #define AARCH32_BREAK_THUMB2_HI 0xa000 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun #ifndef __ASSEMBLY__ 70*4882a593Smuzhiyun struct task_struct; 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun #define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */ 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun #define DBG_HOOK_HANDLED 0 75*4882a593Smuzhiyun #define DBG_HOOK_ERROR 1 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun struct step_hook { 78*4882a593Smuzhiyun struct list_head node; 79*4882a593Smuzhiyun int (*fn)(struct pt_regs *regs, unsigned int esr); 80*4882a593Smuzhiyun }; 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun void register_user_step_hook(struct step_hook *hook); 83*4882a593Smuzhiyun void unregister_user_step_hook(struct step_hook *hook); 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun void register_kernel_step_hook(struct step_hook *hook); 86*4882a593Smuzhiyun void unregister_kernel_step_hook(struct step_hook *hook); 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun struct break_hook { 89*4882a593Smuzhiyun struct list_head node; 90*4882a593Smuzhiyun int (*fn)(struct pt_regs *regs, unsigned int esr); 91*4882a593Smuzhiyun u16 imm; 92*4882a593Smuzhiyun u16 mask; /* These bits are ignored when comparing with imm */ 93*4882a593Smuzhiyun }; 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun void register_user_break_hook(struct break_hook *hook); 96*4882a593Smuzhiyun void unregister_user_break_hook(struct break_hook *hook); 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun void register_kernel_break_hook(struct break_hook *hook); 99*4882a593Smuzhiyun void unregister_kernel_break_hook(struct break_hook *hook); 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun u8 debug_monitors_arch(void); 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun enum dbg_active_el { 104*4882a593Smuzhiyun DBG_ACTIVE_EL0 = 0, 105*4882a593Smuzhiyun DBG_ACTIVE_EL1, 106*4882a593Smuzhiyun }; 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun void enable_debug_monitors(enum dbg_active_el el); 109*4882a593Smuzhiyun void disable_debug_monitors(enum dbg_active_el el); 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun void user_rewind_single_step(struct task_struct *task); 112*4882a593Smuzhiyun void user_fastforward_single_step(struct task_struct *task); 113*4882a593Smuzhiyun void user_regs_reset_single_step(struct user_pt_regs *regs, 114*4882a593Smuzhiyun struct task_struct *task); 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun void kernel_enable_single_step(struct pt_regs *regs); 117*4882a593Smuzhiyun void kernel_disable_single_step(void); 118*4882a593Smuzhiyun int kernel_active_single_step(void); 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun #ifdef CONFIG_HAVE_HW_BREAKPOINT 121*4882a593Smuzhiyun int reinstall_suspended_bps(struct pt_regs *regs); 122*4882a593Smuzhiyun #else reinstall_suspended_bps(struct pt_regs * regs)123*4882a593Smuzhiyunstatic inline int reinstall_suspended_bps(struct pt_regs *regs) 124*4882a593Smuzhiyun { 125*4882a593Smuzhiyun return -ENODEV; 126*4882a593Smuzhiyun } 127*4882a593Smuzhiyun #endif 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun int aarch32_break_handler(struct pt_regs *regs); 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun void debug_traps_init(void); 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun #endif /* __ASSEMBLY */ 134*4882a593Smuzhiyun #endif /* __ASM_DEBUG_MONITORS_H */ 135