summaryrefslogtreecommitdiff
path: root/kprobe
diff options
context:
space:
mode:
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>2013-06-18 12:56:27 +0400
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>2013-06-18 14:53:42 +0400
commitfe8e3e24f2d76600407de3822248ab0faf85647c (patch)
tree69e22e792384fb685a246ada58feb85d60282e6b /kprobe
parent49fb61dc2819d727d000e6aff6fe89964306f63b (diff)
parent9f9fc82513d5ed46d099615b1c1ce37bc5b437c5 (diff)
downloadswap-modules-fe8e3e24f2d76600407de3822248ab0faf85647c.tar.gz
swap-modules-fe8e3e24f2d76600407de3822248ab0faf85647c.tar.bz2
swap-modules-fe8e3e24f2d76600407de3822248ab0faf85647c.zip
Merge commit 'cc09f10e84d5' into kernel
Conflicts: src/modules/kprobe/arch/asm-arm/dbi_kprobes.c src/modules/kprobe/arch/asm-arm/dbi_kprobes_arm.h src/modules/kprobe/arch/dbi_kprobes.h src/modules/kprobe/dbi_kprobes.c
Diffstat (limited to 'kprobe')
-rw-r--r--kprobe/arch/asm-arm/dbi_kprobes.c28
-rw-r--r--kprobe/arch/asm-arm/dbi_kprobes.h3
-rw-r--r--kprobe/arch/asm-arm/trampoline_arm.S8
-rw-r--r--kprobe/arch/asm-arm/trampoline_arm.h1
-rw-r--r--kprobe/dbi_kprobes.c25
5 files changed, 26 insertions, 39 deletions
diff --git a/kprobe/arch/asm-arm/dbi_kprobes.c b/kprobe/arch/asm-arm/dbi_kprobes.c
index f4e1a753..399df62a 100644
--- a/kprobe/arch/asm-arm/dbi_kprobes.c
+++ b/kprobe/arch/asm-arm/dbi_kprobes.c
@@ -56,12 +56,6 @@ extern struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
static void (*__swap_register_undef_hook)(struct undef_hook *hook);
static void (*__swap_unregister_undef_hook)(struct undef_hook *hook);
-static struct kprobe trampoline_p =
-{
- .addr = (kprobe_opcode_t *)&kretprobe_trampoline,
- .pre_handler = trampoline_probe_handler
-};
-
int prep_pc_dep_insn_execbuf(kprobe_opcode_t *insns, kprobe_opcode_t insn, int uregs)
{
int i;
@@ -404,6 +398,19 @@ void arch_disarm_kprobe(struct kprobe *p)
flush_icache_range((unsigned long)p->addr, (unsigned long)p->addr + sizeof(kprobe_opcode_t));
}
+void __naked kretprobe_trampoline(void)
+{
+ __asm__ __volatile__ (
+ "stmdb sp!, {r0 - r11} \n\t"
+ "mov r1, sp \n\t"
+ "mov r0, #0 \n\t"
+ "bl trampoline_probe_handler\n\t"
+ "mov lr, r0 \n\t"
+ "ldmia sp!, {r0 - r11} \n\t"
+ "bx lr \n\t"
+ : : : "memory");
+}
+
void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs)
{
ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr;
@@ -436,8 +443,6 @@ static struct undef_hook undef_ho_k = {
int arch_init_kprobes(void)
{
- int ret = 0;
-
// Register hooks (kprobe_handler)
__swap_register_undef_hook = swap_ksyms("register_undef_hook");
if (__swap_register_undef_hook == NULL) {
@@ -453,17 +458,12 @@ int arch_init_kprobes(void)
}
swap_register_undef_hook(&undef_ho_k);
- if ((ret = dbi_register_kprobe (&trampoline_p)) != 0) {
- //dbi_unregister_jprobe(&do_exit_p, 0);
- return ret;
- }
- return ret;
+ return 0;
}
void arch_exit_kprobes(void)
{
- dbi_unregister_kprobe(&trampoline_p, NULL);
swap_unregister_undef_hook(&undef_ho_k);
}
diff --git a/kprobe/arch/asm-arm/dbi_kprobes.h b/kprobe/arch/asm-arm/dbi_kprobes.h
index 5e36549a..013e85fd 100644
--- a/kprobe/arch/asm-arm/dbi_kprobes.h
+++ b/kprobe/arch/asm-arm/dbi_kprobes.h
@@ -30,6 +30,7 @@
*/
#include <linux/sched.h>
+#include <linux/compiler.h>
typedef unsigned long kprobe_opcode_t;
@@ -508,7 +509,7 @@ void save_previous_kprobe(struct kprobe_ctlblk *kcb, struct kprobe *cur_p);
void restore_previous_kprobe(struct kprobe_ctlblk *kcb);
void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb);
-void kretprobe_trampoline(void);
+void __naked kretprobe_trampoline(void);
int arch_init_kprobes(void);
void arch_exit_kprobes(void);
diff --git a/kprobe/arch/asm-arm/trampoline_arm.S b/kprobe/arch/asm-arm/trampoline_arm.S
index 73199c9c..5b4c7bc1 100644
--- a/kprobe/arch/asm-arm/trampoline_arm.S
+++ b/kprobe/arch/asm-arm/trampoline_arm.S
@@ -4,14 +4,6 @@
* - When the probed function returns, this probe
* causes the handlers to fire
*/
- .global kretprobe_trampoline
-
-kretprobe_trampoline:
- nop
- nop
- mov pc, r14
-
-
.global gen_insn_execbuf
gen_insn_execbuf:
diff --git a/kprobe/arch/asm-arm/trampoline_arm.h b/kprobe/arch/asm-arm/trampoline_arm.h
index 1114d73c..3b35f2ff 100644
--- a/kprobe/arch/asm-arm/trampoline_arm.h
+++ b/kprobe/arch/asm-arm/trampoline_arm.h
@@ -1,7 +1,6 @@
#ifndef __ASM_ARM_TRAMPOLINE_ARM_H
#define __ASM_ARM_TRAMPOLINE_ARM_H
-void kretprobe_trampoline(void);
void gen_insn_execbuf(void);
void pc_dep_insn_execbuf(void);
diff --git a/kprobe/dbi_kprobes.c b/kprobe/dbi_kprobes.c
index 7bc03f5d..208d88e2 100644
--- a/kprobe/dbi_kprobes.c
+++ b/kprobe/dbi_kprobes.c
@@ -648,7 +648,10 @@ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
struct kretprobe *crp = NULL;
- struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ struct kprobe_ctlblk *kcb;
+
+ preempt_disable();
+ kcb = get_kprobe_ctlblk();
spin_lock_irqsave(&kretprobe_lock, flags);
@@ -702,11 +705,6 @@ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
}
kretprobe_assert(ri, orig_ret_address, trampoline_address);
-#ifdef CONFIG_ARM
- regs->ARM_lr = orig_ret_address;
- regs->ARM_pc = orig_ret_address;
-#endif
-
if (kcb->kprobe_status == KPROBE_REENTER) {
restore_previous_kprobe(kcb);
} else {
@@ -714,6 +712,7 @@ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
}
spin_unlock_irqrestore(&kretprobe_lock, flags);
+ preempt_enable_no_resched();
/*
* By returning a non-zero value, we are telling
@@ -721,11 +720,7 @@ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
* to run (and have re-enabled preemption)
*/
-#if defined (CONFIG_X86)
return (int)orig_ret_address;
-#elif defined (CONFIG_ARM)
- return 1;
-#endif
}
struct kretprobe *sched_rp;
@@ -843,13 +838,13 @@ void dbi_unregister_kretprobe(struct kretprobe *rp)
if ((unsigned long)rp->kp.addr == sched_addr)
sched_rp = NULL;
- while ((ri = get_used_rp_inst(rp)) != NULL) {
- if (dbi_disarm_krp_inst(ri) == 0)
- recycle_rp_inst(ri);
- else
- panic("%s (%d/%d): cannot disarm krp instance (%08lx)",
+ while ((ri = get_used_rp_inst (rp)) != NULL) {
+ if (!dbi_disarm_krp_inst(ri)) {
+ printk("%s (%d/%d): cannot disarm krp instance (%08lx)\n",
ri->task->comm, ri->task->tgid, ri->task->pid,
(unsigned long)rp->kp.addr);
+ }
+ recycle_rp_inst(ri);
}
spin_unlock_irqrestore(&kretprobe_lock, flags);