Commit 312dcaf9 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'modules-for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux

Pull modules updates from Jessica Yu:
 "Summary of modules changes for the 5.11 merge window:

   - Fix a race condition between systemd/udev and the module loader.

     The module loader was sending a uevent before the module was fully
     initialized (i.e., before its init function has been called). This
     means udev can start processing the module uevent before the module
     has finished initializing, and some udev rules expect that the
     module has initialized already upon receiving the uevent.

     This resulted in some systemd mount units failing if udev processes
     the event faster than the module can finish init. This is fixed by
     delaying the uevent until after the module has called its init
     routine.

   - Make the linker array sections for kernel params and module version
     attributes more robust by switching to use the alignment of the
     type in question.

     Namely, linker section arrays will be constructed using the
     alignment required by the struct (using __alignof__()) as opposed
     to a specific value such as sizeof(void *) or sizeof(long). This is
     less likely to cause breakages should the size of the type ever
     change (Johan Hovold)

   - Fix module state inconsistency by setting it back to GOING when a
     module fails to load and is on its way out (Miroslav Benes)

   - Some comment and code cleanups (Sergey Shtylyov)"

* tag 'modules-for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux:
  module: delay kobject uevent until after module init call
  module: drop semicolon from version macro
  init: use type alignment for kernel parameters
  params: clean up module-param macros
  params: use type alignment for kernel parameters
  params: drop redundant "unused" attributes
  module: simplify version-attribute handling
  module: drop version-attribute alignment
  module: fix comment style
  module: add more 'kernel-doc' comments
  module: fix up 'kernel-doc' comments
  module: only handle errors with the *switch* statement in module_sig_check()
  module: avoid *goto*s in module_sig_check()
  module: merge repetitive strings in module_sig_check()
  module: set MODULE_STATE_GOING state when a module fails to load
