From 18c97e98769d85d068f0acef80eae5857ae9b9ce Mon Sep 17 00:00:00 2001 From: Vyacheslav Cherkashin Date: Thu, 24 Sep 2015 21:35:09 +0300 Subject: [PATCH] [IMPROVE] call uprobe handler from specific context (for ARM) Uprobe handler will be called from context specified by atomic_ctx. Change-Id: I325e6f1c96c8e009c39bfe9ba926683db7cb0ffa Signed-off-by: Vyacheslav Cherkashin --- preload/preload_probe.c | 9 ++++++++- uprobe/arch/arm/swap-asm/swap_uprobes.c | 19 ++++++++++++++++++- uprobe/swap_uprobes.h | 1 + us_manager/sspt/sspt.h | 1 + 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/preload/preload_probe.c b/preload/preload_probe.c index 9ca7317..18c9585 100644 --- a/preload/preload_probe.c +++ b/preload/preload_probe.c @@ -216,6 +216,13 @@ static void write_msg_init(struct us_ip *ip) preload_module_write_msg_init(ip); } +static int write_msg_reg(struct us_ip *ip) +{ + ip->uprobe.atomic_ctx = false; + + return get_caller_register_probe(ip); +} + static void write_msg_uninit(struct us_ip *ip) { preload_module_write_msg_exit(ip); @@ -226,7 +233,7 @@ static void write_msg_uninit(struct us_ip *ip) static struct probe_iface write_msg_iface = { .init = write_msg_init, .uninit = write_msg_uninit, - .reg = get_caller_register_probe, + .reg = write_msg_reg, .unreg = get_caller_unregister_probe, .get_uprobe = get_caller_get_uprobe, .copy = get_caller_info_copy, diff --git a/uprobe/arch/arm/swap-asm/swap_uprobes.c b/uprobe/arch/arm/swap-asm/swap_uprobes.c index d87b8a0..1250c44 100644 --- a/uprobe/arch/arm/swap-asm/swap_uprobes.c +++ b/uprobe/arch/arm/swap-asm/swap_uprobes.c @@ -935,7 +935,24 @@ int uprobe_trap_handler(struct pt_regs *regs, unsigned int instr) p = get_ukprobe((kprobe_opcode_t *)vaddr, tgid); if (p) { - if (!p->pre_handler || !p->pre_handler(p, regs)) + struct uprobe *up = kp2up(p); + bool prepare = false; + + if (up->atomic_ctx) { + if (!p->pre_handler || !p->pre_handler(p, regs)) + prepare = true; + } else { + swap_preempt_enable_no_resched(); + local_irq_restore(flags); + + if (!p->pre_handler || !p->pre_handler(p, regs)) + prepare = true; + + local_irq_save(flags); + preempt_disable(); + } + + if (prepare) prepare_singlestep(p, regs); } else { ret = urp_handler(regs, tgid); diff --git a/uprobe/swap_uprobes.h b/uprobe/swap_uprobes.h index 66f165f..aee389c 100644 --- a/uprobe/swap_uprobes.h +++ b/uprobe/swap_uprobes.h @@ -48,6 +48,7 @@ struct uprobe { struct task_struct *task; /**< Pointer to the task struct */ struct slot_manager *sm; /**< Pointer to slot manager */ struct arch_specific_tramp atramp; /**< Stores trampoline */ + bool atomic_ctx; /**< Handler context */ }; struct uinst_info { diff --git a/us_manager/sspt/sspt.h b/us_manager/sspt/sspt.h index f3e40e2..63d4822 100644 --- a/us_manager/sspt/sspt.h +++ b/us_manager/sspt/sspt.h @@ -61,6 +61,7 @@ static inline int sspt_register_usprobe(struct us_ip *ip) up->kp.addr = (kprobe_opcode_t *)ip->orig_addr; up->task = ip->page->file->proc->task; up->sm = ip->page->file->proc->sm; + up->atomic_ctx = true; ret = probe_info_register(ip->info, ip); if (ret) { -- 2.7.4