1 // SPDX-License-Identifier: GPL-2.0-or-later 2 3 #include <linux/regset.h> 4 #include <linux/hw_breakpoint.h> 5 6 #include <asm/debug.h> 7 8 #include "ptrace-decl.h" 9 10 void user_enable_single_step(struct task_struct *task) 11 { 12 struct pt_regs *regs = task->thread.regs; 13 14 if (regs != NULL) { 15 regs->msr &= ~MSR_BE; 16 regs->msr |= MSR_SE; 17 } 18 set_tsk_thread_flag(task, TIF_SINGLESTEP); 19 } 20 21 void user_enable_block_step(struct task_struct *task) 22 { 23 struct pt_regs *regs = task->thread.regs; 24 25 if (regs != NULL) { 26 regs->msr &= ~MSR_SE; 27 regs->msr |= MSR_BE; 28 } 29 set_tsk_thread_flag(task, TIF_SINGLESTEP); 30 } 31 32 void user_disable_single_step(struct task_struct *task) 33 { 34 struct pt_regs *regs = task->thread.regs; 35 36 if (regs != NULL) 37 regs->msr &= ~(MSR_SE | MSR_BE); 38 39 clear_tsk_thread_flag(task, TIF_SINGLESTEP); 40 } 41 42 void ppc_gethwdinfo(struct ppc_debug_info *dbginfo) 43 { 44 dbginfo->version = 1; 45 dbginfo->num_instruction_bps = 0; 46 if (ppc_breakpoint_available()) 47 dbginfo->num_data_bps = nr_wp_slots(); 48 else 49 dbginfo->num_data_bps = 0; 50 dbginfo->num_condition_regs = 0; 51 dbginfo->data_bp_alignment = sizeof(long); 52 dbginfo->sizeof_condition = 0; 53 if (IS_ENABLED(CONFIG_HAVE_HW_BREAKPOINT)) { 54 dbginfo->features = PPC_DEBUG_FEATURE_DATA_BP_RANGE; 55 if (dawr_enabled()) 56 dbginfo->features |= PPC_DEBUG_FEATURE_DATA_BP_DAWR; 57 } else { 58 dbginfo->features = 0; 59 } 60 } 61 62 int ptrace_get_debugreg(struct task_struct *child, unsigned long addr, 63 unsigned long __user *datalp) 64 { 65 unsigned long dabr_fake; 66 67 /* We only support one DABR and no IABRS at the moment */ 68 if (addr > 0) 69 return -EINVAL; 70 dabr_fake = ((child->thread.hw_brk[0].address & (~HW_BRK_TYPE_DABR)) | 71 (child->thread.hw_brk[0].type & HW_BRK_TYPE_DABR)); 72 return put_user(dabr_fake, datalp); 73 } 74 75 /* 76 * ptrace_set_debugreg() fakes DABR and DABR is only one. So even if 77 * internal hw supports more than one watchpoint, we support only one 78 * watchpoint with this interface. 79 */ 80 int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned long data) 81 { 82 #ifdef CONFIG_HAVE_HW_BREAKPOINT 83 int ret; 84 struct thread_struct *thread = &task->thread; 85 struct perf_event *bp; 86 struct perf_event_attr attr; 87 #endif /* CONFIG_HAVE_HW_BREAKPOINT */ 88 bool set_bp = true; 89 struct arch_hw_breakpoint hw_brk; 90 91 /* For ppc64 we support one DABR and no IABR's at the moment (ppc64). 92 * For embedded processors we support one DAC and no IAC's at the 93 * moment. 94 */ 95 if (addr > 0) 96 return -EINVAL; 97 98 /* The bottom 3 bits in dabr are flags */ 99 if ((data & ~0x7UL) >= TASK_SIZE) 100 return -EIO; 101 102 /* For processors using DABR (i.e. 970), the bottom 3 bits are flags. 103 * It was assumed, on previous implementations, that 3 bits were 104 * passed together with the data address, fitting the design of the 105 * DABR register, as follows: 106 * 107 * bit 0: Read flag 108 * bit 1: Write flag 109 * bit 2: Breakpoint translation 110 * 111 * Thus, we use them here as so. 112 */ 113 114 /* Ensure breakpoint translation bit is set */ 115 if (data && !(data & HW_BRK_TYPE_TRANSLATE)) 116 return -EIO; 117 hw_brk.address = data & (~HW_BRK_TYPE_DABR); 118 hw_brk.type = (data & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL; 119 hw_brk.len = DABR_MAX_LEN; 120 hw_brk.hw_len = DABR_MAX_LEN; 121 set_bp = (data) && (hw_brk.type & HW_BRK_TYPE_RDWR); 122 #ifdef CONFIG_HAVE_HW_BREAKPOINT 123 bp = thread->ptrace_bps[0]; 124 if (!set_bp) { 125 if (bp) { 126 unregister_hw_breakpoint(bp); 127 thread->ptrace_bps[0] = NULL; 128 } 129 return 0; 130 } 131 if (bp) { 132 attr = bp->attr; 133 attr.bp_addr = hw_brk.address; 134 attr.bp_len = DABR_MAX_LEN; 135 arch_bp_generic_fields(hw_brk.type, &attr.bp_type); 136 137 /* Enable breakpoint */ 138 attr.disabled = false; 139 140 ret = modify_user_hw_breakpoint(bp, &attr); 141 if (ret) 142 return ret; 143 144 thread->ptrace_bps[0] = bp; 145 thread->hw_brk[0] = hw_brk; 146 return 0; 147 } 148 149 /* Create a new breakpoint request if one doesn't exist already */ 150 hw_breakpoint_init(&attr); 151 attr.bp_addr = hw_brk.address; 152 attr.bp_len = DABR_MAX_LEN; 153 arch_bp_generic_fields(hw_brk.type, 154 &attr.bp_type); 155 156 thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr, 157 ptrace_triggered, NULL, task); 158 if (IS_ERR(bp)) { 159 thread->ptrace_bps[0] = NULL; 160 return PTR_ERR(bp); 161 } 162 163 #else /* !CONFIG_HAVE_HW_BREAKPOINT */ 164 if (set_bp && (!ppc_breakpoint_available())) 165 return -ENODEV; 166 #endif /* CONFIG_HAVE_HW_BREAKPOINT */ 167 task->thread.hw_brk[0] = hw_brk; 168 return 0; 169 } 170 171 #ifdef CONFIG_HAVE_HW_BREAKPOINT 172 static int find_empty_ptrace_bp(struct thread_struct *thread) 173 { 174 int i; 175 176 for (i = 0; i < nr_wp_slots(); i++) { 177 if (!thread->ptrace_bps[i]) 178 return i; 179 } 180 return -1; 181 } 182 #endif 183 184 static int find_empty_hw_brk(struct thread_struct *thread) 185 { 186 int i; 187 188 for (i = 0; i < nr_wp_slots(); i++) { 189 if (!thread->hw_brk[i].address) 190 return i; 191 } 192 return -1; 193 } 194 195 long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) 196 { 197 int i; 198 #ifdef CONFIG_HAVE_HW_BREAKPOINT 199 int len = 0; 200 struct thread_struct *thread = &child->thread; 201 struct perf_event *bp; 202 struct perf_event_attr attr; 203 #endif /* CONFIG_HAVE_HW_BREAKPOINT */ 204 struct arch_hw_breakpoint brk; 205 206 if (bp_info->version != 1) 207 return -ENOTSUPP; 208 /* 209 * We only support one data breakpoint 210 */ 211 if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 || 212 (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 || 213 bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE) 214 return -EINVAL; 215 216 if ((unsigned long)bp_info->addr >= TASK_SIZE) 217 return -EIO; 218 219 brk.address = ALIGN_DOWN(bp_info->addr, HW_BREAKPOINT_SIZE); 220 brk.type = HW_BRK_TYPE_TRANSLATE; 221 brk.len = DABR_MAX_LEN; 222 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) 223 brk.type |= HW_BRK_TYPE_READ; 224 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) 225 brk.type |= HW_BRK_TYPE_WRITE; 226 #ifdef CONFIG_HAVE_HW_BREAKPOINT 227 if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) 228 len = bp_info->addr2 - bp_info->addr; 229 else if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT) 230 len = 1; 231 else 232 return -EINVAL; 233 234 i = find_empty_ptrace_bp(thread); 235 if (i < 0) 236 return -ENOSPC; 237 238 /* Create a new breakpoint request if one doesn't exist already */ 239 hw_breakpoint_init(&attr); 240 attr.bp_addr = (unsigned long)bp_info->addr; 241 attr.bp_len = len; 242 arch_bp_generic_fields(brk.type, &attr.bp_type); 243 244 bp = register_user_hw_breakpoint(&attr, ptrace_triggered, NULL, child); 245 thread->ptrace_bps[i] = bp; 246 if (IS_ERR(bp)) { 247 thread->ptrace_bps[i] = NULL; 248 return PTR_ERR(bp); 249 } 250 251 return i + 1; 252 #endif /* CONFIG_HAVE_HW_BREAKPOINT */ 253 254 if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) 255 return -EINVAL; 256 257 i = find_empty_hw_brk(&child->thread); 258 if (i < 0) 259 return -ENOSPC; 260 261 if (!ppc_breakpoint_available()) 262 return -ENODEV; 263 264 child->thread.hw_brk[i] = brk; 265 266 return i + 1; 267 } 268 269 long ppc_del_hwdebug(struct task_struct *child, long data) 270 { 271 #ifdef CONFIG_HAVE_HW_BREAKPOINT 272 int ret = 0; 273 struct thread_struct *thread = &child->thread; 274 struct perf_event *bp; 275 #endif /* CONFIG_HAVE_HW_BREAKPOINT */ 276 if (data < 1 || data > nr_wp_slots()) 277 return -EINVAL; 278 279 #ifdef CONFIG_HAVE_HW_BREAKPOINT 280 bp = thread->ptrace_bps[data - 1]; 281 if (bp) { 282 unregister_hw_breakpoint(bp); 283 thread->ptrace_bps[data - 1] = NULL; 284 } else { 285 ret = -ENOENT; 286 } 287 return ret; 288 #else /* CONFIG_HAVE_HW_BREAKPOINT */ 289 if (child->thread.hw_brk[data - 1].address == 0) 290 return -ENOENT; 291 292 child->thread.hw_brk[data - 1].address = 0; 293 child->thread.hw_brk[data - 1].type = 0; 294 #endif /* CONFIG_HAVE_HW_BREAKPOINT */ 295 296 return 0; 297 } 298