Commit 26b31c19 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Linus Torvalds

kprobes: add (un)register_jprobes for batch registration

Introduce unregister_/register_jprobes() for jprobe batch registration.
Signed-off-by: default avatarMasami Hiramatsu <mhiramat@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: Prasanna S Panchamukhi <prasanna@in.ibm.com>
Cc: Shaohua Li <shaohua.li@intel.com>
Cc: David Miller <davem@davemloft.net>
Cc: "Frank Ch. Eigler" <fche@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 4a296e07
...@@ -240,6 +240,8 @@ int setjmp_pre_handler(struct kprobe *, struct pt_regs *); ...@@ -240,6 +240,8 @@ int setjmp_pre_handler(struct kprobe *, struct pt_regs *);
int longjmp_break_handler(struct kprobe *, struct pt_regs *); int longjmp_break_handler(struct kprobe *, struct pt_regs *);
int register_jprobe(struct jprobe *p); int register_jprobe(struct jprobe *p);
void unregister_jprobe(struct jprobe *p); void unregister_jprobe(struct jprobe *p);
int register_jprobes(struct jprobe **jps, int num);
void unregister_jprobes(struct jprobe **jps, int num);
void jprobe_return(void); void jprobe_return(void);
unsigned long arch_deref_entry_point(void *); unsigned long arch_deref_entry_point(void *);
...@@ -279,9 +281,16 @@ static inline int register_jprobe(struct jprobe *p) ...@@ -279,9 +281,16 @@ static inline int register_jprobe(struct jprobe *p)
{ {
return -ENOSYS; return -ENOSYS;
} }
static inline int register_jprobes(struct jprobe **jps, int num)
{
return -ENOSYS;
}
static inline void unregister_jprobe(struct jprobe *p) static inline void unregister_jprobe(struct jprobe *p)
{ {
} }
static inline void unregister_jprobes(struct jprobe **jps, int num)
{
}
static inline void jprobe_return(void) static inline void jprobe_return(void)
{ {
} }
......
...@@ -755,24 +755,69 @@ unsigned long __weak arch_deref_entry_point(void *entry) ...@@ -755,24 +755,69 @@ unsigned long __weak arch_deref_entry_point(void *entry)
return (unsigned long)entry; return (unsigned long)entry;
} }
int __kprobes register_jprobe(struct jprobe *jp) static int __register_jprobes(struct jprobe **jps, int num,
unsigned long called_from)
{ {
unsigned long addr = arch_deref_entry_point(jp->entry); struct jprobe *jp;
int ret = 0, i;
if (!kernel_text_address(addr)) if (num <= 0)
return -EINVAL; return -EINVAL;
for (i = 0; i < num; i++) {
unsigned long addr;
jp = jps[i];
addr = arch_deref_entry_point(jp->entry);
if (!kernel_text_address(addr))
ret = -EINVAL;
else {
/* Todo: Verify probepoint is a function entry point */
jp->kp.pre_handler = setjmp_pre_handler;
jp->kp.break_handler = longjmp_break_handler;
ret = __register_kprobe(&jp->kp, called_from);
}
if (ret < 0 && i > 0) {
unregister_jprobes(jps, i);
break;
}
}
return ret;
}
/* Todo: Verify probepoint is a function entry point */ int __kprobes register_jprobe(struct jprobe *jp)
jp->kp.pre_handler = setjmp_pre_handler; {
jp->kp.break_handler = longjmp_break_handler; return __register_jprobes(&jp, 1,
return __register_kprobe(&jp->kp,
(unsigned long)__builtin_return_address(0)); (unsigned long)__builtin_return_address(0));
} }
void __kprobes unregister_jprobe(struct jprobe *jp) void __kprobes unregister_jprobe(struct jprobe *jp)
{ {
unregister_kprobe(&jp->kp); unregister_jprobes(&jp, 1);
}
int __kprobes register_jprobes(struct jprobe **jps, int num)
{
return __register_jprobes(jps, num,
(unsigned long)__builtin_return_address(0));
}
void __kprobes unregister_jprobes(struct jprobe **jps, int num)
{
int i;
if (num <= 0)
return;
mutex_lock(&kprobe_mutex);
for (i = 0; i < num; i++)
if (__unregister_kprobe_top(&jps[i]->kp) < 0)
jps[i]->kp.addr = NULL;
mutex_unlock(&kprobe_mutex);
synchronize_sched();
for (i = 0; i < num; i++) {
if (jps[i]->kp.addr)
__unregister_kprobe_bottom(&jps[i]->kp);
}
} }
#ifdef CONFIG_KRETPROBES #ifdef CONFIG_KRETPROBES
...@@ -1236,6 +1281,8 @@ EXPORT_SYMBOL_GPL(register_kprobes); ...@@ -1236,6 +1281,8 @@ EXPORT_SYMBOL_GPL(register_kprobes);
EXPORT_SYMBOL_GPL(unregister_kprobes); EXPORT_SYMBOL_GPL(unregister_kprobes);
EXPORT_SYMBOL_GPL(register_jprobe); EXPORT_SYMBOL_GPL(register_jprobe);
EXPORT_SYMBOL_GPL(unregister_jprobe); EXPORT_SYMBOL_GPL(unregister_jprobe);
EXPORT_SYMBOL_GPL(register_jprobes);
EXPORT_SYMBOL_GPL(unregister_jprobes);
#ifdef CONFIG_KPROBES #ifdef CONFIG_KPROBES
EXPORT_SYMBOL_GPL(jprobe_return); EXPORT_SYMBOL_GPL(jprobe_return);
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment