aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Arapov <anton@redhat.com>2013-04-03 12:00:32 -0400
committerOleg Nesterov <oleg@redhat.com>2013-04-13 09:31:54 -0400
commite78aebfd27256ca59ccd3e6cf62cfad2a80e02d3 (patch)
tree6655e753d20bf964fbdcb6eefb3087dd954e2a1f
parentea024870cf10687b3fded66a9deb6253888f30b7 (diff)
uretprobes: Reserve the first slot in xol_vma for trampoline
Allocate trampoline page, as the very first one in uprobed task xol area, and fill it with breakpoint opcode. Also introduce get_trampoline_vaddr() helper, to wrap the trampoline address extraction from area->vaddr. That removes confusion and eases the debug experience in case ->vaddr notion will be changed. Signed-off-by: Anton Arapov <anton@redhat.com> Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
-rw-r--r--kernel/events/uprobes.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index eb384e90ac92..d345b7c6cb2d 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1132,6 +1132,7 @@ static struct xol_area *get_xol_area(void)
1132{ 1132{
1133 struct mm_struct *mm = current->mm; 1133 struct mm_struct *mm = current->mm;
1134 struct xol_area *area; 1134 struct xol_area *area;
1135 uprobe_opcode_t insn = UPROBE_SWBP_INSN;
1135 1136
1136 area = mm->uprobes_state.xol_area; 1137 area = mm->uprobes_state.xol_area;
1137 if (area) 1138 if (area)
@@ -1149,7 +1150,12 @@ static struct xol_area *get_xol_area(void)
1149 if (!area->page) 1150 if (!area->page)
1150 goto free_bitmap; 1151 goto free_bitmap;
1151 1152
1153 /* allocate first slot of task's xol_area for the return probes */
1154 set_bit(0, area->bitmap);
1155 copy_to_page(area->page, 0, &insn, UPROBE_SWBP_INSN_SIZE);
1156 atomic_set(&area->slot_count, 1);
1152 init_waitqueue_head(&area->wq); 1157 init_waitqueue_head(&area->wq);
1158
1153 if (!xol_add_vma(area)) 1159 if (!xol_add_vma(area))
1154 return area; 1160 return area;
1155 1161
@@ -1346,6 +1352,25 @@ static struct uprobe_task *get_utask(void)
1346 return current->utask; 1352 return current->utask;
1347} 1353}
1348 1354
1355/*
1356 * Current area->vaddr notion assume the trampoline address is always
1357 * equal area->vaddr.
1358 *
1359 * Returns -1 in case the xol_area is not allocated.
1360 */
1361static unsigned long get_trampoline_vaddr(void)
1362{
1363 struct xol_area *area;
1364 unsigned long trampoline_vaddr = -1;
1365
1366 area = current->mm->uprobes_state.xol_area;
1367 smp_read_barrier_depends();
1368 if (area)
1369 trampoline_vaddr = area->vaddr;
1370
1371 return trampoline_vaddr;
1372}
1373
1349/* Prepare to single-step probed instruction out of line. */ 1374/* Prepare to single-step probed instruction out of line. */
1350static int 1375static int
1351pre_ssout(struct uprobe *uprobe, struct pt_regs *regs, unsigned long bp_vaddr) 1376pre_ssout(struct uprobe *uprobe, struct pt_regs *regs, unsigned long bp_vaddr)