public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] module interface improvement for kprobes
@ 2006-08-04 15:17 David Smith
  2006-08-04 15:57 ` Christoph Hellwig
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: David Smith @ 2006-08-04 15:17 UTC (permalink / raw)
  To: linux-kernel; +Cc: rusty, prasanna, ananth, anil.s.keshavamurthy, davem

When inserting a kprobes probe into a loadable module, there isn't a way
for the kprobes module to get a module reference (in order to find the
base address of the module among perhaps other things).

A kprobes probe needs the base address of the module in order to
"relocate" the addresses of probe points (since the load address of the
module can change from run to run of the kprobe).

I've added a new function, module_get_byname(), that looks up a module
by name and returns the module reference.  Note that module_get_byname()
also increments the module reference count.  It does this so that the
module won't be unloaded between the time that module_get_byname() is
called and register_kprobe() is called.

Here's an example of how it would be used from a kprobe:

====
static struct module *mod = NULL;

int init_module(void)
{
	/* grab the module, making sure it won't get unloaded until
	 * we're done */
	const char *mod_name = "joydev";
	if (module_get_byname(mod_name, &mod) != 0)
		return 1;

	/* Specify the address/offset where you want to insert
	 * probe.  If this were a real kprobe module, we'd "relocate"
	 * our probe address based on the load address of the module
	 * we're interested in. */
	kp.addr = (kprobe_opcode_t *) mod->module_core + 0;

	/* All set to register with Kprobes */
        register_kprobe(&kp);
	return 0;
}

void cleanup_module(void)
{
	if (kp.addr != NULL)
		unregister_kprobe(&kp);

	/* allow the module to get unloaded, if needed */
	if (mod != NULL)
		module_put(mod);
}
====

I've included a patch that implements the new function. 

Signed-off-by: David Smith <dsmith@redhat.com>
---

diff --git a/include/linux/module.h b/include/linux/module.h
index 0dfb794..7464e29 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -374,6 +374,8 @@ extern void __module_put_and_exit(struct
 	__attribute__((noreturn));
 #define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE,
code);
 
+long module_get_byname(const char *mod_name, struct module **mod);
+
 #ifdef CONFIG_MODULE_UNLOAD
 unsigned int module_refcount(struct module *mod);
 void __symbol_put(const char *symbol);
@@ -549,6 +551,11 @@ static inline int is_exported(const char
 	return 0;
 }
 
+static inline long module_get_byname(const char *mod_name, struct
module **mod)
+{
+	return 1;
+}
+
 static inline int register_module_notifier(struct notifier_block * nb)
 {
 	/* no events will happen anyway, so this can always succeed */
diff --git a/kernel/module.c b/kernel/module.c
index 2a19cd4..30449ce 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -291,7 +291,27 @@ static struct module *find_module(const 
 	}
 	return NULL;
 }
+  
+long module_get_byname(const char *mod_name, struct module **mod)
+{
+	*mod = NULL;
 
+	/* We must hold module_mutex before calling find_module(). */
+	if (mutex_lock_interruptible(&module_mutex) != 0)
+		return -EINTR;
+
+	*mod = find_module(mod_name);
+	mutex_unlock(&module_mutex);
+	if (*mod) {
+		if (! strong_try_module_get(*mod)) {
+			*mod = NULL;
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(module_get_byname);
+ 
 #ifdef CONFIG_SMP
 /* Number of blocks used and allocated. */
 static unsigned int pcpu_num_used, pcpu_num_allocated;



^ permalink raw reply related	[flat|nested] 12+ messages in thread
* Re: [PATCH] module interface improvement for kprobes
@ 2006-08-04 23:00 Chuck Ebbert
  0 siblings, 0 replies; 12+ messages in thread
From: Chuck Ebbert @ 2006-08-04 23:00 UTC (permalink / raw)
  To: David Smith
  Cc: Ananth N Mavinakayanahalli, Prasanna S Panchamukhi, linux-kernel,
	Rusty Russell, Anil S Keshavamurthy, David S. Miller

In-Reply-To: <1154721061.15967.31.camel@dhcp-2.hsv.redhat.com>

On Fri, 04 Aug 2006 14:51:01 -0500, David Smith wrote:

> > > I've added a new function, module_get_byname(), that looks up a module
> > > by name and returns the module reference.  Note that module_get_byname()
> > > also increments the module reference count.  It does this so that the
> > > module won't be unloaded between the time that module_get_byname() is
> > > called and register_kprobe() is called.

Your patch is word-wrapped.

Also:

> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -291,7 +291,27 @@ static struct module *find_module(const 
>       }
>       return NULL;
>  }
> +  
> +int module_get_byname(const char *mod_name, struct module **mod)
> +{
> +     *mod = NULL;
>  
> +     /* We must hold module_mutex before calling find_module(). */
> +     if (mutex_lock_interruptible(&module_mutex) != 0)
> +             return -EINTR;
> +
> +     *mod = find_module(mod_name);
> +     mutex_unlock(&module_mutex);
> +     if (*mod) {
> +             if (!strong_try_module_get(*mod)) {

What keeps the module from going away between the mutex_unlock() and
strong_try_module_get()? It needs to be something like this:

        *mod = find_module(mod_name);
        if (*mod)
                ret = strong_try_module_get(*mod);
        mutex_unlock(&module_mutex);
        if (!ret) {
                *mod = NULL;
                return -EINVAL;
        }

> +                     *mod = NULL;
> +                     return -EINVAL;
> +             }
> +     }
> +     return 0;
> +}
> +EXPORT_SYMBOL_GPL(module_get_byname);
> + 
>  #ifdef CONFIG_SMP
>  /* Number of blocks used and allocated. */
>  static unsigned int pcpu_num_used, pcpu_num_allocated;

-- 
Chuck


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2006-08-08 15:42 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-04 15:17 [PATCH] module interface improvement for kprobes David Smith
2006-08-04 15:57 ` Christoph Hellwig
2006-08-04 18:30   ` David Smith
2006-08-05 11:35     ` Christoph Hellwig
2006-08-05 21:10       ` Frank Ch. Eigler
2006-08-07  4:52   ` Ananth N Mavinakayanahalli
2006-08-07  5:05     ` Ananth N Mavinakayanahalli
2006-08-08 15:39     ` David Smith
2006-08-04 16:00 ` Randy.Dunlap
2006-08-04 19:51   ` David Smith
2006-08-05  2:28 ` Rusty Russell
  -- strict thread matches above, loose matches on Subject: below --
2006-08-04 23:00 Chuck Ebbert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox