| From ae35d66c5000bcbccb7c1c7451156ff5e2339fb7 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sat, 29 Aug 2020 22:01:09 +0900 |
| Subject: ia64: kprobes: Use generic kretprobe trampoline handler |
| |
| From: Masami Hiramatsu <mhiramat@kernel.org> |
| |
| [ Upstream commit e792ff804f49720ce003b3e4c618b5d996256a18 ] |
| |
| Use the generic kretprobe trampoline handler. Don't use |
| framepointer verification. |
| |
| Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Link: https://lore.kernel.org/r/159870606883.1229682.12331813108378725668.stgit@devnote2 |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| arch/ia64/kernel/kprobes.c | 77 +------------------------------------- |
| 1 file changed, 2 insertions(+), 75 deletions(-) |
| |
| diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c |
| index 7a7df944d7986..fc1ff8a4d7de6 100644 |
| --- a/arch/ia64/kernel/kprobes.c |
| +++ b/arch/ia64/kernel/kprobes.c |
| @@ -396,83 +396,9 @@ static void kretprobe_trampoline(void) |
| { |
| } |
| |
| -/* |
| - * At this point the target function has been tricked into |
| - * returning into our trampoline. Lookup the associated instance |
| - * and then: |
| - * - call the handler function |
| - * - cleanup by marking the instance as unused |
| - * - long jump back to the original return address |
| - */ |
| int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) |
| { |
| - struct kretprobe_instance *ri = NULL; |
| - struct hlist_head *head, empty_rp; |
| - struct hlist_node *tmp; |
| - unsigned long flags, orig_ret_address = 0; |
| - unsigned long trampoline_address = |
| - ((struct fnptr *)kretprobe_trampoline)->ip; |
| - |
| - INIT_HLIST_HEAD(&empty_rp); |
| - kretprobe_hash_lock(current, &head, &flags); |
| - |
| - /* |
| - * It is possible to have multiple instances associated with a given |
| - * task either because an multiple functions in the call path |
| - * have a return probe installed on them, and/or more than one return |
| - * return probe was registered for a target function. |
| - * |
| - * We can handle this because: |
| - * - instances are always inserted at the head of the list |
| - * - when multiple return probes are registered for the same |
| - * function, the first instance's ret_addr will point to the |
| - * real return address, and all the rest will point to |
| - * kretprobe_trampoline |
| - */ |
| - hlist_for_each_entry_safe(ri, tmp, head, hlist) { |
| - if (ri->task != current) |
| - /* another task is sharing our hash bucket */ |
| - continue; |
| - |
| - orig_ret_address = (unsigned long)ri->ret_addr; |
| - if (orig_ret_address != trampoline_address) |
| - /* |
| - * This is the real return address. Any other |
| - * instances associated with this task are for |
| - * other calls deeper on the call stack |
| - */ |
| - break; |
| - } |
| - |
| - regs->cr_iip = orig_ret_address; |
| - |
| - hlist_for_each_entry_safe(ri, tmp, head, hlist) { |
| - if (ri->task != current) |
| - /* another task is sharing our hash bucket */ |
| - continue; |
| - |
| - if (ri->rp && ri->rp->handler) |
| - ri->rp->handler(ri, regs); |
| - |
| - orig_ret_address = (unsigned long)ri->ret_addr; |
| - recycle_rp_inst(ri, &empty_rp); |
| - |
| - if (orig_ret_address != trampoline_address) |
| - /* |
| - * This is the real return address. Any other |
| - * instances associated with this task are for |
| - * other calls deeper on the call stack |
| - */ |
| - break; |
| - } |
| - kretprobe_assert(ri, orig_ret_address, trampoline_address); |
| - |
| - kretprobe_hash_unlock(current, &flags); |
| - |
| - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { |
| - hlist_del(&ri->hlist); |
| - kfree(ri); |
| - } |
| + regs->cr_iip = __kretprobe_trampoline_handler(regs, kretprobe_trampoline, NULL); |
| /* |
| * By returning a non-zero value, we are telling |
| * kprobe_handler() that we don't want the post_handler |
| @@ -485,6 +411,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, |
| struct pt_regs *regs) |
| { |
| ri->ret_addr = (kprobe_opcode_t *)regs->b0; |
| + ri->fp = NULL; |
| |
| /* Replace the return addr with trampoline addr */ |
| regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip; |
| -- |
| 2.27.0 |
| |