Messages in this thread Patch in this message | | | From | Anton Arapov <> | Subject | [RFC PATCH 2/6] uretprobes: trampoline implementation | Date | Fri, 21 Dec 2012 12:16:32 +0100 |
| |
The first time a uprobe with return consumer is hit for a process, a trampoline slot is obtained in the xol_area and initialized with a breakpoint instruction. This slot is subsequently used by all uretprobes.
Signed-off-by: Anton Arapov <anton@redhat.com> Signed-off-by: Anithra P Janakiraman <anithra@linux.vnet.ibm.com> --- include/linux/uprobes.h | 1 + kernel/events/uprobes.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+)
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index a5db480..68780b6 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h @@ -88,6 +88,7 @@ struct xol_area { * the vma go away, and we must handle that reasonably gracefully. */ unsigned long vaddr; /* Page(s) of instruction slots */ + unsigned long rp_trampoline_vaddr; /* address of trampolines */ }; struct uprobes_state { diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 30f2ebc..f0dbbd0 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1246,6 +1246,44 @@ static void xol_free_insn_slot(struct task_struct *tsk) } } +/* + * xol_get_trampoline_slot - A trampoline slot is obtained the first + * time a uprobe with return consumer is hit for a process. Use one + * trampoline slot for all probes pertaining to a process, i.e. + * one per xol_area. + */ +static unsigned long xol_get_trampoline_slot(void) +{ + struct xol_area *area; + unsigned long offset; + void *vaddr; + uprobe_opcode_t bp_insn = UPROBE_SWBP_INSN; + + area = get_xol_area(current->mm); + if (!area) { + area = xol_alloc_area(); + if (!area) + return 0; + } + + if (!area->rp_trampoline_vaddr) + area->rp_trampoline_vaddr = xol_take_insn_slot(area); + + /* + * Initialize the slot if rp_trampoline_vaddr points to valid + * instruction slot. + */ + if (unlikely(!area->rp_trampoline_vaddr)) + return 0; + + offset = area->rp_trampoline_vaddr & ~PAGE_MASK; + vaddr = kmap_atomic(area->page); + memcpy(vaddr + offset, &bp_insn, UPROBE_SWBP_INSN_SIZE); + kunmap_atomic(vaddr); + + return area->rp_trampoline_vaddr; +} + /** * uprobe_get_swbp_addr - compute address of swbp given post-swbp regs * @regs: Reflects the saved state of the task after it has hit a breakpoint -- 1.8.0.2
| |