Commit 81336333 authored by Linus Torvalds's avatar Linus Torvalds

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()
parents 5f129721 9eb76d77
......@@ -4,9 +4,13 @@ Description:
/sys/module/MODULENAME
The name of the module that is in the kernel. This
module name will show up either if the module is built
directly into the kernel, or if it is loaded as a
dynamic module.
module name will always show up if the module is loaded as a
dynamic module. If it is built directly into the kernel, it
will only show up if it has a version or at least one
parameter.
Note: The conditions of creation in the built-in case are not
by design and may be removed in the future.
/sys/module/MODULENAME/parameters
This directory contains individual files that are each
......
......@@ -439,7 +439,7 @@ extern struct kernel_param_ops param_ops_string;
extern int param_set_copystring(const char *val, const struct kernel_param *);
extern int param_get_string(char *buffer, const struct kernel_param *kp);
/* for exporting parameters in /sys/parameters */
/* for exporting parameters in /sys/module/.../parameters */
struct module;
......
......@@ -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 @@ static int complete_formation(struct module *mod, struct load_info *info)
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)
......
......@@ -787,7 +787,7 @@ static void __init kernel_add_sysfs_param(const char *name,
}
/*
* param_sysfs_builtin - add contents in /sys/parameters for built-in modules
* param_sysfs_builtin - add sysfs parameters for built-in modules
*
* Add module_parameters to sysfs for "modules" built into the kernel.
*
......
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