.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License version 2 as |
---|
6 | | - * published by the Free Software Foundation. |
---|
7 | 4 | */ |
---|
8 | 5 | |
---|
9 | 6 | #include <linux/types.h> |
---|
.. | .. |
---|
391 | 388 | { |
---|
392 | 389 | |
---|
393 | 390 | ri->ret_addr = (kprobe_opcode_t *) regs->blink; |
---|
| 391 | + ri->fp = NULL; |
---|
394 | 392 | |
---|
395 | 393 | /* Replace the return addr with trampoline addr */ |
---|
396 | 394 | regs->blink = (unsigned long)&kretprobe_trampoline; |
---|
.. | .. |
---|
399 | 397 | static int __kprobes trampoline_probe_handler(struct kprobe *p, |
---|
400 | 398 | struct pt_regs *regs) |
---|
401 | 399 | { |
---|
402 | | - struct kretprobe_instance *ri = NULL; |
---|
403 | | - struct hlist_head *head, empty_rp; |
---|
404 | | - struct hlist_node *tmp; |
---|
405 | | - unsigned long flags, orig_ret_address = 0; |
---|
406 | | - unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; |
---|
407 | | - |
---|
408 | | - INIT_HLIST_HEAD(&empty_rp); |
---|
409 | | - kretprobe_hash_lock(current, &head, &flags); |
---|
410 | | - |
---|
411 | | - /* |
---|
412 | | - * It is possible to have multiple instances associated with a given |
---|
413 | | - * task either because an multiple functions in the call path |
---|
414 | | - * have a return probe installed on them, and/or more than one return |
---|
415 | | - * return probe was registered for a target function. |
---|
416 | | - * |
---|
417 | | - * We can handle this because: |
---|
418 | | - * - instances are always inserted at the head of the list |
---|
419 | | - * - when multiple return probes are registered for the same |
---|
420 | | - * function, the first instance's ret_addr will point to the |
---|
421 | | - * real return address, and all the rest will point to |
---|
422 | | - * kretprobe_trampoline |
---|
423 | | - */ |
---|
424 | | - hlist_for_each_entry_safe(ri, tmp, head, hlist) { |
---|
425 | | - if (ri->task != current) |
---|
426 | | - /* another task is sharing our hash bucket */ |
---|
427 | | - continue; |
---|
428 | | - |
---|
429 | | - if (ri->rp && ri->rp->handler) |
---|
430 | | - ri->rp->handler(ri, regs); |
---|
431 | | - |
---|
432 | | - orig_ret_address = (unsigned long)ri->ret_addr; |
---|
433 | | - recycle_rp_inst(ri, &empty_rp); |
---|
434 | | - |
---|
435 | | - if (orig_ret_address != trampoline_address) { |
---|
436 | | - /* |
---|
437 | | - * This is the real return address. Any other |
---|
438 | | - * instances associated with this task are for |
---|
439 | | - * other calls deeper on the call stack |
---|
440 | | - */ |
---|
441 | | - break; |
---|
442 | | - } |
---|
443 | | - } |
---|
444 | | - |
---|
445 | | - kretprobe_assert(ri, orig_ret_address, trampoline_address); |
---|
446 | | - regs->ret = orig_ret_address; |
---|
447 | | - |
---|
448 | | - kretprobe_hash_unlock(current, &flags); |
---|
449 | | - |
---|
450 | | - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { |
---|
451 | | - hlist_del(&ri->hlist); |
---|
452 | | - kfree(ri); |
---|
453 | | - } |
---|
| 400 | + regs->ret = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); |
---|
454 | 401 | |
---|
455 | 402 | /* By returning a non zero value, we are telling the kprobe handler |
---|
456 | 403 | * that we don't want the post_handler to run |
---|