.. | .. |
---|
2285 | 2285 | void *__symbol_get(const char *symbol) |
---|
2286 | 2286 | { |
---|
2287 | 2287 | struct module *owner; |
---|
| 2288 | + enum mod_license license; |
---|
2288 | 2289 | const struct kernel_symbol *sym; |
---|
2289 | 2290 | |
---|
2290 | 2291 | preempt_disable(); |
---|
2291 | | - sym = find_symbol(symbol, &owner, NULL, NULL, true, true); |
---|
2292 | | - if (sym && strong_try_module_get(owner)) |
---|
| 2292 | + sym = find_symbol(symbol, &owner, NULL, &license, true, true); |
---|
| 2293 | + if (!sym) |
---|
| 2294 | + goto fail; |
---|
| 2295 | + if (license != GPL_ONLY) { |
---|
| 2296 | + pr_warn("failing symbol_get of non-GPLONLY symbol %s.\n", |
---|
| 2297 | + symbol); |
---|
| 2298 | + goto fail; |
---|
| 2299 | + } |
---|
| 2300 | + if (strong_try_module_get(owner)) |
---|
2293 | 2301 | sym = NULL; |
---|
2294 | 2302 | preempt_enable(); |
---|
2295 | 2303 | |
---|
2296 | 2304 | return sym ? (void *)kernel_symbol_value(sym) : NULL; |
---|
| 2305 | +fail: |
---|
| 2306 | + preempt_enable(); |
---|
| 2307 | + return NULL; |
---|
2297 | 2308 | } |
---|
2298 | 2309 | EXPORT_SYMBOL_GPL(__symbol_get); |
---|
2299 | 2310 | |
---|
2300 | | -static bool module_init_layout_section(const char *sname) |
---|
| 2311 | +bool module_init_layout_section(const char *sname) |
---|
2301 | 2312 | { |
---|
2302 | 2313 | #ifndef CONFIG_MODULE_UNLOAD |
---|
2303 | 2314 | if (module_exit_section(sname)) |
---|
.. | .. |
---|
3686 | 3697 | sched_annotate_sleep(); |
---|
3687 | 3698 | mutex_lock(&module_mutex); |
---|
3688 | 3699 | mod = find_module_all(name, strlen(name), true); |
---|
3689 | | - ret = !mod || mod->state == MODULE_STATE_LIVE; |
---|
| 3700 | + ret = !mod || mod->state == MODULE_STATE_LIVE |
---|
| 3701 | + || mod->state == MODULE_STATE_GOING; |
---|
3690 | 3702 | mutex_unlock(&module_mutex); |
---|
3691 | 3703 | |
---|
3692 | 3704 | return ret; |
---|
.. | .. |
---|
3857 | 3869 | |
---|
3858 | 3870 | mod->state = MODULE_STATE_UNFORMED; |
---|
3859 | 3871 | |
---|
3860 | | -again: |
---|
3861 | 3872 | mutex_lock(&module_mutex); |
---|
3862 | 3873 | old = find_module_all(mod->name, strlen(mod->name), true); |
---|
3863 | 3874 | if (old != NULL) { |
---|
3864 | | - if (old->state != MODULE_STATE_LIVE) { |
---|
| 3875 | + if (old->state == MODULE_STATE_COMING |
---|
| 3876 | + || old->state == MODULE_STATE_UNFORMED) { |
---|
3865 | 3877 | /* Wait in case it fails to load. */ |
---|
3866 | 3878 | mutex_unlock(&module_mutex); |
---|
3867 | 3879 | err = wait_event_interruptible(module_wq, |
---|
3868 | 3880 | finished_loading(mod->name)); |
---|
3869 | 3881 | if (err) |
---|
3870 | 3882 | goto out_unlocked; |
---|
3871 | | - goto again; |
---|
| 3883 | + |
---|
| 3884 | + /* The module might have gone in the meantime. */ |
---|
| 3885 | + mutex_lock(&module_mutex); |
---|
| 3886 | + old = find_module_all(mod->name, strlen(mod->name), |
---|
| 3887 | + true); |
---|
3872 | 3888 | } |
---|
3873 | | - err = -EEXIST; |
---|
| 3889 | + |
---|
| 3890 | + /* |
---|
| 3891 | + * We are here only when the same module was being loaded. Do |
---|
| 3892 | + * not try to load it again right now. It prevents long delays |
---|
| 3893 | + * caused by serialized module load failures. It might happen |
---|
| 3894 | + * when more devices of the same type trigger load of |
---|
| 3895 | + * a particular module. |
---|
| 3896 | + */ |
---|
| 3897 | + if (old && old->state == MODULE_STATE_LIVE) |
---|
| 3898 | + err = -EEXIST; |
---|
| 3899 | + else |
---|
| 3900 | + err = -EBUSY; |
---|
3874 | 3901 | goto out; |
---|
3875 | 3902 | } |
---|
3876 | 3903 | mod_update_bounds(mod); |
---|