forked from Minki/linux
Nothing interesting. Except the most embarrassing bugfix ever. But let's
ignore that. Cheers, Rusty. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJR3NrgAAoJENkgDmzRrbjxaQ0P/RwaKDlmrrFiFD6yYZRQKM1G esv3H5j3jU29Eo5WvY1IEoWbMCK4ObL9DL86CCL/XgYZIhJfTiND+R2W8XBSEXec qwJXb3oMWVMDBBnxknl/pf0RWhwaFwxsQ89Yco6zsGTWQ0kB6+PAaUNOh91MBOYJ UM3nJD79Xqv9X/WcTtPNUmVmmZ7WJFqQ3UYhpTL2WRfRnEO/ku8GwAvLunSFuLBP iI4IjSMM8ssLL10g3Cm7J/pzLTTRctmjEZzIclACUrAgm3V+s1NeARztKZiuCVoz 3Eu0VIp5t2rvifOajj0UF0pdO8Q3XpsMj+lr21gg2rc2VTHKZ3oobEzGX7Ev0lae BH1DdW3ivgyq3cBi56Dh3aZDggF24h+QO6qN92s73l0qYK1t+eAg1qc76lsayclB ozJJD9/xuEqLV3GScbMdqb4AxTc6Y0ks0SWD07PvoQkthH/2tPiLpSvrITdKdCrY 0+RssMuO4StM1e8ALjHqDz+/2k8MS70b0e8JUp0e1WaKzMUKKUYZIqQTGqczHH7u 4hWJiSMnsZqzLLKUX2A6nVlg0eo6zgyqHuxk6O4fHghXWOJJlLjWcMQW26dBS3ki FpWYsJeHw6HcITcbWXkdozygf0GOwiaHaI6ivVnB3L8spc6VFD4gvDpbcpAeixGX BfFA7nG/Hy3aOT05juMj =OVO/ -----END PGP SIGNATURE----- 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:
commit
8133633368
@ -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 @@ 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)
|
||||
|
@ -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.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user