diff options
author | Prasanna S. Panchamukhi <prasanna@in.ibm.com> | 2004-11-07 04:07:23 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-11-07 04:07:23 -0800 |
commit | 3d6921be81ab76bb542b9a7f04e130009e1662b1 (patch) | |
tree | 04d49bbb35240d36e48382519aab2d6cccb14d32 /kernel | |
parent | 1af13030a03ec94e8df5176ce04e6486914f786a (diff) | |
download | history-3d6921be81ab76bb542b9a7f04e130009e1662b1.tar.gz |
[PATCH] kprobes: Minor i386 changes required for porting kprobes to x86_64
- Kprobes structure has been modified to support copying of original
instruction as required by the architecture. On x86_64 normal pages we
get from kmalloc or vmalloc are not executable. Single-stepping an
instruction on such a page yields an oops. So instead of storing the
instruction copies in their respective kprobe objects, we allocate a
page, map it executable, and store all the instruction copies there and
store the pointer of the copied instruction in the specific kprobes
object.
- jprobe_return_end is moved into inline assembly to avoid compiler
optimization.
- arch_prepare_kprobe() now returns an integer,since
arch_prepare_kprobe() might fail on other architectures.
- added arch_remove_kprobe() routine, since other architectures requires
it.
Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/kprobes.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index ca4e28b4c6a759..d3d1321b0e5c2c 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -84,10 +84,13 @@ int register_kprobe(struct kprobe *p) ret = -EEXIST; goto out; } + + if ((ret = arch_prepare_kprobe(p)) != 0) { + goto out; + } hlist_add_head(&p->hlist, &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); - arch_prepare_kprobe(p); p->opcode = *p->addr; *p->addr = BREAKPOINT_INSTRUCTION; flush_icache_range((unsigned long) p->addr, @@ -101,6 +104,7 @@ void unregister_kprobe(struct kprobe *p) { unsigned long flags; spin_lock_irqsave(&kprobe_lock, flags); + arch_remove_kprobe(p); *p->addr = p->opcode; hlist_del(&p->hlist); flush_icache_range((unsigned long) p->addr, |