| .. | .. |
|---|
| 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; |
|---|