summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>2015-09-24 21:35:09 +0300
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>2015-09-24 21:35:09 +0300
commit18c97e98769d85d068f0acef80eae5857ae9b9ce (patch)
tree90860e755ca632a1a170cc169d283ab07570ff9e
parent87489e87a4abad57558ff3e7ab775dc264348342 (diff)
downloadswap-modules-18c97e98769d85d068f0acef80eae5857ae9b9ce.tar.gz
swap-modules-18c97e98769d85d068f0acef80eae5857ae9b9ce.tar.bz2
swap-modules-18c97e98769d85d068f0acef80eae5857ae9b9ce.zip
[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 <v.cherkashin@samsung.com>
-rw-r--r--preload/preload_probe.c9
-rw-r--r--uprobe/arch/arm/swap-asm/swap_uprobes.c19
-rw-r--r--uprobe/swap_uprobes.h1
-rw-r--r--us_manager/sspt/sspt.h1
4 files changed, 28 insertions, 2 deletions
diff --git a/preload/preload_probe.c b/preload/preload_probe.c
index 9ca7317e..18c9585d 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 d87b8a0a..1250c447 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 66f165ff..aee389c4 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 f3e40e2a..63d4822e 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) {