aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/module.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 63cf6e7f1394..74bc19562ca3 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2845,6 +2845,20 @@ static int post_relocation(struct module *mod, const struct load_info *info)
2845 return module_finalize(info->hdr, info->sechdrs, mod); 2845 return module_finalize(info->hdr, info->sechdrs, mod);
2846} 2846}
2847 2847
2848/* Is this module of this name done loading? No locks held. */
2849static bool finished_loading(const char *name)
2850{
2851 struct module *mod;
2852 bool ret;
2853
2854 mutex_lock(&module_mutex);
2855 mod = find_module(name);
2856 ret = !mod || mod->state != MODULE_STATE_COMING;
2857 mutex_unlock(&module_mutex);
2858
2859 return ret;
2860}
2861
2848/* Allocate and load the module: note that size of section 0 is always 2862/* Allocate and load the module: note that size of section 0 is always
2849 zero, and we rely on this for optional sections. */ 2863 zero, and we rely on this for optional sections. */
2850static struct module *load_module(void __user *umod, 2864static struct module *load_module(void __user *umod,
@@ -2852,7 +2866,7 @@ static struct module *load_module(void __user *umod,
2852 const char __user *uargs) 2866 const char __user *uargs)
2853{ 2867{
2854 struct load_info info = { NULL, }; 2868 struct load_info info = { NULL, };
2855 struct module *mod; 2869 struct module *mod, *old;
2856 long err; 2870 long err;
2857 2871
2858 pr_debug("load_module: umod=%p, len=%lu, uargs=%p\n", 2872 pr_debug("load_module: umod=%p, len=%lu, uargs=%p\n",
@@ -2918,8 +2932,18 @@ static struct module *load_module(void __user *umod,
2918 * function to insert in a way safe to concurrent readers. 2932 * function to insert in a way safe to concurrent readers.
2919 * The mutex protects against concurrent writers. 2933 * The mutex protects against concurrent writers.
2920 */ 2934 */
2935again:
2921 mutex_lock(&module_mutex); 2936 mutex_lock(&module_mutex);
2922 if (find_module(mod->name)) { 2937 if ((old = find_module(mod->name)) != NULL) {
2938 if (old->state == MODULE_STATE_COMING) {
2939 /* Wait in case it fails to load. */
2940 mutex_unlock(&module_mutex);
2941 err = wait_event_interruptible(module_wq,
2942 finished_loading(mod->name));
2943 if (err)
2944 goto free_arch_cleanup;
2945 goto again;
2946 }
2923 err = -EEXIST; 2947 err = -EEXIST;
2924 goto unlock; 2948 goto unlock;
2925 } 2949 }