···480480 return 0;481481}482482483483-/* architecture specific initialization */484484-int arch_init_kprobes(void)483483+/* Called with kretprobe_lock held. The value stored in the return484484+ * address register is actually 2 instructions before where the485485+ * callee will return to. Sequences usually look something like this486486+ *487487+ * call some_function <--- return register points here488488+ * nop <--- call delay slot489489+ * whatever <--- where callee returns to490490+ *491491+ * To keep trampoline_probe_handler logic simpler, we normalize the492492+ * value kept in ri->ret_addr so we don't need to keep adjusting it493493+ * back and forth.494494+ */495495+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,496496+ struct pt_regs *regs)485497{498498+ ri->ret_addr = (kprobe_opcode_t *)(regs->u_regs[UREG_RETPC] + 8);499499+500500+ /* Replace the return addr with trampoline addr */501501+ regs->u_regs[UREG_RETPC] =502502+ ((unsigned long)kretprobe_trampoline) - 8;503503+}504504+505505+/*506506+ * Called when the probe at kretprobe trampoline is hit507507+ */508508+int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)509509+{510510+ struct kretprobe_instance *ri = NULL;511511+ struct hlist_head *head, empty_rp;512512+ struct hlist_node *node, *tmp;513513+ unsigned long flags, orig_ret_address = 0;514514+ unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;515515+516516+ INIT_HLIST_HEAD(&empty_rp);517517+ spin_lock_irqsave(&kretprobe_lock, flags);518518+ head = kretprobe_inst_table_head(current);519519+520520+ /*521521+ * It is possible to have multiple instances associated with a given522522+ * task either because an multiple functions in the call path523523+ * have a return probe installed on them, and/or more then one return524524+ * return probe was registered for a target function.525525+ *526526+ * We can handle this because:527527+ * - instances are always inserted at the head of the list528528+ * - when multiple return probes are registered for the same529529+ * function, the first instance's ret_addr will point to the530530+ * real return address, and all the rest will point to531531+ * kretprobe_trampoline532532+ */533533+ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {534534+ if (ri->task != current)535535+ /* another task is sharing our hash bucket */536536+ continue;537537+538538+ if (ri->rp && ri->rp->handler)539539+ ri->rp->handler(ri, regs);540540+541541+ orig_ret_address = (unsigned long)ri->ret_addr;542542+ recycle_rp_inst(ri, &empty_rp);543543+544544+ if (orig_ret_address != trampoline_address)545545+ /*546546+ * This is the real return address. Any other547547+ * instances associated with this task are for548548+ * other calls deeper on the call stack549549+ */550550+ break;551551+ }552552+553553+ kretprobe_assert(ri, orig_ret_address, trampoline_address);554554+ regs->tpc = orig_ret_address;555555+ regs->tnpc = orig_ret_address + 4;556556+557557+ reset_current_kprobe();558558+ spin_unlock_irqrestore(&kretprobe_lock, flags);559559+ preempt_enable_no_resched();560560+561561+ hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {562562+ hlist_del(&ri->hlist);563563+ kfree(ri);564564+ }565565+ /*566566+ * By returning a non-zero value, we are telling567567+ * kprobe_handler() that we don't want the post_handler568568+ * to run (and have re-enabled preemption)569569+ */570570+ return 1;571571+}572572+573573+void kretprobe_trampoline_holder(void)574574+{575575+ asm volatile(".global kretprobe_trampoline\n"576576+ "kretprobe_trampoline:\n"577577+ "\tnop\n"578578+ "\tnop\n");579579+}580580+static struct kprobe trampoline_p = {581581+ .addr = (kprobe_opcode_t *) &kretprobe_trampoline,582582+ .pre_handler = trampoline_probe_handler583583+};584584+585585+int __init arch_init_kprobes(void)586586+{587587+ return register_kprobe(&trampoline_p);588588+}589589+590590+int __kprobes arch_trampoline_kprobe(struct kprobe *p)591591+{592592+ if (p->addr == (kprobe_opcode_t *)&kretprobe_trampoline)593593+ return 1;594594+486595 return 0;487596}
+4
include/asm-sparc64/kprobes.h
···14141515#define arch_remove_kprobe(p) do {} while (0)16161717+#define ARCH_SUPPORTS_KRETPROBES1818+1719#define flush_insn_slot(p) \1820do { flushi(&(p)->ainsn.insn[0]); \1921 flushi(&(p)->ainsn.insn[1]); \2022} while (0)2323+2424+void kretprobe_trampoline(void);21252226/* Architecture specific copy of original instruction*/2327struct arch_specific_insn {