1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Kernel probes (kprobes) for SuperH |
4 | * |
5 | * Copyright (C) 2007 Chris Smith <chris.smith@st.com> |
6 | * Copyright (C) 2006 Lineo Solutions, Inc. |
7 | */ |
8 | #include <linux/kprobes.h> |
9 | #include <linux/extable.h> |
10 | #include <linux/ptrace.h> |
11 | #include <linux/preempt.h> |
12 | #include <linux/kdebug.h> |
13 | #include <linux/slab.h> |
14 | #include <asm/cacheflush.h> |
15 | #include <linux/uaccess.h> |
16 | |
17 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; |
18 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); |
19 | |
20 | static DEFINE_PER_CPU(struct kprobe, saved_current_opcode); |
21 | static DEFINE_PER_CPU(struct kprobe, saved_next_opcode); |
22 | static DEFINE_PER_CPU(struct kprobe, saved_next_opcode2); |
23 | |
24 | #define OPCODE_JMP(x) (((x) & 0xF0FF) == 0x402b) |
25 | #define OPCODE_JSR(x) (((x) & 0xF0FF) == 0x400b) |
26 | #define OPCODE_BRA(x) (((x) & 0xF000) == 0xa000) |
27 | #define OPCODE_BRAF(x) (((x) & 0xF0FF) == 0x0023) |
28 | #define OPCODE_BSR(x) (((x) & 0xF000) == 0xb000) |
29 | #define OPCODE_BSRF(x) (((x) & 0xF0FF) == 0x0003) |
30 | |
31 | #define OPCODE_BF_S(x) (((x) & 0xFF00) == 0x8f00) |
32 | #define OPCODE_BT_S(x) (((x) & 0xFF00) == 0x8d00) |
33 | |
34 | #define OPCODE_BF(x) (((x) & 0xFF00) == 0x8b00) |
35 | #define OPCODE_BT(x) (((x) & 0xFF00) == 0x8900) |
36 | |
37 | #define OPCODE_RTS(x) (((x) & 0x000F) == 0x000b) |
38 | #define OPCODE_RTE(x) (((x) & 0xFFFF) == 0x002b) |
39 | |
40 | int __kprobes arch_prepare_kprobe(struct kprobe *p) |
41 | { |
42 | kprobe_opcode_t opcode = *(kprobe_opcode_t *) (p->addr); |
43 | |
44 | if (OPCODE_RTE(opcode)) |
45 | return -EFAULT; /* Bad breakpoint */ |
46 | |
47 | p->opcode = opcode; |
48 | |
49 | return 0; |
50 | } |
51 | |
52 | void __kprobes arch_copy_kprobe(struct kprobe *p) |
53 | { |
54 | memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); |
55 | p->opcode = *p->addr; |
56 | } |
57 | |
58 | void __kprobes arch_arm_kprobe(struct kprobe *p) |
59 | { |
60 | *p->addr = BREAKPOINT_INSTRUCTION; |
61 | flush_icache_range(start: (unsigned long)p->addr, |
62 | end: (unsigned long)p->addr + sizeof(kprobe_opcode_t)); |
63 | } |
64 | |
65 | void __kprobes arch_disarm_kprobe(struct kprobe *p) |
66 | { |
67 | *p->addr = p->opcode; |
68 | flush_icache_range(start: (unsigned long)p->addr, |
69 | end: (unsigned long)p->addr + sizeof(kprobe_opcode_t)); |
70 | } |
71 | |
72 | int __kprobes arch_trampoline_kprobe(struct kprobe *p) |
73 | { |
74 | if (*p->addr == BREAKPOINT_INSTRUCTION) |
75 | return 1; |
76 | |
77 | return 0; |
78 | } |
79 | |
80 | /** |
81 | * If an illegal slot instruction exception occurs for an address |
82 | * containing a kprobe, remove the probe. |
83 | * |
84 | * Returns 0 if the exception was handled successfully, 1 otherwise. |
85 | */ |
86 | int __kprobes kprobe_handle_illslot(unsigned long pc) |
87 | { |
88 | struct kprobe *p = get_kprobe(addr: (kprobe_opcode_t *) pc + 1); |
89 | |
90 | if (p != NULL) { |
91 | printk("Warning: removing kprobe from delay slot: 0x%.8x\n" , |
92 | (unsigned int)pc + 2); |
93 | unregister_kprobe(p); |
94 | return 0; |
95 | } |
96 | |
97 | return 1; |
98 | } |
99 | |
100 | void __kprobes arch_remove_kprobe(struct kprobe *p) |
101 | { |
102 | struct kprobe *saved = this_cpu_ptr(&saved_next_opcode); |
103 | |
104 | if (saved->addr) { |
105 | arch_disarm_kprobe(p); |
106 | arch_disarm_kprobe(p: saved); |
107 | |
108 | saved->addr = NULL; |
109 | saved->opcode = 0; |
110 | |
111 | saved = this_cpu_ptr(&saved_next_opcode2); |
112 | if (saved->addr) { |
113 | arch_disarm_kprobe(p: saved); |
114 | |
115 | saved->addr = NULL; |
116 | saved->opcode = 0; |
117 | } |
118 | } |
119 | } |
120 | |
121 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) |
122 | { |
123 | kcb->prev_kprobe.kp = kprobe_running(); |
124 | kcb->prev_kprobe.status = kcb->kprobe_status; |
125 | } |
126 | |
127 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
128 | { |
129 | __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); |
130 | kcb->kprobe_status = kcb->prev_kprobe.status; |
131 | } |
132 | |
133 | static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, |
134 | struct kprobe_ctlblk *kcb) |
135 | { |
136 | __this_cpu_write(current_kprobe, p); |
137 | } |
138 | |
139 | /* |
140 | * Singlestep is implemented by disabling the current kprobe and setting one |
141 | * on the next instruction, following branches. Two probes are set if the |
142 | * branch is conditional. |
143 | */ |
144 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) |
145 | { |
146 | __this_cpu_write(saved_current_opcode.addr, (kprobe_opcode_t *)regs->pc); |
147 | |
148 | if (p != NULL) { |
149 | struct kprobe *op1, *op2; |
150 | |
151 | arch_disarm_kprobe(p); |
152 | |
153 | op1 = this_cpu_ptr(&saved_next_opcode); |
154 | op2 = this_cpu_ptr(&saved_next_opcode2); |
155 | |
156 | if (OPCODE_JSR(p->opcode) || OPCODE_JMP(p->opcode)) { |
157 | unsigned int reg_nr = ((p->opcode >> 8) & 0x000F); |
158 | op1->addr = (kprobe_opcode_t *) regs->regs[reg_nr]; |
159 | } else if (OPCODE_BRA(p->opcode) || OPCODE_BSR(p->opcode)) { |
160 | unsigned long disp = (p->opcode & 0x0FFF); |
161 | op1->addr = |
162 | (kprobe_opcode_t *) (regs->pc + 4 + disp * 2); |
163 | |
164 | } else if (OPCODE_BRAF(p->opcode) || OPCODE_BSRF(p->opcode)) { |
165 | unsigned int reg_nr = ((p->opcode >> 8) & 0x000F); |
166 | op1->addr = |
167 | (kprobe_opcode_t *) (regs->pc + 4 + |
168 | regs->regs[reg_nr]); |
169 | |
170 | } else if (OPCODE_RTS(p->opcode)) { |
171 | op1->addr = (kprobe_opcode_t *) regs->pr; |
172 | |
173 | } else if (OPCODE_BF(p->opcode) || OPCODE_BT(p->opcode)) { |
174 | unsigned long disp = (p->opcode & 0x00FF); |
175 | /* case 1 */ |
176 | op1->addr = p->addr + 1; |
177 | /* case 2 */ |
178 | op2->addr = |
179 | (kprobe_opcode_t *) (regs->pc + 4 + disp * 2); |
180 | op2->opcode = *(op2->addr); |
181 | arch_arm_kprobe(p: op2); |
182 | |
183 | } else if (OPCODE_BF_S(p->opcode) || OPCODE_BT_S(p->opcode)) { |
184 | unsigned long disp = (p->opcode & 0x00FF); |
185 | /* case 1 */ |
186 | op1->addr = p->addr + 2; |
187 | /* case 2 */ |
188 | op2->addr = |
189 | (kprobe_opcode_t *) (regs->pc + 4 + disp * 2); |
190 | op2->opcode = *(op2->addr); |
191 | arch_arm_kprobe(p: op2); |
192 | |
193 | } else { |
194 | op1->addr = p->addr + 1; |
195 | } |
196 | |
197 | op1->opcode = *(op1->addr); |
198 | arch_arm_kprobe(p: op1); |
199 | } |
200 | } |
201 | |
202 | /* Called with kretprobe_lock held */ |
203 | void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, |
204 | struct pt_regs *regs) |
205 | { |
206 | ri->ret_addr = (kprobe_opcode_t *) regs->pr; |
207 | ri->fp = NULL; |
208 | |
209 | /* Replace the return addr with trampoline addr */ |
210 | regs->pr = (unsigned long)__kretprobe_trampoline; |
211 | } |
212 | |
213 | static int __kprobes kprobe_handler(struct pt_regs *regs) |
214 | { |
215 | struct kprobe *p; |
216 | int ret = 0; |
217 | kprobe_opcode_t *addr = NULL; |
218 | struct kprobe_ctlblk *kcb; |
219 | |
220 | /* |
221 | * We don't want to be preempted for the entire |
222 | * duration of kprobe processing |
223 | */ |
224 | preempt_disable(); |
225 | kcb = get_kprobe_ctlblk(); |
226 | |
227 | addr = (kprobe_opcode_t *) (regs->pc); |
228 | |
229 | /* Check we're not actually recursing */ |
230 | if (kprobe_running()) { |
231 | p = get_kprobe(addr); |
232 | if (p) { |
233 | if (kcb->kprobe_status == KPROBE_HIT_SS && |
234 | *p->ainsn.insn == BREAKPOINT_INSTRUCTION) { |
235 | goto no_kprobe; |
236 | } |
237 | /* We have reentered the kprobe_handler(), since |
238 | * another probe was hit while within the handler. |
239 | * We here save the original kprobes variables and |
240 | * just single step on the instruction of the new probe |
241 | * without calling any user handlers. |
242 | */ |
243 | save_previous_kprobe(kcb); |
244 | set_current_kprobe(p, regs, kcb); |
245 | kprobes_inc_nmissed_count(p); |
246 | prepare_singlestep(p, regs); |
247 | kcb->kprobe_status = KPROBE_REENTER; |
248 | return 1; |
249 | } |
250 | goto no_kprobe; |
251 | } |
252 | |
253 | p = get_kprobe(addr); |
254 | if (!p) { |
255 | /* Not one of ours: let kernel handle it */ |
256 | if (*(kprobe_opcode_t *)addr != BREAKPOINT_INSTRUCTION) { |
257 | /* |
258 | * The breakpoint instruction was removed right |
259 | * after we hit it. Another cpu has removed |
260 | * either a probepoint or a debugger breakpoint |
261 | * at this address. In either case, no further |
262 | * handling of this interrupt is appropriate. |
263 | */ |
264 | ret = 1; |
265 | } |
266 | |
267 | goto no_kprobe; |
268 | } |
269 | |
270 | set_current_kprobe(p, regs, kcb); |
271 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; |
272 | |
273 | if (p->pre_handler && p->pre_handler(p, regs)) { |
274 | /* handler has already set things up, so skip ss setup */ |
275 | reset_current_kprobe(); |
276 | preempt_enable_no_resched(); |
277 | return 1; |
278 | } |
279 | |
280 | prepare_singlestep(p, regs); |
281 | kcb->kprobe_status = KPROBE_HIT_SS; |
282 | return 1; |
283 | |
284 | no_kprobe: |
285 | preempt_enable_no_resched(); |
286 | return ret; |
287 | } |
288 | |
289 | /* |
290 | * For function-return probes, init_kprobes() establishes a probepoint |
291 | * here. When a retprobed function returns, this probe is hit and |
292 | * trampoline_probe_handler() runs, calling the kretprobe's handler. |
293 | */ |
294 | static void __used kretprobe_trampoline_holder(void) |
295 | { |
296 | asm volatile (".globl __kretprobe_trampoline\n" |
297 | "__kretprobe_trampoline:\n\t" |
298 | "nop\n" ); |
299 | } |
300 | |
301 | /* |
302 | * Called when we hit the probe point at __kretprobe_trampoline |
303 | */ |
304 | int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) |
305 | { |
306 | regs->pc = __kretprobe_trampoline_handler(regs, NULL); |
307 | |
308 | return 1; |
309 | } |
310 | |
311 | static int __kprobes post_kprobe_handler(struct pt_regs *regs) |
312 | { |
313 | struct kprobe *cur = kprobe_running(); |
314 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
315 | kprobe_opcode_t *addr = NULL; |
316 | struct kprobe *p = NULL; |
317 | |
318 | if (!cur) |
319 | return 0; |
320 | |
321 | if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) { |
322 | kcb->kprobe_status = KPROBE_HIT_SSDONE; |
323 | cur->post_handler(cur, regs, 0); |
324 | } |
325 | |
326 | p = this_cpu_ptr(&saved_next_opcode); |
327 | if (p->addr) { |
328 | arch_disarm_kprobe(p); |
329 | p->addr = NULL; |
330 | p->opcode = 0; |
331 | |
332 | addr = __this_cpu_read(saved_current_opcode.addr); |
333 | __this_cpu_write(saved_current_opcode.addr, NULL); |
334 | |
335 | p = get_kprobe(addr); |
336 | arch_arm_kprobe(p); |
337 | |
338 | p = this_cpu_ptr(&saved_next_opcode2); |
339 | if (p->addr) { |
340 | arch_disarm_kprobe(p); |
341 | p->addr = NULL; |
342 | p->opcode = 0; |
343 | } |
344 | } |
345 | |
346 | /* Restore back the original saved kprobes variables and continue. */ |
347 | if (kcb->kprobe_status == KPROBE_REENTER) { |
348 | restore_previous_kprobe(kcb); |
349 | goto out; |
350 | } |
351 | |
352 | reset_current_kprobe(); |
353 | |
354 | out: |
355 | preempt_enable_no_resched(); |
356 | |
357 | return 1; |
358 | } |
359 | |
360 | int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
361 | { |
362 | struct kprobe *cur = kprobe_running(); |
363 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
364 | const struct exception_table_entry *entry; |
365 | |
366 | switch (kcb->kprobe_status) { |
367 | case KPROBE_HIT_SS: |
368 | case KPROBE_REENTER: |
369 | /* |
370 | * We are here because the instruction being single |
371 | * stepped caused a page fault. We reset the current |
372 | * kprobe, point the pc back to the probe address |
373 | * and allow the page fault handler to continue as a |
374 | * normal page fault. |
375 | */ |
376 | regs->pc = (unsigned long)cur->addr; |
377 | if (kcb->kprobe_status == KPROBE_REENTER) |
378 | restore_previous_kprobe(kcb); |
379 | else |
380 | reset_current_kprobe(); |
381 | preempt_enable_no_resched(); |
382 | break; |
383 | case KPROBE_HIT_ACTIVE: |
384 | case KPROBE_HIT_SSDONE: |
385 | /* |
386 | * In case the user-specified fault handler returned |
387 | * zero, try to fix up. |
388 | */ |
389 | if ((entry = search_exception_tables(add: regs->pc)) != NULL) { |
390 | regs->pc = entry->fixup; |
391 | return 1; |
392 | } |
393 | |
394 | /* |
395 | * fixup_exception() could not handle it, |
396 | * Let do_page_fault() fix it. |
397 | */ |
398 | break; |
399 | default: |
400 | break; |
401 | } |
402 | |
403 | return 0; |
404 | } |
405 | |
406 | /* |
407 | * Wrapper routine to for handling exceptions. |
408 | */ |
409 | int __kprobes kprobe_exceptions_notify(struct notifier_block *self, |
410 | unsigned long val, void *data) |
411 | { |
412 | struct kprobe *p = NULL; |
413 | struct die_args *args = (struct die_args *)data; |
414 | int ret = NOTIFY_DONE; |
415 | kprobe_opcode_t *addr = NULL; |
416 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
417 | |
418 | addr = (kprobe_opcode_t *) (args->regs->pc); |
419 | if (val == DIE_TRAP && |
420 | args->trapnr == (BREAKPOINT_INSTRUCTION & 0xff)) { |
421 | if (!kprobe_running()) { |
422 | if (kprobe_handler(regs: args->regs)) { |
423 | ret = NOTIFY_STOP; |
424 | } else { |
425 | /* Not a kprobe trap */ |
426 | ret = NOTIFY_DONE; |
427 | } |
428 | } else { |
429 | p = get_kprobe(addr); |
430 | if ((kcb->kprobe_status == KPROBE_HIT_SS) || |
431 | (kcb->kprobe_status == KPROBE_REENTER)) { |
432 | if (post_kprobe_handler(regs: args->regs)) |
433 | ret = NOTIFY_STOP; |
434 | } else { |
435 | if (kprobe_handler(regs: args->regs)) |
436 | ret = NOTIFY_STOP; |
437 | } |
438 | } |
439 | } |
440 | |
441 | return ret; |
442 | } |
443 | |
444 | static struct kprobe trampoline_p = { |
445 | .addr = (kprobe_opcode_t *)&__kretprobe_trampoline, |
446 | .pre_handler = trampoline_probe_handler |
447 | }; |
448 | |
449 | int __init arch_init_kprobes(void) |
450 | { |
451 | return register_kprobe(p: &trampoline_p); |
452 | } |
453 | |