aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2015-06-25 17:14:38 -0400
committerRusty Russell <rusty@rustcorp.com.au>2015-06-28 01:16:14 -0400
commitcf2fde7b39e9446e2af015215d7fb695781af0c1 (patch)
tree646bec4e1717bf8370a3d4153c59a06a4a78f73f
parent38183b9c31cf21d8996d6eee2e3a14508b20c418 (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.h2
-rw-r--r--kernel/module.c9
-rw-r--r--kernel/params.c18
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
1823static 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
1825static int mod_sysfs_setup(struct module *mod, 1829static 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
1849static void init_param_lock(struct module *mod)
1850{
1851}
1845#endif /* CONFIG_SYSFS */ 1852#endif /* CONFIG_SYSFS */
1846 1853
1847static void mod_sysfs_teardown(struct module *mod) 1854static 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 */
29static DEFINE_MUTEX(param_lock); 30static 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 : &param_lock) 33#define KPARAM_MUTEX(mod) ((mod) ? &(mod)->param_lock : &param_lock)
33#define KPARAM_IS_LOCKED(mod) mutex_is_locked(KPARAM_MUTEX(mod)) 34
35static inline void check_kparam_locked(struct module *mod)
36{
37 BUG_ON(!mutex_is_locked(KPARAM_MUTEX(mod)));
38}
39#else
40static 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. */
36struct kmalloced_param { 46struct 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
619void kernel_param_lock(struct module *mod) 630void 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
630EXPORT_SYMBOL(kernel_param_lock); 640EXPORT_SYMBOL(kernel_param_lock);
631EXPORT_SYMBOL(kernel_param_unlock); 641EXPORT_SYMBOL(kernel_param_unlock);
632 642