@@ -320,6 +320,7 @@ enum module_state {
MODULE_STATE_COMING, /* Full formed, running module_init. */
MODULE_STATE_GOING, /* Going away. */
MODULE_STATE_UNFORMED, /* Still setting it up. */
+ MODULE_STATE_GONE, /* Deconstructing and freeing. */
};
struct mod_tree_node {
@@ -620,6 +621,11 @@ static inline bool module_is_coming(struct module *mod)
return mod->state == MODULE_STATE_COMING;
}
+static inline bool module_is_formed(struct module *mod)
+{
+ return mod->state < MODULE_STATE_UNFORMED;
+}
+
struct module *__module_text_address(unsigned long addr);
struct module *__module_address(unsigned long addr);
bool is_module_address(unsigned long addr);
@@ -361,7 +361,7 @@ int lookup_module_symbol_name(unsigned long addr, char *symname)
preempt_disable();
list_for_each_entry_rcu(mod, &modules, list) {
- if (mod->state == MODULE_STATE_UNFORMED)
+ if (!module_is_formed(mod))
continue;
if (within_module(addr, mod)) {
const char *sym;
@@ -389,7 +389,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
list_for_each_entry_rcu(mod, &modules, list) {
struct mod_kallsyms *kallsyms;
- if (mod->state == MODULE_STATE_UNFORMED)
+ if (!module_is_formed(mod))
continue;
kallsyms = rcu_dereference_sched(mod->kallsyms);
if (symnum < kallsyms->num_symtab) {
@@ -441,7 +441,7 @@ static unsigned long __module_kallsyms_lookup_name(const char *name)
list_for_each_entry_rcu(mod, &modules, list) {
unsigned long ret;
- if (mod->state == MODULE_STATE_UNFORMED)
+ if (!module_is_formed(mod))
continue;
ret = __find_kallsyms_symbol_value(mod, name);
if (ret)
@@ -484,7 +484,7 @@ int module_kallsyms_on_each_symbol(const char *modname,
list_for_each_entry(mod, &modules, list) {
struct mod_kallsyms *kallsyms;
- if (mod->state == MODULE_STATE_UNFORMED)
+ if (!module_is_formed(mod))
continue;
if (modname && strcmp(modname, mod->name))
@@ -23,7 +23,7 @@ int kdb_lsmod(int argc, const char **argv)
kdb_printf("Module Size modstruct Used by\n");
list_for_each_entry(mod, &modules, list) {
- if (mod->state == MODULE_STATE_UNFORMED)
+ if (!module_is_formed(mod))
continue;
kdb_printf("%-20s%8u", mod->name, mod->mem[MOD_TEXT].size);
@@ -153,7 +153,7 @@ EXPORT_SYMBOL(unregister_module_notifier);
*/
static inline int strong_try_module_get(struct module *mod)
{
- BUG_ON(mod && mod->state == MODULE_STATE_UNFORMED);
+ BUG_ON(mod && !module_is_formed(mod));
if (mod && mod->state == MODULE_STATE_COMING)
return -EBUSY;
if (try_module_get(mod))
@@ -361,7 +361,7 @@ bool find_symbol(struct find_symbol_arg *fsa)
GPL_ONLY },
};
- if (mod->state == MODULE_STATE_UNFORMED)
+ if (!module_is_formed(mod))
continue;
for (i = 0; i < ARRAY_SIZE(arr); i++)
@@ -386,7 +386,7 @@ struct module *find_module_all(const char *name, size_t len,
list_for_each_entry_rcu(mod, &modules, list,
lockdep_is_held(&module_mutex)) {
- if (!even_unformed && mod->state == MODULE_STATE_UNFORMED)
+ if (!even_unformed && !module_is_formed(mod))
continue;
if (strlen(mod->name) == len && !memcmp(mod->name, name, len))
return mod;
@@ -457,7 +457,7 @@ bool __is_module_percpu_address(unsigned long addr, unsigned long *can_addr)
preempt_disable();
list_for_each_entry_rcu(mod, &modules, list) {
- if (mod->state == MODULE_STATE_UNFORMED)
+ if (!module_is_formed(mod))
continue;
if (!mod->percpu_size)
continue;
@@ -1326,7 +1326,7 @@ static void free_module(struct module *mod)
* that noone uses it while it's being deconstructed.
*/
mutex_lock(&module_mutex);
- mod->state = MODULE_STATE_UNFORMED;
+ mod->state = MODULE_STATE_GONE;
mutex_unlock(&module_mutex);
/* Arch-specific cleanup. */
@@ -3048,8 +3048,7 @@ static int module_patient_check_exists(const char *name,
if (old == NULL)
return 0;
- if (old->state == MODULE_STATE_COMING ||
- old->state == MODULE_STATE_UNFORMED) {
+ if (old->state == MODULE_STATE_COMING || !module_is_formed(old)) {
/* Wait in case it fails to load. */
mutex_unlock(&module_mutex);
err = wait_event_interruptible(module_wq,
@@ -3608,7 +3607,7 @@ char *module_flags(struct module *mod, char *buf, bool show_state)
{
int bx = 0;
- BUG_ON(mod->state == MODULE_STATE_UNFORMED);
+ BUG_ON(!module_is_formed(mod));
if (!mod->taints && !show_state)
goto out;
if (mod->taints ||
@@ -3702,7 +3701,7 @@ struct module *__module_address(unsigned long addr)
mod = mod_find(addr, &mod_tree);
if (mod) {
BUG_ON(!within_module(addr, mod));
- if (mod->state == MODULE_STATE_UNFORMED)
+ if (!module_is_formed(mod))
mod = NULL;
}
return mod;
@@ -3756,7 +3755,7 @@ void print_modules(void)
/* Most callers should already have preempt disabled, but make sure */
preempt_disable();
list_for_each_entry_rcu(mod, &modules, list) {
- if (mod->state == MODULE_STATE_UNFORMED)
+ if (!module_is_formed(mod))
continue;
pr_cont(" %s%s", mod->name, module_flags(mod, buf, true));
}
@@ -79,7 +79,7 @@ static int m_show(struct seq_file *m, void *p)
unsigned int size;
/* We always ignore unformed modules. */
- if (mod->state == MODULE_STATE_UNFORMED)
+ if (!module_is_formed(mod))
return 0;
size = module_total_size(mod);
@@ -668,6 +668,8 @@ static int tracepoint_module_notify(struct notifier_block *self,
break;
case MODULE_STATE_UNFORMED:
break;
+ case MODULE_STATE_GONE:
+ break;
}
return notifier_from_errno(ret);
}
@@ -836,6 +836,8 @@ static int kunit_module_notify(struct notifier_block *nb, unsigned long val,
break;
case MODULE_STATE_UNFORMED:
break;
+ case MODULE_STATE_GONE:
+ break;
}
return 0;
@@ -93,6 +93,7 @@ static const char *const module_state[] = {
[MODULE_STATE_COMING] = "[MODULE_STATE_COMING] Full formed, running module_init",
[MODULE_STATE_GOING] = "[MODULE_STATE_GOING] Going away",
[MODULE_STATE_UNFORMED] = "[MODULE_STATE_UNFORMED] Still setting it up",
+ [MODULE_STATE_GONE] = "[MODULE_STATE_GONE] Deconstructing and freeing",
};
static void callback_info(const char *callback, struct klp_object *obj)
@@ -16,6 +16,7 @@ static const char *const module_state[] = {
[MODULE_STATE_COMING] = "[MODULE_STATE_COMING] Full formed, running module_init",
[MODULE_STATE_GOING] = "[MODULE_STATE_GOING] Going away",
[MODULE_STATE_UNFORMED] = "[MODULE_STATE_UNFORMED] Still setting it up",
+ [MODULE_STATE_GONE] = "[MODULE_STATE_GONE] Deconstructing and freeing",
};
static void callback_info(const char *callback, struct klp_object *obj)
@@ -16,6 +16,7 @@ static const char *const module_state[] = {
[MODULE_STATE_COMING] = "[MODULE_STATE_COMING] Full formed, running module_init",
[MODULE_STATE_GOING] = "[MODULE_STATE_GOING] Going away",
[MODULE_STATE_UNFORMED] = "[MODULE_STATE_UNFORMED] Still setting it up",
+ [MODULE_STATE_GONE] = "[MODULE_STATE_GONE] Deconstructing and freeing",
};
static void callback_info(const char *callback, struct klp_object *obj)
@@ -18,6 +18,7 @@ static const char *const module_state[] = {
[MODULE_STATE_COMING] = "[MODULE_STATE_COMING] Full formed, running module_init",
[MODULE_STATE_GOING] = "[MODULE_STATE_GOING] Going away",
[MODULE_STATE_UNFORMED] = "[MODULE_STATE_UNFORMED] Still setting it up",
+ [MODULE_STATE_GONE] = "[MODULE_STATE_GONE] Deconstructing and freeing",
};
static void callback_info(const char *callback, struct klp_object *obj)
@@ -18,6 +18,7 @@ static const char *const module_state[] = {
[MODULE_STATE_COMING] = "[MODULE_STATE_COMING] Full formed, running module_init",
[MODULE_STATE_GOING] = "[MODULE_STATE_GOING] Going away",
[MODULE_STATE_UNFORMED] = "[MODULE_STATE_UNFORMED] Still setting it up",
+ [MODULE_STATE_GONE] = "[MODULE_STATE_GONE] Deconstructing and freeing",
};
static void callback_info(const char *callback, struct klp_object *obj)