Commit 2390fd2b authored by Brian Gerst's avatar Brian Gerst Committed by Linus Torvalds

[PATCH] Remove in-kernel init_module/cleanup_module stubs

This patch removes the default stubs for init_module and cleanup_module,
and checks for NULL instead.  It changes modpost to only create references
to those functions if they actually exist.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 2bb56b4e
...@@ -89,13 +89,6 @@ static inline int strong_try_module_get(struct module *mod) ...@@ -89,13 +89,6 @@ static inline int strong_try_module_get(struct module *mod)
return try_module_get(mod); return try_module_get(mod);
} }
/* Stub function for modules which don't have an initfn */
int init_module(void)
{
return 0;
}
EXPORT_SYMBOL(init_module);
/* A thread that wants to hold a reference to a module only while it /* A thread that wants to hold a reference to a module only while it
* is running can call ths to safely exit. * is running can call ths to safely exit.
* nfsd and lockd use this. * nfsd and lockd use this.
...@@ -529,12 +522,6 @@ EXPORT_SYMBOL(module_refcount); ...@@ -529,12 +522,6 @@ EXPORT_SYMBOL(module_refcount);
/* This exists whether we can unload or not */ /* This exists whether we can unload or not */
static void free_module(struct module *mod); static void free_module(struct module *mod);
/* Stub function for modules which don't have an exitfn */
void cleanup_module(void)
{
}
EXPORT_SYMBOL(cleanup_module);
static void wait_for_zero_refcount(struct module *mod) static void wait_for_zero_refcount(struct module *mod)
{ {
/* Since we might sleep for some time, drop the semaphore first */ /* Since we might sleep for some time, drop the semaphore first */
...@@ -589,7 +576,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags) ...@@ -589,7 +576,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
} }
/* If it has an init func, it must have an exit func to unload */ /* If it has an init func, it must have an exit func to unload */
if ((mod->init != init_module && mod->exit == cleanup_module) if ((mod->init != NULL && mod->exit == NULL)
|| mod->unsafe) { || mod->unsafe) {
forced = try_force(flags); forced = try_force(flags);
if (!forced) { if (!forced) {
...@@ -610,9 +597,11 @@ sys_delete_module(const char __user *name_user, unsigned int flags) ...@@ -610,9 +597,11 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
wait_for_zero_refcount(mod); wait_for_zero_refcount(mod);
/* Final destruction now noone is using it. */ /* Final destruction now noone is using it. */
if (mod->exit != NULL) {
up(&module_mutex); up(&module_mutex);
mod->exit(); mod->exit();
down(&module_mutex); down(&module_mutex);
}
free_module(mod); free_module(mod);
out: out:
...@@ -639,7 +628,7 @@ static void print_unload_info(struct seq_file *m, struct module *mod) ...@@ -639,7 +628,7 @@ static void print_unload_info(struct seq_file *m, struct module *mod)
seq_printf(m, "[unsafe],"); seq_printf(m, "[unsafe],");
} }
if (mod->init != init_module && mod->exit == cleanup_module) { if (mod->init != NULL && mod->exit == NULL) {
printed_something = 1; printed_something = 1;
seq_printf(m, "[permanent],"); seq_printf(m, "[permanent],");
} }
...@@ -1836,7 +1825,7 @@ sys_init_module(void __user *umod, ...@@ -1836,7 +1825,7 @@ sys_init_module(void __user *umod,
const char __user *uargs) const char __user *uargs)
{ {
struct module *mod; struct module *mod;
int ret; int ret = 0;
/* Must have permission */ /* Must have permission */
if (!capable(CAP_SYS_MODULE)) if (!capable(CAP_SYS_MODULE))
...@@ -1875,6 +1864,7 @@ sys_init_module(void __user *umod, ...@@ -1875,6 +1864,7 @@ sys_init_module(void __user *umod,
up(&notify_mutex); up(&notify_mutex);
/* Start the module */ /* Start the module */
if (mod->init != NULL)
ret = mod->init(); ret = mod->init();
if (ret < 0) { if (ret < 0) {
/* Init routine failed: abort. Try to protect us from /* Init routine failed: abort. Try to protect us from
......
...@@ -376,6 +376,10 @@ handle_modversions(struct module *mod, struct elf_info *info, ...@@ -376,6 +376,10 @@ handle_modversions(struct module *mod, struct elf_info *info,
add_exported_symbol(symname + strlen(KSYMTAB_PFX), add_exported_symbol(symname + strlen(KSYMTAB_PFX),
mod, NULL); mod, NULL);
} }
if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
mod->has_init = 1;
if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0)
mod->has_cleanup = 1;
break; break;
} }
} }
...@@ -410,9 +414,6 @@ read_symbols(char *modname) ...@@ -410,9 +414,6 @@ read_symbols(char *modname)
if (is_vmlinux(modname)) { if (is_vmlinux(modname)) {
unsigned int fake_crc = 0; unsigned int fake_crc = 0;
have_vmlinux = 1; have_vmlinux = 1;
/* May not have this if !CONFIG_MODULE_UNLOAD: fake it.
If it appears, we'll get the real CRC. */
add_exported_symbol("cleanup_module", mod, &fake_crc);
add_exported_symbol("struct_module", mod, &fake_crc); add_exported_symbol("struct_module", mod, &fake_crc);
mod->skip = 1; mod->skip = 1;
} }
...@@ -431,14 +432,8 @@ read_symbols(char *modname) ...@@ -431,14 +432,8 @@ read_symbols(char *modname)
* never passed as an argument to an exported function, so * never passed as an argument to an exported function, so
* the automatic versioning doesn't pick it up, but it's really * the automatic versioning doesn't pick it up, but it's really
* important anyhow */ * important anyhow */
if (modversions) { if (modversions)
mod->unres = alloc_symbol("struct_module", mod->unres); mod->unres = alloc_symbol("struct_module", mod->unres);
/* Always version init_module and cleanup_module, in
* case module doesn't have its own. */
mod->unres = alloc_symbol("init_module", mod->unres);
mod->unres = alloc_symbol("cleanup_module", mod->unres);
}
} }
#define SZ 500 #define SZ 500
...@@ -479,7 +474,7 @@ buf_write(struct buffer *buf, const char *s, int len) ...@@ -479,7 +474,7 @@ buf_write(struct buffer *buf, const char *s, int len)
/* Header for the generated file */ /* Header for the generated file */
void void
add_header(struct buffer *b) add_header(struct buffer *b, struct module *mod)
{ {
buf_printf(b, "#include <linux/module.h>\n"); buf_printf(b, "#include <linux/module.h>\n");
buf_printf(b, "#include <linux/vermagic.h>\n"); buf_printf(b, "#include <linux/vermagic.h>\n");
...@@ -491,10 +486,12 @@ add_header(struct buffer *b) ...@@ -491,10 +486,12 @@ add_header(struct buffer *b)
buf_printf(b, "struct module __this_module\n"); buf_printf(b, "struct module __this_module\n");
buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
buf_printf(b, " .name = __stringify(KBUILD_MODNAME),\n"); buf_printf(b, " .name = __stringify(KBUILD_MODNAME),\n");
if (mod->has_init)
buf_printf(b, " .init = init_module,\n"); buf_printf(b, " .init = init_module,\n");
buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"); if (mod->has_cleanup)
buf_printf(b, " .exit = cleanup_module,\n"); buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
buf_printf(b, "#endif\n"); " .exit = cleanup_module,\n"
"#endif\n");
buf_printf(b, "};\n"); buf_printf(b, "};\n");
} }
...@@ -723,7 +720,7 @@ main(int argc, char **argv) ...@@ -723,7 +720,7 @@ main(int argc, char **argv)
buf.pos = 0; buf.pos = 0;
add_header(&buf); add_header(&buf, mod);
add_versions(&buf, mod); add_versions(&buf, mod);
add_depends(&buf, mod, modules); add_depends(&buf, mod, modules);
add_moddevtable(&buf, mod); add_moddevtable(&buf, mod);
......
...@@ -74,6 +74,8 @@ struct module { ...@@ -74,6 +74,8 @@ struct module {
struct symbol *unres; struct symbol *unres;
int seen; int seen;
int skip; int skip;
int has_init;
int has_cleanup;
struct buffer dev_table_buf; struct buffer dev_table_buf;
}; };
......
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