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