diff --git a/kernel/patch/module/module.c b/kernel/patch/module/module.c index aac23bdf..35ef772a 100644 --- a/kernel/patch/module/module.c +++ b/kernel/patch/module/module.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -447,7 +448,7 @@ static int elf_header_check(struct load_info *info) } struct module modules = { 0 }; -static spinlock_t module_lock; +static DEFINE_MUTEX(module_ctl_lock); long load_module(const void *data, int len, const char *args, const char *event, void *__user reserved) { @@ -458,18 +459,20 @@ long load_module(const void *data, int len, const char *args, const char *event, if ((rc = elf_header_check(info))) goto out; if ((rc = setup_load_info(info))) goto out; + mutex_lock(&module_ctl_lock); + if (find_module(info->info.name)) { logkfd("%s exist\n", info->info.name); set_load_error(info, "module already exists"); rc = -EEXIST; - goto out; + goto unlock; } struct module *mod = (struct module *)vmalloc(sizeof(struct module)); if (!mod) { set_load_error(info, "allocate module state failed"); rc = -ENOMEM; - goto out; + goto unlock; } memset(mod, 0, sizeof(struct module)); @@ -503,7 +506,7 @@ long load_module(const void *data, int len, const char *args, const char *event, if (!rc) { logkfi("[%s] succeed with [%s] \n", mod->info.name, args); list_add_tail(&mod->list, &modules.list); - goto out; + goto unlock; } else { set_load_error(info, "module init failed"); logkfi("[%s] failed with [%s] error: %d, try exit ...\n", mod->info.name, args, rc); @@ -515,25 +518,28 @@ long load_module(const void *data, int len, const char *args, const char *event, kp_free_exec(mod->start); free1: kvfree(mod); +unlock: + mutex_unlock(&module_ctl_lock); out: set_kpm_load_result(reserved, rc, rc ? load_error(info, "load module failed") : "module loaded"); return rc; } -// todo: lock long unload_module(const char *name, void *__user reserved) { if (!name) return -EINVAL; logkfe("name: %s\n", name); - rcu_read_lock(); long rc = 0; + mutex_lock(&module_ctl_lock); + struct module *mod = find_module(name); if (!mod) { rc = -ENOENT; goto out; } + list_del(&mod->list); rc = (*mod->exit)(reserved); @@ -546,7 +552,7 @@ long unload_module(const char *name, void *__user reserved) logkfi("name: %s, rc: %d\n", name, rc); out: - rcu_read_unlock(); + mutex_unlock(&module_ctl_lock); return rc; } @@ -609,7 +615,7 @@ long module_control0(const char *name, const char *ctl_args, char *__user out_ms logkfi("name %s, args: %s\n", name, ctl_args); long rc = 0; - rcu_read_lock(); + mutex_lock(&module_ctl_lock); struct module *mod = find_module(name); if (!mod) { @@ -637,7 +643,7 @@ long module_control0(const char *name, const char *ctl_args, char *__user out_ms logkfi("name: %s, rc: %d\n", name, rc); out: - rcu_read_unlock(); + mutex_unlock(&module_ctl_lock); return rc; } @@ -766,5 +772,4 @@ int get_module_info(const char *name, char *out_info, int size) void module_init() { INIT_LIST_HEAD(&modules.list); - spin_lock_init(&module_lock); }