diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2015-06-25 17:14:38 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-06-28 01:16:14 -0400 |
commit | cf2fde7b39e9446e2af015215d7fb695781af0c1 (patch) | |
tree | 646bec4e1717bf8370a3d4153c59a06a4a78f73f | |
parent | 38183b9c31cf21d8996d6eee2e3a14508b20c418 (diff) |
param: fix module param locks when !CONFIG_SYSFS.
As Dan Streetman points out, the entire point of locking for is to
stop sysfs accesses, so they're elided entirely in the !SYSFS case.
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r-- | include/linux/module.h | 2 | ||||
-rw-r--r-- | kernel/module.c | 9 | ||||
-rw-r--r-- | kernel/params.c | 18 |
3 files changed, 24 insertions, 5 deletions
diff --git a/include/linux/module.h b/include/linux/module.h index 6ba0e87fa804..46efa1c9de60 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -240,7 +240,9 @@ struct module { | |||
240 | unsigned int num_syms; | 240 | unsigned int num_syms; |
241 | 241 | ||
242 | /* Kernel parameters. */ | 242 | /* Kernel parameters. */ |
243 | #ifdef CONFIG_SYSFS | ||
243 | struct mutex param_lock; | 244 | struct mutex param_lock; |
245 | #endif | ||
244 | struct kernel_param *kp; | 246 | struct kernel_param *kp; |
245 | unsigned int num_kp; | 247 | unsigned int num_kp; |
246 | 248 | ||
diff --git a/kernel/module.c b/kernel/module.c index 8ec33ce202a6..b4994adf7187 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -1820,6 +1820,10 @@ static void mod_sysfs_fini(struct module *mod) | |||
1820 | mod_kobject_put(mod); | 1820 | mod_kobject_put(mod); |
1821 | } | 1821 | } |
1822 | 1822 | ||
1823 | static void init_param_lock(struct module *mod) | ||
1824 | { | ||
1825 | mutex_init(&mod->param_lock); | ||
1826 | } | ||
1823 | #else /* !CONFIG_SYSFS */ | 1827 | #else /* !CONFIG_SYSFS */ |
1824 | 1828 | ||
1825 | static int mod_sysfs_setup(struct module *mod, | 1829 | static int mod_sysfs_setup(struct module *mod, |
@@ -1842,6 +1846,9 @@ static void del_usage_links(struct module *mod) | |||
1842 | { | 1846 | { |
1843 | } | 1847 | } |
1844 | 1848 | ||
1849 | static void init_param_lock(struct module *mod) | ||
1850 | { | ||
1851 | } | ||
1845 | #endif /* CONFIG_SYSFS */ | 1852 | #endif /* CONFIG_SYSFS */ |
1846 | 1853 | ||
1847 | static void mod_sysfs_teardown(struct module *mod) | 1854 | static void mod_sysfs_teardown(struct module *mod) |
@@ -3442,7 +3449,7 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
3442 | if (err) | 3449 | if (err) |
3443 | goto unlink_mod; | 3450 | goto unlink_mod; |
3444 | 3451 | ||
3445 | mutex_init(&mod->param_lock); | 3452 | init_param_lock(mod); |
3446 | 3453 | ||
3447 | /* Now we've got everything in the final locations, we can | 3454 | /* Now we've got everything in the final locations, we can |
3448 | * find optional sections. */ | 3455 | * find optional sections. */ |
diff --git a/kernel/params.c b/kernel/params.c index 8890d0b8dffc..faa461c16f12 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -25,12 +25,22 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/ctype.h> | 26 | #include <linux/ctype.h> |
27 | 27 | ||
28 | #ifdef CONFIG_SYSFS | ||
28 | /* Protects all built-in parameters, modules use their own param_lock */ | 29 | /* Protects all built-in parameters, modules use their own param_lock */ |
29 | static DEFINE_MUTEX(param_lock); | 30 | static DEFINE_MUTEX(param_lock); |
30 | 31 | ||
31 | /* Use the module's mutex, or if built-in use the built-in mutex */ | 32 | /* Use the module's mutex, or if built-in use the built-in mutex */ |
32 | #define KPARAM_MUTEX(mod) ((mod) ? &(mod)->param_lock : ¶m_lock) | 33 | #define KPARAM_MUTEX(mod) ((mod) ? &(mod)->param_lock : ¶m_lock) |
33 | #define KPARAM_IS_LOCKED(mod) mutex_is_locked(KPARAM_MUTEX(mod)) | 34 | |
35 | static inline void check_kparam_locked(struct module *mod) | ||
36 | { | ||
37 | BUG_ON(!mutex_is_locked(KPARAM_MUTEX(mod))); | ||
38 | } | ||
39 | #else | ||
40 | static inline void check_kparam_locked(struct module *mod) | ||
41 | { | ||
42 | } | ||
43 | #endif /* !CONFIG_SYSFS */ | ||
34 | 44 | ||
35 | /* This just allows us to keep track of which parameters are kmalloced. */ | 45 | /* This just allows us to keep track of which parameters are kmalloced. */ |
36 | struct kmalloced_param { | 46 | struct kmalloced_param { |
@@ -459,7 +469,7 @@ static int param_array(struct module *mod, | |||
459 | /* nul-terminate and parse */ | 469 | /* nul-terminate and parse */ |
460 | save = val[len]; | 470 | save = val[len]; |
461 | ((char *)val)[len] = '\0'; | 471 | ((char *)val)[len] = '\0'; |
462 | BUG_ON(!KPARAM_IS_LOCKED(mod)); | 472 | check_kparam_locked(mod); |
463 | ret = set(val, &kp); | 473 | ret = set(val, &kp); |
464 | 474 | ||
465 | if (ret != 0) | 475 | if (ret != 0) |
@@ -496,7 +506,7 @@ static int param_array_get(char *buffer, const struct kernel_param *kp) | |||
496 | if (i) | 506 | if (i) |
497 | buffer[off++] = ','; | 507 | buffer[off++] = ','; |
498 | p.arg = arr->elem + arr->elemsize * i; | 508 | p.arg = arr->elem + arr->elemsize * i; |
499 | BUG_ON(!KPARAM_IS_LOCKED(p.mod)); | 509 | check_kparam_locked(p.mod); |
500 | ret = arr->ops->get(buffer + off, &p); | 510 | ret = arr->ops->get(buffer + off, &p); |
501 | if (ret < 0) | 511 | if (ret < 0) |
502 | return ret; | 512 | return ret; |
@@ -616,6 +626,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr, | |||
616 | #define __modinit __init | 626 | #define __modinit __init |
617 | #endif | 627 | #endif |
618 | 628 | ||
629 | #ifdef CONFIG_SYSFS | ||
619 | void kernel_param_lock(struct module *mod) | 630 | void kernel_param_lock(struct module *mod) |
620 | { | 631 | { |
621 | mutex_lock(KPARAM_MUTEX(mod)); | 632 | mutex_lock(KPARAM_MUTEX(mod)); |
@@ -626,7 +637,6 @@ void kernel_param_unlock(struct module *mod) | |||
626 | mutex_unlock(KPARAM_MUTEX(mod)); | 637 | mutex_unlock(KPARAM_MUTEX(mod)); |
627 | } | 638 | } |
628 | 639 | ||
629 | #ifdef CONFIG_SYSFS | ||
630 | EXPORT_SYMBOL(kernel_param_lock); | 640 | EXPORT_SYMBOL(kernel_param_lock); |
631 | EXPORT_SYMBOL(kernel_param_unlock); | 641 | EXPORT_SYMBOL(kernel_param_unlock); |
632 | 642 | ||