Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux

Pull module updates from Rusty Russell:
 "Nothing interesting.  Except the most embarrassing bugfix ever.  But
  let's ignore that"

* tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
  module: cleanup call chain.
  module: do percpu allocation after uniqueness check.  No, really!
  modules: don't fail to load on unknown parameters.
  ABI: Clarify when /sys/module/MODULENAME is created
  There is no /sys/parameters
  module: don't modify argument of module_kallsyms_lookup_name()
This commit is contained in:
Linus Torvalds
2013-07-10 14:51:41 -07:00
4 changed files with 52 additions and 39 deletions

View File

@@ -455,7 +455,7 @@ const struct kernel_symbol *find_symbol(const char *name,
EXPORT_SYMBOL_GPL(find_symbol);
/* Search for module by name: must hold module_mutex. */
static struct module *find_module_all(const char *name,
static struct module *find_module_all(const char *name, size_t len,
bool even_unformed)
{
struct module *mod;
@@ -463,7 +463,7 @@ static struct module *find_module_all(const char *name,
list_for_each_entry(mod, &modules, list) {
if (!even_unformed && mod->state == MODULE_STATE_UNFORMED)
continue;
if (strcmp(mod->name, name) == 0)
if (strlen(mod->name) == len && !memcmp(mod->name, name, len))
return mod;
}
return NULL;
@@ -471,7 +471,7 @@ static struct module *find_module_all(const char *name,
struct module *find_module(const char *name)
{
return find_module_all(name, false);
return find_module_all(name, strlen(name), false);
}
EXPORT_SYMBOL_GPL(find_module);
@@ -482,23 +482,28 @@ static inline void __percpu *mod_percpu(struct module *mod)
return mod->percpu;
}
static int percpu_modalloc(struct module *mod,
unsigned long size, unsigned long align)
static int percpu_modalloc(struct module *mod, struct load_info *info)
{
Elf_Shdr *pcpusec = &info->sechdrs[info->index.pcpu];
unsigned long align = pcpusec->sh_addralign;
if (!pcpusec->sh_size)
return 0;
if (align > PAGE_SIZE) {
printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
mod->name, align, PAGE_SIZE);
align = PAGE_SIZE;
}
mod->percpu = __alloc_reserved_percpu(size, align);
mod->percpu = __alloc_reserved_percpu(pcpusec->sh_size, align);
if (!mod->percpu) {
printk(KERN_WARNING
"%s: Could not allocate %lu bytes percpu data\n",
mod->name, size);
mod->name, (unsigned long)pcpusec->sh_size);
return -ENOMEM;
}
mod->percpu_size = size;
mod->percpu_size = pcpusec->sh_size;
return 0;
}
@@ -563,10 +568,12 @@ static inline void __percpu *mod_percpu(struct module *mod)
{
return NULL;
}
static inline int percpu_modalloc(struct module *mod,
unsigned long size, unsigned long align)
static int percpu_modalloc(struct module *mod, struct load_info *info)
{
return -ENOMEM;
/* UP modules shouldn't have this section: ENOMEM isn't quite right */
if (info->sechdrs[info->index.pcpu].sh_size != 0)
return -ENOMEM;
return 0;
}
static inline void percpu_modfree(struct module *mod)
{
@@ -2927,7 +2934,6 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
{
/* Module within temporary copy. */
struct module *mod;
Elf_Shdr *pcpusec;
int err;
mod = setup_load_info(info, flags);
@@ -2942,17 +2948,10 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
err = module_frob_arch_sections(info->hdr, info->sechdrs,
info->secstrings, mod);
if (err < 0)
goto out;
return ERR_PTR(err);
pcpusec = &info->sechdrs[info->index.pcpu];
if (pcpusec->sh_size) {
/* We have a special allocation for this section. */
err = percpu_modalloc(mod,
pcpusec->sh_size, pcpusec->sh_addralign);
if (err)
goto out;
pcpusec->sh_flags &= ~(unsigned long)SHF_ALLOC;
}
/* We will do a special allocation for per-cpu sections later. */
info->sechdrs[info->index.pcpu].sh_flags &= ~(unsigned long)SHF_ALLOC;
/* Determine total sizes, and put offsets in sh_entsize. For now
this is done generically; there doesn't appear to be any
@@ -2963,17 +2962,12 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
/* Allocate and move to the final place */
err = move_module(mod, info);
if (err)
goto free_percpu;
return ERR_PTR(err);
/* Module has been copied to its final place now: return it. */
mod = (void *)info->sechdrs[info->index.mod].sh_addr;
kmemleak_load_module(mod, info);
return mod;
free_percpu:
percpu_modfree(mod);
out:
return ERR_PTR(err);
}
/* mod is no longer valid after this! */
@@ -3014,7 +3008,7 @@ static bool finished_loading(const char *name)
bool ret;
mutex_lock(&module_mutex);
mod = find_module_all(name, true);
mod = find_module_all(name, strlen(name), true);
ret = !mod || mod->state == MODULE_STATE_LIVE
|| mod->state == MODULE_STATE_GOING;
mutex_unlock(&module_mutex);
@@ -3152,7 +3146,8 @@ static int add_unformed_module(struct module *mod)
again:
mutex_lock(&module_mutex);
if ((old = find_module_all(mod->name, true)) != NULL) {
old = find_module_all(mod->name, strlen(mod->name), true);
if (old != NULL) {
if (old->state == MODULE_STATE_COMING
|| old->state == MODULE_STATE_UNFORMED) {
/* Wait in case it fails to load. */
@@ -3198,6 +3193,17 @@ out:
return err;
}
static int unknown_module_param_cb(char *param, char *val, const char *modname)
{
/* Check for magic 'dyndbg' arg */
int ret = ddebug_dyndbg_module_param_cb(param, val, modname);
if (ret != 0) {
printk(KERN_WARNING "%s: unknown parameter '%s' ignored\n",
modname, param);
}
return 0;
}
/* Allocate and load the module: note that size of section 0 is always
zero, and we rely on this for optional sections. */
static int load_module(struct load_info *info, const char __user *uargs,
@@ -3237,6 +3243,11 @@ static int load_module(struct load_info *info, const char __user *uargs,
}
#endif
/* To avoid stressing percpu allocator, do this once we're unique. */
err = percpu_modalloc(mod, info);
if (err)
goto unlink_mod;
/* Now module is in final location, initialize linked lists, etc. */
err = module_unload_init(mod);
if (err)
@@ -3284,7 +3295,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
/* Module is ready to execute: parsing args may do that. */
err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
-32768, 32767, &ddebug_dyndbg_module_param_cb);
-32768, 32767, unknown_module_param_cb);
if (err < 0)
goto bug_cleanup;
@@ -3563,10 +3574,8 @@ unsigned long module_kallsyms_lookup_name(const char *name)
/* Don't lock: we're in enough trouble already. */
preempt_disable();
if ((colon = strchr(name, ':')) != NULL) {
*colon = '\0';
if ((mod = find_module(name)) != NULL)
if ((mod = find_module_all(name, colon - name, false)) != NULL)
ret = mod_find_symname(mod, colon+1);
*colon = ':';
} else {
list_for_each_entry_rcu(mod, &modules, list) {
if (mod->state == MODULE_STATE_UNFORMED)