[IMPROVE] call uprobe handler from specific context (for ARM) 88/48688/1
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 24 Sep 2015 18:35:09 +0000 (21:35 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 24 Sep 2015 18:35:09 +0000 (21:35 +0300)
Uprobe handler will be called from context specified by atomic_ctx.

Change-Id: I325e6f1c96c8e009c39bfe9ba926683db7cb0ffa
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
preload/preload_probe.c
uprobe/arch/arm/swap-asm/swap_uprobes.c
uprobe/swap_uprobes.h
us_manager/sspt/sspt.h

index 9ca7317..18c9585 100644 (file)
@@ -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,
index d87b8a0..1250c44 100644 (file)
@@ -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);
index 66f165f..aee389c 100644 (file)
@@ -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 {
index f3e40e2..63d4822 100644 (file)
@@ -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) {