parents 6daa9043 38dc717e
...@@ -255,7 +255,7 @@ struct obs_kernel_param { ...@@ -255,7 +255,7 @@ struct obs_kernel_param {
__aligned(1) = str; \ __aligned(1) = str; \
static struct obs_kernel_param __setup_##unique_id \ static struct obs_kernel_param __setup_##unique_id \
__used __section(".init.setup") \ __used __section(".init.setup") \
__attribute__((aligned((sizeof(long))))) \ __aligned(__alignof__(struct obs_kernel_param)) \
= { __setup_str_##unique_id, fn, early } = { __setup_str_##unique_id, fn, early }
#define __setup(str, fn) \ #define __setup(str, fn) \
......
...@@ -66,7 +66,7 @@ struct module_version_attribute { ...@@ -66,7 +66,7 @@ struct module_version_attribute {
struct module_attribute mattr; struct module_attribute mattr;
const char *module_name; const char *module_name;
const char *version; const char *version;
} __attribute__ ((__aligned__(sizeof(void *)))); };
extern ssize_t __modver_version_show(struct module_attribute *, extern ssize_t __modver_version_show(struct module_attribute *,
struct module_kobject *, char *); struct module_kobject *, char *);
...@@ -266,20 +266,20 @@ extern typeof(name) __mod_##type##__##name##_device_table \ ...@@ -266,20 +266,20 @@ extern typeof(name) __mod_##type##__##name##_device_table \
#else #else
#define MODULE_VERSION(_version) \ #define MODULE_VERSION(_version) \
MODULE_INFO(version, _version); \ MODULE_INFO(version, _version); \
static struct module_version_attribute ___modver_attr = { \ static struct module_version_attribute __modver_attr \
.mattr = { \ __used __section("__modver") \
.attr = { \ __aligned(__alignof__(struct module_version_attribute)) \
.name = "version", \ = { \
.mode = S_IRUGO, \ .mattr = { \
.attr = { \
.name = "version", \
.mode = S_IRUGO, \
}, \
.show = __modver_version_show, \
}, \ }, \
.show = __modver_version_show, \ .module_name = KBUILD_MODNAME, \
}, \ .version = _version, \
.module_name = KBUILD_MODNAME, \ }
.version = _version, \
}; \
static const struct module_version_attribute \
__used __section("__modver") \
* __moduleparam_const __modver_attr = &___modver_attr
#endif #endif
/* Optional firmware file (or files) needed by the module /* Optional firmware file (or files) needed by the module
......
...@@ -21,12 +21,12 @@ ...@@ -21,12 +21,12 @@
#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
#define __MODULE_INFO(tag, name, info) \ #define __MODULE_INFO(tag, name, info) \
static const char __UNIQUE_ID(name)[] \ static const char __UNIQUE_ID(name)[] \
__used __section(".modinfo") __attribute__((unused, aligned(1))) \ __used __section(".modinfo") __aligned(1) \
= __MODULE_INFO_PREFIX __stringify(tag) "=" info = __MODULE_INFO_PREFIX __stringify(tag) "=" info
#define __MODULE_PARM_TYPE(name, _type) \ #define __MODULE_PARM_TYPE(name, _type) \
__MODULE_INFO(parmtype, name##type, #name ":" _type) __MODULE_INFO(parmtype, name##type, #name ":" _type)
/* One for each parameter, describing how to use it. Some files do /* One for each parameter, describing how to use it. Some files do
multiple of these per line, so can't just use MODULE_INFO. */ multiple of these per line, so can't just use MODULE_INFO. */
...@@ -288,8 +288,8 @@ struct kparam_array ...@@ -288,8 +288,8 @@ struct kparam_array
/* Default value instead of permissions? */ \ /* Default value instead of permissions? */ \
static const char __param_str_##name[] = prefix #name; \ static const char __param_str_##name[] = prefix #name; \
static struct kernel_param __moduleparam_const __param_##name \ static struct kernel_param __moduleparam_const __param_##name \
__used \ __used __section("__param") \
__section("__param") __attribute__ ((unused, aligned(sizeof(void *)))) \ __aligned(__alignof__(struct kernel_param)) \
= { __param_str_##name, THIS_MODULE, ops, \ = { __param_str_##name, THIS_MODULE, ops, \
VERIFY_OCTAL_PERMISSIONS(perm), level, flags, { arg } } VERIFY_OCTAL_PERMISSIONS(perm), level, flags, { arg } }
......
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
/* /*
Copyright (C) 2002 Richard Henderson * Copyright (C) 2002 Richard Henderson
Copyright (C) 2001 Rusty Russell, 2002, 2010 Rusty Russell IBM. * Copyright (C) 2001 Rusty Russell, 2002, 2010 Rusty Russell IBM.
*/
*/
#define INCLUDE_VERMAGIC #define INCLUDE_VERMAGIC
...@@ -86,7 +85,8 @@ ...@@ -86,7 +85,8 @@
* 1) List of modules (also safely readable with preempt_disable), * 1) List of modules (also safely readable with preempt_disable),
* 2) module_use links, * 2) module_use links,
* 3) module_addr_min/module_addr_max. * 3) module_addr_min/module_addr_max.
* (delete and add uses RCU list operations). */ * (delete and add uses RCU list operations).
*/
DEFINE_MUTEX(module_mutex); DEFINE_MUTEX(module_mutex);
EXPORT_SYMBOL_GPL(module_mutex); EXPORT_SYMBOL_GPL(module_mutex);
static LIST_HEAD(modules); static LIST_HEAD(modules);
...@@ -615,8 +615,10 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms, ...@@ -615,8 +615,10 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms,
return false; return false;
} }
/* Find an exported symbol and return it, along with, (optional) crc and /*
* (optional) module which owns it. Needs preempt disabled or module_mutex. */ * Find an exported symbol and return it, along with, (optional) crc and
* (optional) module which owns it. Needs preempt disabled or module_mutex.
*/
static const struct kernel_symbol *find_symbol(const char *name, static const struct kernel_symbol *find_symbol(const char *name,
struct module **owner, struct module **owner,
const s32 **crc, const s32 **crc,
...@@ -756,13 +758,12 @@ bool __is_module_percpu_address(unsigned long addr, unsigned long *can_addr) ...@@ -756,13 +758,12 @@ bool __is_module_percpu_address(unsigned long addr, unsigned long *can_addr)
} }
/** /**
* is_module_percpu_address - test whether address is from module static percpu * is_module_percpu_address() - test whether address is from module static percpu
* @addr: address to test * @addr: address to test
* *
* Test whether @addr belongs to module static percpu area. * Test whether @addr belongs to module static percpu area.
* *
* RETURNS: * Return: %true if @addr is from module static percpu area
* %true if @addr is from module static percpu area
*/ */
bool is_module_percpu_address(unsigned long addr) bool is_module_percpu_address(unsigned long addr)
{ {
...@@ -986,11 +987,10 @@ static int try_stop_module(struct module *mod, int flags, int *forced) ...@@ -986,11 +987,10 @@ static int try_stop_module(struct module *mod, int flags, int *forced)
} }
/** /**
* module_refcount - return the refcount or -1 if unloading * module_refcount() - return the refcount or -1 if unloading
*
* @mod: the module we're checking * @mod: the module we're checking
* *
* Returns: * Return:
* -1 if the module is in the process of unloading * -1 if the module is in the process of unloading
* otherwise the number of references in the kernel to the module * otherwise the number of references in the kernel to the module
*/ */
...@@ -1675,8 +1675,10 @@ static void remove_sect_attrs(struct module *mod) ...@@ -1675,8 +1675,10 @@ static void remove_sect_attrs(struct module *mod)
if (mod->sect_attrs) { if (mod->sect_attrs) {
sysfs_remove_group(&mod->mkobj.kobj, sysfs_remove_group(&mod->mkobj.kobj,
&mod->sect_attrs->grp); &mod->sect_attrs->grp);
/* We are positive that no one is using any sect attrs /*
* at this point. Deallocate immediately. */ * We are positive that no one is using any sect attrs
* at this point. Deallocate immediately.
*/
free_sect_attrs(mod->sect_attrs); free_sect_attrs(mod->sect_attrs);
mod->sect_attrs = NULL; mod->sect_attrs = NULL;
} }
...@@ -1924,7 +1926,6 @@ static int mod_sysfs_init(struct module *mod) ...@@ -1924,7 +1926,6 @@ static int mod_sysfs_init(struct module *mod)
if (err) if (err)
mod_kobject_put(mod); mod_kobject_put(mod);
/* delay uevent until full sysfs population */
out: out:
return err; return err;
} }
...@@ -1961,7 +1962,6 @@ static int mod_sysfs_setup(struct module *mod, ...@@ -1961,7 +1962,6 @@ static int mod_sysfs_setup(struct module *mod,
add_sect_attrs(mod, info); add_sect_attrs(mod, info);
add_notes_attrs(mod, info); add_notes_attrs(mod, info);
kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD);
return 0; return 0;
out_unreg_modinfo_attrs: out_unreg_modinfo_attrs:
...@@ -2247,8 +2247,10 @@ static void free_module(struct module *mod) ...@@ -2247,8 +2247,10 @@ static void free_module(struct module *mod)
mod_sysfs_teardown(mod); mod_sysfs_teardown(mod);
/* We leave it in list to prevent duplicate loads, but make sure /*
* that noone uses it while it's being deconstructed. */ * We leave it in list to prevent duplicate loads, but make sure
* that noone uses it while it's being deconstructed.
*/
mutex_lock(&module_mutex); mutex_lock(&module_mutex);
mod->state = MODULE_STATE_UNFORMED; mod->state = MODULE_STATE_UNFORMED;
mutex_unlock(&module_mutex); mutex_unlock(&module_mutex);
...@@ -2365,8 +2367,10 @@ static int simplify_symbols(struct module *mod, const struct load_info *info) ...@@ -2365,8 +2367,10 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
if (!strncmp(name, "__gnu_lto", 9)) if (!strncmp(name, "__gnu_lto", 9))
break; break;
/* We compiled with -fno-common. These are not /*
supposed to happen. */ * We compiled with -fno-common. These are not
* supposed to happen.
*/
pr_debug("Common symbol: %s\n", name); pr_debug("Common symbol: %s\n", name);
pr_warn("%s: please compile with -fno-common\n", pr_warn("%s: please compile with -fno-common\n",
mod->name); mod->name);
...@@ -2469,16 +2473,20 @@ static long get_offset(struct module *mod, unsigned int *size, ...@@ -2469,16 +2473,20 @@ static long get_offset(struct module *mod, unsigned int *size,
return ret; return ret;
} }
/* Lay out the SHF_ALLOC sections in a way not dissimilar to how ld /*
might -- code, read-only data, read-write data, small data. Tally * Lay out the SHF_ALLOC sections in a way not dissimilar to how ld
sizes, and place the offsets into sh_entsize fields: high bit means it * might -- code, read-only data, read-write data, small data. Tally
belongs in init. */ * sizes, and place the offsets into sh_entsize fields: high bit means it
* belongs in init.
*/
static void layout_sections(struct module *mod, struct load_info *info) static void layout_sections(struct module *mod, struct load_info *info)
{ {
static unsigned long const masks[][2] = { static unsigned long const masks[][2] = {
/* NOTE: all executable code must be the first section /*
* NOTE: all executable code must be the first section
* in this array; otherwise modify the text_size * in this array; otherwise modify the text_size
* finder in the two loops below */ * finder in the two loops below
*/
{ SHF_EXECINSTR | SHF_ALLOC, ARCH_SHF_SMALL }, { SHF_EXECINSTR | SHF_ALLOC, ARCH_SHF_SMALL },
{ SHF_ALLOC, SHF_WRITE | ARCH_SHF_SMALL }, { SHF_ALLOC, SHF_WRITE | ARCH_SHF_SMALL },
{ SHF_RO_AFTER_INIT | SHF_ALLOC, ARCH_SHF_SMALL }, { SHF_RO_AFTER_INIT | SHF_ALLOC, ARCH_SHF_SMALL },
...@@ -2924,40 +2932,43 @@ static int module_sig_check(struct load_info *info, int flags) ...@@ -2924,40 +2932,43 @@ static int module_sig_check(struct load_info *info, int flags)
/* We truncate the module to discard the signature */ /* We truncate the module to discard the signature */
info->len -= markerlen; info->len -= markerlen;
err = mod_verify_sig(mod, info); err = mod_verify_sig(mod, info);
if (!err) {
info->sig_ok = true;
return 0;
}
} }
/*
* We don't permit modules to be loaded into the trusted kernels
* without a valid signature on them, but if we're not enforcing,
* certain errors are non-fatal.
*/
switch (err) { switch (err) {
case 0:
info->sig_ok = true;
return 0;
/* We don't permit modules to be loaded into trusted kernels
* without a valid signature on them, but if we're not
* enforcing, certain errors are non-fatal.
*/
case -ENODATA: case -ENODATA:
reason = "Loading of unsigned module"; reason = "unsigned module";
goto decide; break;
case -ENOPKG: case -ENOPKG:
reason = "Loading of module with unsupported crypto"; reason = "module with unsupported crypto";
goto decide; break;
case -ENOKEY: case -ENOKEY:
reason = "Loading of module with unavailable key"; reason = "module with unavailable key";
decide: break;
if (is_module_sig_enforced()) {
pr_notice("%s: %s is rejected\n", info->name, reason);
return -EKEYREJECTED;
}
return security_locked_down(LOCKDOWN_MODULE_SIGNATURE);
/* All other errors are fatal, including nomem, unparseable
* signatures and signature check failures - even if signatures
* aren't required.
*/
default: default:
/*
* All other errors are fatal, including lack of memory,
* unparseable signatures, and signature check failures --
* even if signatures aren't required.
*/
return err; return err;
} }
if (is_module_sig_enforced()) {
pr_notice("%s: loading of %s is rejected\n", info->name, reason);
return -EKEYREJECTED;
}
return security_locked_down(LOCKDOWN_MODULE_SIGNATURE);
} }
#else /* !CONFIG_MODULE_SIG */ #else /* !CONFIG_MODULE_SIG */
static int module_sig_check(struct load_info *info, int flags) static int module_sig_check(struct load_info *info, int flags)
...@@ -3090,8 +3101,10 @@ static int rewrite_section_headers(struct load_info *info, int flags) ...@@ -3090,8 +3101,10 @@ static int rewrite_section_headers(struct load_info *info, int flags)
return -ENOEXEC; return -ENOEXEC;
} }
/* Mark all sections sh_addr with their address in the /*
temporary image. */ * Mark all sections sh_addr with their address in the
* temporary image.
*/
shdr->sh_addr = (size_t)info->hdr + shdr->sh_offset; shdr->sh_addr = (size_t)info->hdr + shdr->sh_offset;
#ifndef CONFIG_MODULE_UNLOAD #ifndef CONFIG_MODULE_UNLOAD
...@@ -3525,9 +3538,11 @@ static struct module *layout_and_allocate(struct load_info *info, int flags) ...@@ -3525,9 +3538,11 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
if (ndx) if (ndx)
info->sechdrs[ndx].sh_flags |= SHF_RO_AFTER_INIT; info->sechdrs[ndx].sh_flags |= SHF_RO_AFTER_INIT;
/* Determine total sizes, and put offsets in sh_entsize. For now /*
this is done generically; there doesn't appear to be any * Determine total sizes, and put offsets in sh_entsize. For now
special cases for the architectures. */ * this is done generically; there doesn't appear to be any
* special cases for the architectures.
*/
layout_sections(info->mod, info); layout_sections(info->mod, info);
layout_symtab(info->mod, info); layout_symtab(info->mod, info);
...@@ -3671,6 +3686,9 @@ static noinline int do_init_module(struct module *mod) ...@@ -3671,6 +3686,9 @@ static noinline int do_init_module(struct module *mod)
blocking_notifier_call_chain(&module_notify_list, blocking_notifier_call_chain(&module_notify_list,
MODULE_STATE_LIVE, mod); MODULE_STATE_LIVE, mod);
/* Delay uevent until module has finished its init routine */
kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD);
/* /*
* We need to finish all async code before the module init sequence * We need to finish all async code before the module init sequence
* is done. This has potential to deadlock. For example, a newly * is done. This has potential to deadlock. For example, a newly
...@@ -3815,8 +3833,10 @@ static int complete_formation(struct module *mod, struct load_info *info) ...@@ -3815,8 +3833,10 @@ static int complete_formation(struct module *mod, struct load_info *info)
module_enable_nx(mod); module_enable_nx(mod);
module_enable_x(mod); module_enable_x(mod);
/* Mark state as coming so strong_try_module_get() ignores us, /*
* but kallsyms etc. can see us. */ * Mark state as coming so strong_try_module_get() ignores us,
* but kallsyms etc. can see us.
*/
mod->state = MODULE_STATE_COMING; mod->state = MODULE_STATE_COMING;
mutex_unlock(&module_mutex); mutex_unlock(&module_mutex);
...@@ -3863,8 +3883,10 @@ static int unknown_module_param_cb(char *param, char *val, const char *modname, ...@@ -3863,8 +3883,10 @@ static int unknown_module_param_cb(char *param, char *val, const char *modname,
return 0; return 0;
} }
/* Allocate and load the module: note that size of section 0 is always /*
zero, and we rely on this for optional sections. */ * 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, static int load_module(struct load_info *info, const char __user *uargs,
int flags) int flags)
{ {
...@@ -3938,8 +3960,10 @@ static int load_module(struct load_info *info, const char __user *uargs, ...@@ -3938,8 +3960,10 @@ static int load_module(struct load_info *info, const char __user *uargs,
init_param_lock(mod); init_param_lock(mod);
/* Now we've got everything in the final locations, we can /*
* find optional sections. */ * Now we've got everything in the final locations, we can
* find optional sections.
*/
err = find_module_sections(mod, info); err = find_module_sections(mod, info);
if (err) if (err)
goto free_unload; goto free_unload;
...@@ -4027,6 +4051,7 @@ static int load_module(struct load_info *info, const char __user *uargs, ...@@ -4027,6 +4051,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
MODULE_STATE_GOING, mod); MODULE_STATE_GOING, mod);
klp_module_going(mod); klp_module_going(mod);
bug_cleanup: bug_cleanup:
mod->state = MODULE_STATE_GOING;
/* module_bug_cleanup needs module_mutex protection */ /* module_bug_cleanup needs module_mutex protection */
mutex_lock(&module_mutex); mutex_lock(&module_mutex);
module_bug_cleanup(mod); module_bug_cleanup(mod);
...@@ -4152,8 +4177,10 @@ static const char *find_kallsyms_symbol(struct module *mod, ...@@ -4152,8 +4177,10 @@ static const char *find_kallsyms_symbol(struct module *mod,
bestval = kallsyms_symbol_value(&kallsyms->symtab[best]); bestval = kallsyms_symbol_value(&kallsyms->symtab[best]);
/* Scan for closest preceding symbol, and next symbol. (ELF /*
starts real symbols at 1). */ * Scan for closest preceding symbol, and next symbol. (ELF
* starts real symbols at 1).
*/
for (i = 1; i < kallsyms->num_symtab; i++) { for (i = 1; i < kallsyms->num_symtab; i++) {
const Elf_Sym *sym = &kallsyms->symtab[i]; const Elf_Sym *sym = &kallsyms->symtab[i];
unsigned long thisval = kallsyms_symbol_value(sym); unsigned long thisval = kallsyms_symbol_value(sym);
...@@ -4161,8 +4188,10 @@ static const char *find_kallsyms_symbol(struct module *mod, ...@@ -4161,8 +4188,10 @@ static const char *find_kallsyms_symbol(struct module *mod,
if (sym->st_shndx == SHN_UNDEF) if (sym->st_shndx == SHN_UNDEF)
continue; continue;
/* We ignore unnamed symbols: they're uninformative /*
* and inserted at a whim. */ * We ignore unnamed symbols: they're uninformative
* and inserted at a whim.
*/
if (*kallsyms_symbol_name(kallsyms, i) == '\0' if (*kallsyms_symbol_name(kallsyms, i) == '\0'
|| is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i))) || is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i)))
continue; continue;
...@@ -4192,8 +4221,10 @@ void * __weak dereference_module_function_descriptor(struct module *mod, ...@@ -4192,8 +4221,10 @@ void * __weak dereference_module_function_descriptor(struct module *mod,
return ptr; return ptr;
} }
/* For kallsyms to ask for address resolution. NULL means not found. Careful /*
* not to lock to avoid deadlock on oopses, simply disable preemption. */ * For kallsyms to ask for address resolution. NULL means not found. Careful
* not to lock to avoid deadlock on oopses, simply disable preemption.
*/
const char *module_address_lookup(unsigned long addr, const char *module_address_lookup(unsigned long addr,
unsigned long *size, unsigned long *size,
unsigned long *offset, unsigned long *offset,
...@@ -4451,11 +4482,12 @@ static int m_show(struct seq_file *m, void *p) ...@@ -4451,11 +4482,12 @@ static int m_show(struct seq_file *m, void *p)
return 0; return 0;
} }
/* Format: modulename size refcount deps address /*
* Format: modulename size refcount deps address
Where refcount is a number or -, and deps is a comma-separated list *
of depends or -. * Where refcount is a number or -, and deps is a comma-separated list
*/ * of depends or -.
*/
static const struct seq_operations modules_op = { static const struct seq_operations modules_op = {
.start = m_start, .start = m_start,
.next = m_next, .next = m_next,
...@@ -4525,8 +4557,8 @@ const struct exception_table_entry *search_module_extables(unsigned long addr) ...@@ -4525,8 +4557,8 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
return e; return e;
} }
/* /**
* is_module_address - is this address inside a module? * is_module_address() - is this address inside a module?
* @addr: the address to check. * @addr: the address to check.
* *
* See is_module_text_address() if you simply want to see if the address * See is_module_text_address() if you simply want to see if the address
...@@ -4543,8 +4575,8 @@ bool is_module_address(unsigned long addr) ...@@ -4543,8 +4575,8 @@ bool is_module_address(unsigned long addr)
return ret; return ret;
} }
/* /**
* __module_address - get the module which contains an address. * __module_address() - get the module which contains an address.
* @addr: the address. * @addr: the address.
* *
* Must be called with preempt disabled or module mutex held so that * Must be called with preempt disabled or module mutex held so that
...@@ -4568,8 +4600,8 @@ struct module *__module_address(unsigned long addr) ...@@ -4568,8 +4600,8 @@ struct module *__module_address(unsigned long addr)
return mod; return mod;
} }
/* /**
* is_module_text_address - is this address inside module code? * is_module_text_address() - is this address inside module code?
* @addr: the address to check. * @addr: the address to check.
* *
* See is_module_address() if you simply want to see if the address is * See is_module_address() if you simply want to see if the address is
...@@ -4587,8 +4619,8 @@ bool is_module_text_address(unsigned long addr) ...@@ -4587,8 +4619,8 @@ bool is_module_text_address(unsigned long addr)
return ret; return ret;
} }
/* /**
* __module_text_address - get the module whose code contains an address. * __module_text_address() - get the module whose code contains an address.
* @addr: the address. * @addr: the address.
* *
* Must be called with preempt disabled or module mutex held so that * Must be called with preempt disabled or module mutex held so that
...@@ -4627,8 +4659,10 @@ void print_modules(void) ...@@ -4627,8 +4659,10 @@ void print_modules(void)
} }
#ifdef CONFIG_MODVERSIONS #ifdef CONFIG_MODVERSIONS
/* Generate the signature for all relevant module structures here. /*
* If these change, we don't want to try to parse the module. */ * Generate the signature for all relevant module structures here.
* If these change, we don't want to try to parse the module.
*/
void module_layout(struct module *mod, void module_layout(struct module *mod,
struct modversion_info *ver, struct modversion_info *ver,
struct kernel_param *kp, struct kernel_param *kp,
......
...@@ -843,18 +843,16 @@ ssize_t __modver_version_show(struct module_attribute *mattr, ...@@ -843,18 +843,16 @@ ssize_t __modver_version_show(struct module_attribute *mattr,
return scnprintf(buf, PAGE_SIZE, "%s\n", vattr->version); return scnprintf(buf, PAGE_SIZE, "%s\n", vattr->version);
} }
extern const struct module_version_attribute *__start___modver[]; extern const struct module_version_attribute __start___modver[];
extern const struct module_version_attribute *__stop___modver[]; extern const struct module_version_attribute __stop___modver[];
static void __init version_sysfs_builtin(void) static void __init version_sysfs_builtin(void)
{ {
const struct module_version_attribute **p; const struct module_version_attribute *vattr;
struct module_kobject *mk; struct module_kobject *mk;
int err; int err;
for (p = __start___modver; p < __stop___modver; p++) { for (vattr = __start___modver; vattr < __stop___modver; vattr++) {
const struct module_version_attribute *vattr = *p;
mk = locate_module_kobject(vattr->module_name); mk = locate_module_kobject(vattr->module_name);
if (mk) { if (mk) {
err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr); err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr);
......
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