.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * Kernel probes (kprobes) for SuperH |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2007 Chris Smith <chris.smith@st.com> |
---|
5 | 6 | * Copyright (C) 2006 Lineo Solutions, Inc. |
---|
6 | | - * |
---|
7 | | - * This file is subject to the terms and conditions of the GNU General Public |
---|
8 | | - * License. See the file "COPYING" in the main directory of this archive |
---|
9 | | - * for more details. |
---|
10 | 7 | */ |
---|
11 | 8 | #include <linux/kprobes.h> |
---|
12 | 9 | #include <linux/extable.h> |
---|
.. | .. |
---|
207 | 204 | struct pt_regs *regs) |
---|
208 | 205 | { |
---|
209 | 206 | ri->ret_addr = (kprobe_opcode_t *) regs->pr; |
---|
| 207 | + ri->fp = NULL; |
---|
210 | 208 | |
---|
211 | 209 | /* Replace the return addr with trampoline addr */ |
---|
212 | 210 | regs->pr = (unsigned long)kretprobe_trampoline; |
---|
.. | .. |
---|
305 | 303 | */ |
---|
306 | 304 | int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) |
---|
307 | 305 | { |
---|
308 | | - struct kretprobe_instance *ri = NULL; |
---|
309 | | - struct hlist_head *head, empty_rp; |
---|
310 | | - struct hlist_node *tmp; |
---|
311 | | - unsigned long flags, orig_ret_address = 0; |
---|
312 | | - unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; |
---|
| 306 | + regs->pc = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); |
---|
313 | 307 | |
---|
314 | | - INIT_HLIST_HEAD(&empty_rp); |
---|
315 | | - kretprobe_hash_lock(current, &head, &flags); |
---|
316 | | - |
---|
317 | | - /* |
---|
318 | | - * It is possible to have multiple instances associated with a given |
---|
319 | | - * task either because an multiple functions in the call path |
---|
320 | | - * have a return probe installed on them, and/or more then one return |
---|
321 | | - * return probe was registered for a target function. |
---|
322 | | - * |
---|
323 | | - * We can handle this because: |
---|
324 | | - * - instances are always inserted at the head of the list |
---|
325 | | - * - when multiple return probes are registered for the same |
---|
326 | | - * function, the first instance's ret_addr will point to the |
---|
327 | | - * real return address, and all the rest will point to |
---|
328 | | - * kretprobe_trampoline |
---|
329 | | - */ |
---|
330 | | - hlist_for_each_entry_safe(ri, tmp, head, hlist) { |
---|
331 | | - if (ri->task != current) |
---|
332 | | - /* another task is sharing our hash bucket */ |
---|
333 | | - continue; |
---|
334 | | - |
---|
335 | | - if (ri->rp && ri->rp->handler) { |
---|
336 | | - __this_cpu_write(current_kprobe, &ri->rp->kp); |
---|
337 | | - ri->rp->handler(ri, regs); |
---|
338 | | - __this_cpu_write(current_kprobe, NULL); |
---|
339 | | - } |
---|
340 | | - |
---|
341 | | - orig_ret_address = (unsigned long)ri->ret_addr; |
---|
342 | | - recycle_rp_inst(ri, &empty_rp); |
---|
343 | | - |
---|
344 | | - if (orig_ret_address != trampoline_address) |
---|
345 | | - /* |
---|
346 | | - * This is the real return address. Any other |
---|
347 | | - * instances associated with this task are for |
---|
348 | | - * other calls deeper on the call stack |
---|
349 | | - */ |
---|
350 | | - break; |
---|
351 | | - } |
---|
352 | | - |
---|
353 | | - kretprobe_assert(ri, orig_ret_address, trampoline_address); |
---|
354 | | - |
---|
355 | | - regs->pc = orig_ret_address; |
---|
356 | | - kretprobe_hash_unlock(current, &flags); |
---|
357 | | - |
---|
358 | | - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { |
---|
359 | | - hlist_del(&ri->hlist); |
---|
360 | | - kfree(ri); |
---|
361 | | - } |
---|
362 | | - |
---|
363 | | - return orig_ret_address; |
---|
| 308 | + return 1; |
---|
364 | 309 | } |
---|
365 | 310 | |
---|
366 | 311 | static int __kprobes post_kprobe_handler(struct pt_regs *regs) |
---|
.. | .. |
---|
488 | 433 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
---|
489 | 434 | |
---|
490 | 435 | addr = (kprobe_opcode_t *) (args->regs->pc); |
---|
491 | | - if (val == DIE_TRAP) { |
---|
| 436 | + if (val == DIE_TRAP && |
---|
| 437 | + args->trapnr == (BREAKPOINT_INSTRUCTION & 0xff)) { |
---|
492 | 438 | if (!kprobe_running()) { |
---|
493 | 439 | if (kprobe_handler(args->regs)) { |
---|
494 | 440 | ret = NOTIFY_STOP; |
---|