diff options
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 181 |
1 files changed, 133 insertions, 48 deletions
diff --git a/kernel/module.c b/kernel/module.c index 250092c1d57d..eab08274ec9b 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -188,6 +188,7 @@ struct load_info { | |||
| 188 | ongoing or failed initialization etc. */ | 188 | ongoing or failed initialization etc. */ |
| 189 | static inline int strong_try_module_get(struct module *mod) | 189 | static inline int strong_try_module_get(struct module *mod) |
| 190 | { | 190 | { |
| 191 | BUG_ON(mod && mod->state == MODULE_STATE_UNFORMED); | ||
| 191 | if (mod && mod->state == MODULE_STATE_COMING) | 192 | if (mod && mod->state == MODULE_STATE_COMING) |
| 192 | return -EBUSY; | 193 | return -EBUSY; |
| 193 | if (try_module_get(mod)) | 194 | if (try_module_get(mod)) |
| @@ -343,6 +344,9 @@ bool each_symbol_section(bool (*fn)(const struct symsearch *arr, | |||
| 343 | #endif | 344 | #endif |
| 344 | }; | 345 | }; |
| 345 | 346 | ||
| 347 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 348 | continue; | ||
| 349 | |||
| 346 | if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data)) | 350 | if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data)) |
| 347 | return true; | 351 | return true; |
| 348 | } | 352 | } |
| @@ -450,16 +454,24 @@ const struct kernel_symbol *find_symbol(const char *name, | |||
| 450 | EXPORT_SYMBOL_GPL(find_symbol); | 454 | EXPORT_SYMBOL_GPL(find_symbol); |
| 451 | 455 | ||
| 452 | /* Search for module by name: must hold module_mutex. */ | 456 | /* Search for module by name: must hold module_mutex. */ |
| 453 | struct module *find_module(const char *name) | 457 | static struct module *find_module_all(const char *name, |
| 458 | bool even_unformed) | ||
| 454 | { | 459 | { |
| 455 | struct module *mod; | 460 | struct module *mod; |
| 456 | 461 | ||
| 457 | list_for_each_entry(mod, &modules, list) { | 462 | list_for_each_entry(mod, &modules, list) { |
| 463 | if (!even_unformed && mod->state == MODULE_STATE_UNFORMED) | ||
| 464 | continue; | ||
| 458 | if (strcmp(mod->name, name) == 0) | 465 | if (strcmp(mod->name, name) == 0) |
| 459 | return mod; | 466 | return mod; |
| 460 | } | 467 | } |
| 461 | return NULL; | 468 | return NULL; |
| 462 | } | 469 | } |
| 470 | |||
| 471 | struct module *find_module(const char *name) | ||
| 472 | { | ||
| 473 | return find_module_all(name, false); | ||
| 474 | } | ||
| 463 | EXPORT_SYMBOL_GPL(find_module); | 475 | EXPORT_SYMBOL_GPL(find_module); |
| 464 | 476 | ||
| 465 | #ifdef CONFIG_SMP | 477 | #ifdef CONFIG_SMP |
| @@ -525,6 +537,8 @@ bool is_module_percpu_address(unsigned long addr) | |||
| 525 | preempt_disable(); | 537 | preempt_disable(); |
| 526 | 538 | ||
| 527 | list_for_each_entry_rcu(mod, &modules, list) { | 539 | list_for_each_entry_rcu(mod, &modules, list) { |
| 540 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 541 | continue; | ||
| 528 | if (!mod->percpu_size) | 542 | if (!mod->percpu_size) |
| 529 | continue; | 543 | continue; |
| 530 | for_each_possible_cpu(cpu) { | 544 | for_each_possible_cpu(cpu) { |
| @@ -1048,6 +1062,8 @@ static ssize_t show_initstate(struct module_attribute *mattr, | |||
| 1048 | case MODULE_STATE_GOING: | 1062 | case MODULE_STATE_GOING: |
| 1049 | state = "going"; | 1063 | state = "going"; |
| 1050 | break; | 1064 | break; |
| 1065 | default: | ||
| 1066 | BUG(); | ||
| 1051 | } | 1067 | } |
| 1052 | return sprintf(buffer, "%s\n", state); | 1068 | return sprintf(buffer, "%s\n", state); |
| 1053 | } | 1069 | } |
| @@ -1786,6 +1802,8 @@ void set_all_modules_text_rw(void) | |||
| 1786 | 1802 | ||
| 1787 | mutex_lock(&module_mutex); | 1803 | mutex_lock(&module_mutex); |
| 1788 | list_for_each_entry_rcu(mod, &modules, list) { | 1804 | list_for_each_entry_rcu(mod, &modules, list) { |
| 1805 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 1806 | continue; | ||
| 1789 | if ((mod->module_core) && (mod->core_text_size)) { | 1807 | if ((mod->module_core) && (mod->core_text_size)) { |
| 1790 | set_page_attributes(mod->module_core, | 1808 | set_page_attributes(mod->module_core, |
| 1791 | mod->module_core + mod->core_text_size, | 1809 | mod->module_core + mod->core_text_size, |
| @@ -1807,6 +1825,8 @@ void set_all_modules_text_ro(void) | |||
| 1807 | 1825 | ||
| 1808 | mutex_lock(&module_mutex); | 1826 | mutex_lock(&module_mutex); |
| 1809 | list_for_each_entry_rcu(mod, &modules, list) { | 1827 | list_for_each_entry_rcu(mod, &modules, list) { |
| 1828 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 1829 | continue; | ||
| 1810 | if ((mod->module_core) && (mod->core_text_size)) { | 1830 | if ((mod->module_core) && (mod->core_text_size)) { |
| 1811 | set_page_attributes(mod->module_core, | 1831 | set_page_attributes(mod->module_core, |
| 1812 | mod->module_core + mod->core_text_size, | 1832 | mod->module_core + mod->core_text_size, |
| @@ -2527,6 +2547,13 @@ static int copy_module_from_fd(int fd, struct load_info *info) | |||
| 2527 | err = -EFBIG; | 2547 | err = -EFBIG; |
| 2528 | goto out; | 2548 | goto out; |
| 2529 | } | 2549 | } |
| 2550 | |||
| 2551 | /* Don't hand 0 to vmalloc, it whines. */ | ||
| 2552 | if (stat.size == 0) { | ||
| 2553 | err = -EINVAL; | ||
| 2554 | goto out; | ||
| 2555 | } | ||
| 2556 | |||
| 2530 | info->hdr = vmalloc(stat.size); | 2557 | info->hdr = vmalloc(stat.size); |
| 2531 | if (!info->hdr) { | 2558 | if (!info->hdr) { |
| 2532 | err = -ENOMEM; | 2559 | err = -ENOMEM; |
| @@ -2990,8 +3017,9 @@ static bool finished_loading(const char *name) | |||
| 2990 | bool ret; | 3017 | bool ret; |
| 2991 | 3018 | ||
| 2992 | mutex_lock(&module_mutex); | 3019 | mutex_lock(&module_mutex); |
| 2993 | mod = find_module(name); | 3020 | mod = find_module_all(name, true); |
| 2994 | ret = !mod || mod->state != MODULE_STATE_COMING; | 3021 | ret = !mod || mod->state == MODULE_STATE_LIVE |
| 3022 | || mod->state == MODULE_STATE_GOING; | ||
| 2995 | mutex_unlock(&module_mutex); | 3023 | mutex_unlock(&module_mutex); |
| 2996 | 3024 | ||
| 2997 | return ret; | 3025 | return ret; |
| @@ -3013,6 +3041,12 @@ static int do_init_module(struct module *mod) | |||
| 3013 | { | 3041 | { |
| 3014 | int ret = 0; | 3042 | int ret = 0; |
| 3015 | 3043 | ||
| 3044 | /* | ||
| 3045 | * We want to find out whether @mod uses async during init. Clear | ||
| 3046 | * PF_USED_ASYNC. async_schedule*() will set it. | ||
| 3047 | */ | ||
| 3048 | current->flags &= ~PF_USED_ASYNC; | ||
| 3049 | |||
| 3016 | blocking_notifier_call_chain(&module_notify_list, | 3050 | blocking_notifier_call_chain(&module_notify_list, |
| 3017 | MODULE_STATE_COMING, mod); | 3051 | MODULE_STATE_COMING, mod); |
| 3018 | 3052 | ||
| @@ -3058,8 +3092,25 @@ static int do_init_module(struct module *mod) | |||
| 3058 | blocking_notifier_call_chain(&module_notify_list, | 3092 | blocking_notifier_call_chain(&module_notify_list, |
| 3059 | MODULE_STATE_LIVE, mod); | 3093 | MODULE_STATE_LIVE, mod); |
| 3060 | 3094 | ||
| 3061 | /* We need to finish all async code before the module init sequence is done */ | 3095 | /* |
| 3062 | async_synchronize_full(); | 3096 | * We need to finish all async code before the module init sequence |
| 3097 | * is done. This has potential to deadlock. For example, a newly | ||
| 3098 | * detected block device can trigger request_module() of the | ||
| 3099 | * default iosched from async probing task. Once userland helper | ||
| 3100 | * reaches here, async_synchronize_full() will wait on the async | ||
| 3101 | * task waiting on request_module() and deadlock. | ||
| 3102 | * | ||
| 3103 | * This deadlock is avoided by perfomring async_synchronize_full() | ||
| 3104 | * iff module init queued any async jobs. This isn't a full | ||
| 3105 | * solution as it will deadlock the same if module loading from | ||
| 3106 | * async jobs nests more than once; however, due to the various | ||
| 3107 | * constraints, this hack seems to be the best option for now. | ||
| 3108 | * Please refer to the following thread for details. | ||
| 3109 | * | ||
| 3110 | * http://thread.gmane.org/gmane.linux.kernel/1420814 | ||
| 3111 | */ | ||
| 3112 | if (current->flags & PF_USED_ASYNC) | ||
| 3113 | async_synchronize_full(); | ||
| 3063 | 3114 | ||
| 3064 | mutex_lock(&module_mutex); | 3115 | mutex_lock(&module_mutex); |
| 3065 | /* Drop initial reference. */ | 3116 | /* Drop initial reference. */ |
| @@ -3113,6 +3164,32 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
| 3113 | goto free_copy; | 3164 | goto free_copy; |
| 3114 | } | 3165 | } |
| 3115 | 3166 | ||
| 3167 | /* | ||
| 3168 | * We try to place it in the list now to make sure it's unique | ||
| 3169 | * before we dedicate too many resources. In particular, | ||
| 3170 | * temporary percpu memory exhaustion. | ||
| 3171 | */ | ||
| 3172 | mod->state = MODULE_STATE_UNFORMED; | ||
| 3173 | again: | ||
| 3174 | mutex_lock(&module_mutex); | ||
| 3175 | if ((old = find_module_all(mod->name, true)) != NULL) { | ||
| 3176 | if (old->state == MODULE_STATE_COMING | ||
| 3177 | || old->state == MODULE_STATE_UNFORMED) { | ||
| 3178 | /* Wait in case it fails to load. */ | ||
| 3179 | mutex_unlock(&module_mutex); | ||
| 3180 | err = wait_event_interruptible(module_wq, | ||
| 3181 | finished_loading(mod->name)); | ||
| 3182 | if (err) | ||
| 3183 | goto free_module; | ||
| 3184 | goto again; | ||
| 3185 | } | ||
| 3186 | err = -EEXIST; | ||
| 3187 | mutex_unlock(&module_mutex); | ||
| 3188 | goto free_module; | ||
| 3189 | } | ||
| 3190 | list_add_rcu(&mod->list, &modules); | ||
| 3191 | mutex_unlock(&module_mutex); | ||
| 3192 | |||
| 3116 | #ifdef CONFIG_MODULE_SIG | 3193 | #ifdef CONFIG_MODULE_SIG |
| 3117 | mod->sig_ok = info->sig_ok; | 3194 | mod->sig_ok = info->sig_ok; |
| 3118 | if (!mod->sig_ok) | 3195 | if (!mod->sig_ok) |
| @@ -3122,7 +3199,7 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
| 3122 | /* Now module is in final location, initialize linked lists, etc. */ | 3199 | /* Now module is in final location, initialize linked lists, etc. */ |
| 3123 | err = module_unload_init(mod); | 3200 | err = module_unload_init(mod); |
| 3124 | if (err) | 3201 | if (err) |
| 3125 | goto free_module; | 3202 | goto unlink_mod; |
| 3126 | 3203 | ||
| 3127 | /* Now we've got everything in the final locations, we can | 3204 | /* Now we've got everything in the final locations, we can |
| 3128 | * find optional sections. */ | 3205 | * find optional sections. */ |
| @@ -3157,54 +3234,33 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
| 3157 | goto free_arch_cleanup; | 3234 | goto free_arch_cleanup; |
| 3158 | } | 3235 | } |
| 3159 | 3236 | ||
| 3160 | /* Mark state as coming so strong_try_module_get() ignores us. */ | ||
| 3161 | mod->state = MODULE_STATE_COMING; | ||
| 3162 | |||
| 3163 | /* Now sew it into the lists so we can get lockdep and oops | ||
| 3164 | * info during argument parsing. No one should access us, since | ||
| 3165 | * strong_try_module_get() will fail. | ||
| 3166 | * lockdep/oops can run asynchronous, so use the RCU list insertion | ||
| 3167 | * function to insert in a way safe to concurrent readers. | ||
| 3168 | * The mutex protects against concurrent writers. | ||
| 3169 | */ | ||
| 3170 | again: | ||
| 3171 | mutex_lock(&module_mutex); | ||
| 3172 | if ((old = find_module(mod->name)) != NULL) { | ||
| 3173 | if (old->state == MODULE_STATE_COMING) { | ||
| 3174 | /* Wait in case it fails to load. */ | ||
| 3175 | mutex_unlock(&module_mutex); | ||
| 3176 | err = wait_event_interruptible(module_wq, | ||
| 3177 | finished_loading(mod->name)); | ||
| 3178 | if (err) | ||
| 3179 | goto free_arch_cleanup; | ||
| 3180 | goto again; | ||
| 3181 | } | ||
| 3182 | err = -EEXIST; | ||
| 3183 | goto unlock; | ||
| 3184 | } | ||
| 3185 | |||
| 3186 | /* This has to be done once we're sure module name is unique. */ | ||
| 3187 | dynamic_debug_setup(info->debug, info->num_debug); | 3237 | dynamic_debug_setup(info->debug, info->num_debug); |
| 3188 | 3238 | ||
| 3189 | /* Find duplicate symbols */ | 3239 | mutex_lock(&module_mutex); |
| 3240 | /* Find duplicate symbols (must be called under lock). */ | ||
| 3190 | err = verify_export_symbols(mod); | 3241 | err = verify_export_symbols(mod); |
| 3191 | if (err < 0) | 3242 | if (err < 0) |
| 3192 | goto ddebug; | 3243 | goto ddebug_cleanup; |
| 3193 | 3244 | ||
| 3245 | /* This relies on module_mutex for list integrity. */ | ||
| 3194 | module_bug_finalize(info->hdr, info->sechdrs, mod); | 3246 | module_bug_finalize(info->hdr, info->sechdrs, mod); |
| 3195 | list_add_rcu(&mod->list, &modules); | 3247 | |
| 3248 | /* Mark state as coming so strong_try_module_get() ignores us, | ||
| 3249 | * but kallsyms etc. can see us. */ | ||
| 3250 | mod->state = MODULE_STATE_COMING; | ||
| 3251 | |||
| 3196 | mutex_unlock(&module_mutex); | 3252 | mutex_unlock(&module_mutex); |
| 3197 | 3253 | ||
| 3198 | /* Module is ready to execute: parsing args may do that. */ | 3254 | /* Module is ready to execute: parsing args may do that. */ |
| 3199 | err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, | 3255 | err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, |
| 3200 | -32768, 32767, &ddebug_dyndbg_module_param_cb); | 3256 | -32768, 32767, &ddebug_dyndbg_module_param_cb); |
| 3201 | if (err < 0) | 3257 | if (err < 0) |
| 3202 | goto unlink; | 3258 | goto bug_cleanup; |
| 3203 | 3259 | ||
| 3204 | /* Link in to syfs. */ | 3260 | /* Link in to syfs. */ |
| 3205 | err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp); | 3261 | err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp); |
| 3206 | if (err < 0) | 3262 | if (err < 0) |
| 3207 | goto unlink; | 3263 | goto bug_cleanup; |
| 3208 | 3264 | ||
| 3209 | /* Get rid of temporary copy. */ | 3265 | /* Get rid of temporary copy. */ |
| 3210 | free_copy(info); | 3266 | free_copy(info); |
| @@ -3214,16 +3270,13 @@ again: | |||
| 3214 | 3270 | ||
| 3215 | return do_init_module(mod); | 3271 | return do_init_module(mod); |
| 3216 | 3272 | ||
| 3217 | unlink: | 3273 | bug_cleanup: |
| 3274 | /* module_bug_cleanup needs module_mutex protection */ | ||
| 3218 | mutex_lock(&module_mutex); | 3275 | mutex_lock(&module_mutex); |
| 3219 | /* Unlink carefully: kallsyms could be walking list. */ | ||
| 3220 | list_del_rcu(&mod->list); | ||
| 3221 | module_bug_cleanup(mod); | 3276 | module_bug_cleanup(mod); |
| 3222 | wake_up_all(&module_wq); | 3277 | ddebug_cleanup: |
| 3223 | ddebug: | ||
| 3224 | dynamic_debug_remove(info->debug); | ||
| 3225 | unlock: | ||
| 3226 | mutex_unlock(&module_mutex); | 3278 | mutex_unlock(&module_mutex); |
| 3279 | dynamic_debug_remove(info->debug); | ||
| 3227 | synchronize_sched(); | 3280 | synchronize_sched(); |
| 3228 | kfree(mod->args); | 3281 | kfree(mod->args); |
| 3229 | free_arch_cleanup: | 3282 | free_arch_cleanup: |
| @@ -3232,6 +3285,12 @@ again: | |||
| 3232 | free_modinfo(mod); | 3285 | free_modinfo(mod); |
| 3233 | free_unload: | 3286 | free_unload: |
| 3234 | module_unload_free(mod); | 3287 | module_unload_free(mod); |
| 3288 | unlink_mod: | ||
| 3289 | mutex_lock(&module_mutex); | ||
| 3290 | /* Unlink carefully: kallsyms could be walking list. */ | ||
| 3291 | list_del_rcu(&mod->list); | ||
| 3292 | wake_up_all(&module_wq); | ||
| 3293 | mutex_unlock(&module_mutex); | ||
| 3235 | free_module: | 3294 | free_module: |
| 3236 | module_deallocate(mod, info); | 3295 | module_deallocate(mod, info); |
| 3237 | free_copy: | 3296 | free_copy: |
| @@ -3354,6 +3413,8 @@ const char *module_address_lookup(unsigned long addr, | |||
| 3354 | 3413 | ||
| 3355 | preempt_disable(); | 3414 | preempt_disable(); |
| 3356 | list_for_each_entry_rcu(mod, &modules, list) { | 3415 | list_for_each_entry_rcu(mod, &modules, list) { |
| 3416 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 3417 | continue; | ||
| 3357 | if (within_module_init(addr, mod) || | 3418 | if (within_module_init(addr, mod) || |
| 3358 | within_module_core(addr, mod)) { | 3419 | within_module_core(addr, mod)) { |
| 3359 | if (modname) | 3420 | if (modname) |
| @@ -3377,6 +3438,8 @@ int lookup_module_symbol_name(unsigned long addr, char *symname) | |||
| 3377 | 3438 | ||
| 3378 | preempt_disable(); | 3439 | preempt_disable(); |
| 3379 | list_for_each_entry_rcu(mod, &modules, list) { | 3440 | list_for_each_entry_rcu(mod, &modules, list) { |
| 3441 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 3442 | continue; | ||
| 3380 | if (within_module_init(addr, mod) || | 3443 | if (within_module_init(addr, mod) || |
| 3381 | within_module_core(addr, mod)) { | 3444 | within_module_core(addr, mod)) { |
| 3382 | const char *sym; | 3445 | const char *sym; |
| @@ -3401,6 +3464,8 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, | |||
| 3401 | 3464 | ||
| 3402 | preempt_disable(); | 3465 | preempt_disable(); |
| 3403 | list_for_each_entry_rcu(mod, &modules, list) { | 3466 | list_for_each_entry_rcu(mod, &modules, list) { |
| 3467 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 3468 | continue; | ||
| 3404 | if (within_module_init(addr, mod) || | 3469 | if (within_module_init(addr, mod) || |
| 3405 | within_module_core(addr, mod)) { | 3470 | within_module_core(addr, mod)) { |
| 3406 | const char *sym; | 3471 | const char *sym; |
| @@ -3428,6 +3493,8 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, | |||
| 3428 | 3493 | ||
| 3429 | preempt_disable(); | 3494 | preempt_disable(); |
| 3430 | list_for_each_entry_rcu(mod, &modules, list) { | 3495 | list_for_each_entry_rcu(mod, &modules, list) { |
| 3496 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 3497 | continue; | ||
| 3431 | if (symnum < mod->num_symtab) { | 3498 | if (symnum < mod->num_symtab) { |
| 3432 | *value = mod->symtab[symnum].st_value; | 3499 | *value = mod->symtab[symnum].st_value; |
| 3433 | *type = mod->symtab[symnum].st_info; | 3500 | *type = mod->symtab[symnum].st_info; |
| @@ -3470,9 +3537,12 @@ unsigned long module_kallsyms_lookup_name(const char *name) | |||
| 3470 | ret = mod_find_symname(mod, colon+1); | 3537 | ret = mod_find_symname(mod, colon+1); |
| 3471 | *colon = ':'; | 3538 | *colon = ':'; |
| 3472 | } else { | 3539 | } else { |
| 3473 | list_for_each_entry_rcu(mod, &modules, list) | 3540 | list_for_each_entry_rcu(mod, &modules, list) { |
| 3541 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 3542 | continue; | ||
| 3474 | if ((ret = mod_find_symname(mod, name)) != 0) | 3543 | if ((ret = mod_find_symname(mod, name)) != 0) |
| 3475 | break; | 3544 | break; |
| 3545 | } | ||
| 3476 | } | 3546 | } |
| 3477 | preempt_enable(); | 3547 | preempt_enable(); |
| 3478 | return ret; | 3548 | return ret; |
| @@ -3487,6 +3557,8 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, | |||
| 3487 | int ret; | 3557 | int ret; |
| 3488 | 3558 | ||
| 3489 | list_for_each_entry(mod, &modules, list) { | 3559 | list_for_each_entry(mod, &modules, list) { |
| 3560 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 3561 | continue; | ||
| 3490 | for (i = 0; i < mod->num_symtab; i++) { | 3562 | for (i = 0; i < mod->num_symtab; i++) { |
| 3491 | ret = fn(data, mod->strtab + mod->symtab[i].st_name, | 3563 | ret = fn(data, mod->strtab + mod->symtab[i].st_name, |
| 3492 | mod, mod->symtab[i].st_value); | 3564 | mod, mod->symtab[i].st_value); |
| @@ -3502,6 +3574,7 @@ static char *module_flags(struct module *mod, char *buf) | |||
| 3502 | { | 3574 | { |
| 3503 | int bx = 0; | 3575 | int bx = 0; |
| 3504 | 3576 | ||
| 3577 | BUG_ON(mod->state == MODULE_STATE_UNFORMED); | ||
| 3505 | if (mod->taints || | 3578 | if (mod->taints || |
| 3506 | mod->state == MODULE_STATE_GOING || | 3579 | mod->state == MODULE_STATE_GOING || |
| 3507 | mod->state == MODULE_STATE_COMING) { | 3580 | mod->state == MODULE_STATE_COMING) { |
| @@ -3543,6 +3616,10 @@ static int m_show(struct seq_file *m, void *p) | |||
| 3543 | struct module *mod = list_entry(p, struct module, list); | 3616 | struct module *mod = list_entry(p, struct module, list); |
| 3544 | char buf[8]; | 3617 | char buf[8]; |
| 3545 | 3618 | ||
| 3619 | /* We always ignore unformed modules. */ | ||
| 3620 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 3621 | return 0; | ||
| 3622 | |||
| 3546 | seq_printf(m, "%s %u", | 3623 | seq_printf(m, "%s %u", |
| 3547 | mod->name, mod->init_size + mod->core_size); | 3624 | mod->name, mod->init_size + mod->core_size); |
| 3548 | print_unload_info(m, mod); | 3625 | print_unload_info(m, mod); |
| @@ -3603,6 +3680,8 @@ const struct exception_table_entry *search_module_extables(unsigned long addr) | |||
| 3603 | 3680 | ||
| 3604 | preempt_disable(); | 3681 | preempt_disable(); |
| 3605 | list_for_each_entry_rcu(mod, &modules, list) { | 3682 | list_for_each_entry_rcu(mod, &modules, list) { |
| 3683 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 3684 | continue; | ||
| 3606 | if (mod->num_exentries == 0) | 3685 | if (mod->num_exentries == 0) |
| 3607 | continue; | 3686 | continue; |
| 3608 | 3687 | ||
| @@ -3651,10 +3730,13 @@ struct module *__module_address(unsigned long addr) | |||
| 3651 | if (addr < module_addr_min || addr > module_addr_max) | 3730 | if (addr < module_addr_min || addr > module_addr_max) |
| 3652 | return NULL; | 3731 | return NULL; |
| 3653 | 3732 | ||
| 3654 | list_for_each_entry_rcu(mod, &modules, list) | 3733 | list_for_each_entry_rcu(mod, &modules, list) { |
| 3734 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 3735 | continue; | ||
| 3655 | if (within_module_core(addr, mod) | 3736 | if (within_module_core(addr, mod) |
| 3656 | || within_module_init(addr, mod)) | 3737 | || within_module_init(addr, mod)) |
| 3657 | return mod; | 3738 | return mod; |
| 3739 | } | ||
| 3658 | return NULL; | 3740 | return NULL; |
| 3659 | } | 3741 | } |
| 3660 | EXPORT_SYMBOL_GPL(__module_address); | 3742 | EXPORT_SYMBOL_GPL(__module_address); |
| @@ -3707,8 +3789,11 @@ void print_modules(void) | |||
| 3707 | printk(KERN_DEFAULT "Modules linked in:"); | 3789 | printk(KERN_DEFAULT "Modules linked in:"); |
| 3708 | /* Most callers should already have preempt disabled, but make sure */ | 3790 | /* Most callers should already have preempt disabled, but make sure */ |
| 3709 | preempt_disable(); | 3791 | preempt_disable(); |
| 3710 | list_for_each_entry_rcu(mod, &modules, list) | 3792 | list_for_each_entry_rcu(mod, &modules, list) { |
| 3793 | if (mod->state == MODULE_STATE_UNFORMED) | ||
| 3794 | continue; | ||
| 3711 | printk(" %s%s", mod->name, module_flags(mod, buf)); | 3795 | printk(" %s%s", mod->name, module_flags(mod, buf)); |
| 3796 | } | ||
| 3712 | preempt_enable(); | 3797 | preempt_enable(); |
| 3713 | if (last_unloaded_module[0]) | 3798 | if (last_unloaded_module[0]) |
| 3714 | printk(" [last unloaded: %s]", last_unloaded_module); | 3799 | printk(" [last unloaded: %s]", last_unloaded_module); |
