aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/um/drivers/hostaudio_kern.c20
-rw-r--r--drivers/net/ethernet/myricom/myri10ge/myri10ge.c6
-rw-r--r--drivers/net/wireless/libertas_tf/if_usb.c6
-rw-r--r--drivers/usb/atm/ueagle-atm.c4
-rw-r--r--drivers/video/fbdev/vt8623fb.c4
-rw-r--r--include/linux/module.h1
-rw-r--r--include/linux/moduleparam.h61
-rw-r--r--kernel/module.c2
-rw-r--r--kernel/params.c50
-rw-r--r--net/mac80211/rate.c4
10 files changed, 65 insertions, 93 deletions
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index 9b90fdc4b151..f6b911cc3923 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -185,9 +185,9 @@ static int hostaudio_open(struct inode *inode, struct file *file)
185 int ret; 185 int ret;
186 186
187#ifdef DEBUG 187#ifdef DEBUG
188 kparam_block_sysfs_write(dsp); 188 kernel_param_lock(THIS_MODULE);
189 printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp); 189 printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp);
190 kparam_unblock_sysfs_write(dsp); 190 kernel_param_unlock(THIS_MODULE);
191#endif 191#endif
192 192
193 state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL); 193 state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
@@ -199,11 +199,11 @@ static int hostaudio_open(struct inode *inode, struct file *file)
199 if (file->f_mode & FMODE_WRITE) 199 if (file->f_mode & FMODE_WRITE)
200 w = 1; 200 w = 1;
201 201
202 kparam_block_sysfs_write(dsp); 202 kernel_param_lock(THIS_MODULE);
203 mutex_lock(&hostaudio_mutex); 203 mutex_lock(&hostaudio_mutex);
204 ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); 204 ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
205 mutex_unlock(&hostaudio_mutex); 205 mutex_unlock(&hostaudio_mutex);
206 kparam_unblock_sysfs_write(dsp); 206 kernel_param_unlock(THIS_MODULE);
207 207
208 if (ret < 0) { 208 if (ret < 0) {
209 kfree(state); 209 kfree(state);
@@ -260,17 +260,17 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
260 if (file->f_mode & FMODE_WRITE) 260 if (file->f_mode & FMODE_WRITE)
261 w = 1; 261 w = 1;
262 262
263 kparam_block_sysfs_write(mixer); 263 kernel_param_lock(THIS_MODULE);
264 mutex_lock(&hostaudio_mutex); 264 mutex_lock(&hostaudio_mutex);
265 ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); 265 ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
266 mutex_unlock(&hostaudio_mutex); 266 mutex_unlock(&hostaudio_mutex);
267 kparam_unblock_sysfs_write(mixer); 267 kernel_param_unlock(THIS_MODULE);
268 268
269 if (ret < 0) { 269 if (ret < 0) {
270 kparam_block_sysfs_write(dsp); 270 kernel_param_lock(THIS_MODULE);
271 printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', " 271 printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', "
272 "err = %d\n", dsp, -ret); 272 "err = %d\n", dsp, -ret);
273 kparam_unblock_sysfs_write(dsp); 273 kernel_param_unlock(THIS_MODULE);
274 kfree(state); 274 kfree(state);
275 return ret; 275 return ret;
276 } 276 }
@@ -326,10 +326,10 @@ MODULE_LICENSE("GPL");
326 326
327static int __init hostaudio_init_module(void) 327static int __init hostaudio_init_module(void)
328{ 328{
329 __kernel_param_lock(); 329 kernel_param_lock(THIS_MODULE);
330 printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n", 330 printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
331 dsp, mixer); 331 dsp, mixer);
332 __kernel_param_unlock(); 332 kernel_param_unlock(THIS_MODULE);
333 333
334 module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1); 334 module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
335 if (module_data.dev_audio < 0) { 335 if (module_data.dev_audio < 0) {
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 2bae50292dcd..83651ac8ddb9 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -279,7 +279,7 @@ MODULE_FIRMWARE("myri10ge_eth_z8e.dat");
279MODULE_FIRMWARE("myri10ge_rss_ethp_z8e.dat"); 279MODULE_FIRMWARE("myri10ge_rss_ethp_z8e.dat");
280MODULE_FIRMWARE("myri10ge_rss_eth_z8e.dat"); 280MODULE_FIRMWARE("myri10ge_rss_eth_z8e.dat");
281 281
282/* Careful: must be accessed under kparam_block_sysfs_write */ 282/* Careful: must be accessed under kernel_param_lock() */
283static char *myri10ge_fw_name = NULL; 283static char *myri10ge_fw_name = NULL;
284module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR); 284module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR);
285MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name"); 285MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name");
@@ -3427,7 +3427,7 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
3427 } 3427 }
3428 } 3428 }
3429 3429
3430 kparam_block_sysfs_write(myri10ge_fw_name); 3430 kernel_param_lock(THIS_MODULE);
3431 if (myri10ge_fw_name != NULL) { 3431 if (myri10ge_fw_name != NULL) {
3432 char *fw_name = kstrdup(myri10ge_fw_name, GFP_KERNEL); 3432 char *fw_name = kstrdup(myri10ge_fw_name, GFP_KERNEL);
3433 if (fw_name) { 3433 if (fw_name) {
@@ -3435,7 +3435,7 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
3435 set_fw_name(mgp, fw_name, true); 3435 set_fw_name(mgp, fw_name, true);
3436 } 3436 }
3437 } 3437 }
3438 kparam_unblock_sysfs_write(myri10ge_fw_name); 3438 kernel_param_unlock(THIS_MODULE);
3439 3439
3440 if (mgp->board_number < MYRI10GE_MAX_BOARDS && 3440 if (mgp->board_number < MYRI10GE_MAX_BOARDS &&
3441 myri10ge_fw_names[mgp->board_number] != NULL && 3441 myri10ge_fw_names[mgp->board_number] != NULL &&
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c
index 1a20cee5febe..799a2efe5793 100644
--- a/drivers/net/wireless/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/libertas_tf/if_usb.c
@@ -821,15 +821,15 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp)
821 821
822 lbtf_deb_enter(LBTF_DEB_USB); 822 lbtf_deb_enter(LBTF_DEB_USB);
823 823
824 kparam_block_sysfs_write(fw_name); 824 kernel_param_lock(THIS_MODULE);
825 ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev); 825 ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev);
826 if (ret < 0) { 826 if (ret < 0) {
827 pr_err("request_firmware() failed with %#x\n", ret); 827 pr_err("request_firmware() failed with %#x\n", ret);
828 pr_err("firmware %s not found\n", lbtf_fw_name); 828 pr_err("firmware %s not found\n", lbtf_fw_name);
829 kparam_unblock_sysfs_write(fw_name); 829 kernel_param_unlock(THIS_MODULE);
830 goto done; 830 goto done;
831 } 831 }
832 kparam_unblock_sysfs_write(fw_name); 832 kernel_param_unlock(THIS_MODULE);
833 833
834 if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) 834 if (check_fwfile_format(cardp->fw->data, cardp->fw->size))
835 goto release_fw; 835 goto release_fw;
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index 888998a7fe31..a2ae88dbda78 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -1599,7 +1599,7 @@ static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver)
1599 char file_arr[] = "CMVxy.bin"; 1599 char file_arr[] = "CMVxy.bin";
1600 char *file; 1600 char *file;
1601 1601
1602 kparam_block_sysfs_write(cmv_file); 1602 kernel_param_lock(THIS_MODULE);
1603 /* set proper name corresponding modem version and line type */ 1603 /* set proper name corresponding modem version and line type */
1604 if (cmv_file[sc->modem_index] == NULL) { 1604 if (cmv_file[sc->modem_index] == NULL) {
1605 if (UEA_CHIP_VERSION(sc) == ADI930) 1605 if (UEA_CHIP_VERSION(sc) == ADI930)
@@ -1618,7 +1618,7 @@ static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver)
1618 strlcat(cmv_name, file, UEA_FW_NAME_MAX); 1618 strlcat(cmv_name, file, UEA_FW_NAME_MAX);
1619 if (ver == 2) 1619 if (ver == 2)
1620 strlcat(cmv_name, ".v2", UEA_FW_NAME_MAX); 1620 strlcat(cmv_name, ".v2", UEA_FW_NAME_MAX);
1621 kparam_unblock_sysfs_write(cmv_file); 1621 kernel_param_unlock(THIS_MODULE);
1622} 1622}
1623 1623
1624static int request_cmvs_old(struct uea_softc *sc, 1624static int request_cmvs_old(struct uea_softc *sc,
diff --git a/drivers/video/fbdev/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c
index ea7f056ed5fe..8bac309c24b9 100644
--- a/drivers/video/fbdev/vt8623fb.c
+++ b/drivers/video/fbdev/vt8623fb.c
@@ -754,9 +754,9 @@ static int vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
754 754
755 /* Prepare startup mode */ 755 /* Prepare startup mode */
756 756
757 kparam_block_sysfs_write(mode_option); 757 kernel_param_lock(THIS_MODULE);
758 rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8); 758 rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8);
759 kparam_unblock_sysfs_write(mode_option); 759 kernel_param_unlock(THIS_MODULE);
760 if (! ((rc == 1) || (rc == 2))) { 760 if (! ((rc == 1) || (rc == 2))) {
761 rc = -EINVAL; 761 rc = -EINVAL;
762 dev_err(info->device, "mode %s not found\n", mode_option); 762 dev_err(info->device, "mode %s not found\n", mode_option);
diff --git a/include/linux/module.h b/include/linux/module.h
index 4c1b02e1361d..6ba0e87fa804 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -240,6 +240,7 @@ struct module {
240 unsigned int num_syms; 240 unsigned int num_syms;
241 241
242 /* Kernel parameters. */ 242 /* Kernel parameters. */
243 struct mutex param_lock;
243 struct kernel_param *kp; 244 struct kernel_param *kp;
244 unsigned int num_kp; 245 unsigned int num_kp;
245 246
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index ab5031453807..f1fdc50520d8 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -67,6 +67,7 @@ enum {
67 67
68struct kernel_param { 68struct kernel_param {
69 const char *name; 69 const char *name;
70 struct module *mod;
70 const struct kernel_param_ops *ops; 71 const struct kernel_param_ops *ops;
71 const u16 perm; 72 const u16 perm;
72 s8 level; 73 s8 level;
@@ -108,7 +109,7 @@ struct kparam_array
108 * 109 *
109 * @perm is 0 if the the variable is not to appear in sysfs, or 0444 110 * @perm is 0 if the the variable is not to appear in sysfs, or 0444
110 * for world-readable, 0644 for root-writable, etc. Note that if it 111 * for world-readable, 0644 for root-writable, etc. Note that if it
111 * is writable, you may need to use kparam_block_sysfs_write() around 112 * is writable, you may need to use kernel_param_lock() around
112 * accesses (esp. charp, which can be kfreed when it changes). 113 * accesses (esp. charp, which can be kfreed when it changes).
113 * 114 *
114 * The @type is simply pasted to refer to a param_ops_##type and a 115 * The @type is simply pasted to refer to a param_ops_##type and a
@@ -216,12 +217,12 @@ struct kparam_array
216 parameters. */ 217 parameters. */
217#define __module_param_call(prefix, name, ops, arg, perm, level, flags) \ 218#define __module_param_call(prefix, name, ops, arg, perm, level, flags) \
218 /* Default value instead of permissions? */ \ 219 /* Default value instead of permissions? */ \
219 static const char __param_str_##name[] = prefix #name; \ 220 static const char __param_str_##name[] = prefix #name; \
220 static struct kernel_param __moduleparam_const __param_##name \ 221 static struct kernel_param __moduleparam_const __param_##name \
221 __used \ 222 __used \
222 __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ 223 __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
223 = { __param_str_##name, ops, VERIFY_OCTAL_PERMISSIONS(perm), \ 224 = { __param_str_##name, THIS_MODULE, ops, \
224 level, flags, { arg } } 225 VERIFY_OCTAL_PERMISSIONS(perm), level, flags, { arg } }
225 226
226/* Obsolete - use module_param_cb() */ 227/* Obsolete - use module_param_cb() */
227#define module_param_call(name, set, get, arg, perm) \ 228#define module_param_call(name, set, get, arg, perm) \
@@ -238,58 +239,14 @@ __check_old_set_param(int (*oldset)(const char *, struct kernel_param *))
238 return 0; 239 return 0;
239} 240}
240 241
241/**
242 * kparam_block_sysfs_write - make sure a parameter isn't written via sysfs.
243 * @name: the name of the parameter
244 *
245 * There's no point blocking write on a paramter that isn't writable via sysfs!
246 */
247#define kparam_block_sysfs_write(name) \
248 do { \
249 BUG_ON(!(__param_##name.perm & 0222)); \
250 __kernel_param_lock(); \
251 } while (0)
252
253/**
254 * kparam_unblock_sysfs_write - allows sysfs to write to a parameter again.
255 * @name: the name of the parameter
256 */
257#define kparam_unblock_sysfs_write(name) \
258 do { \
259 BUG_ON(!(__param_##name.perm & 0222)); \
260 __kernel_param_unlock(); \
261 } while (0)
262
263/**
264 * kparam_block_sysfs_read - make sure a parameter isn't read via sysfs.
265 * @name: the name of the parameter
266 *
267 * This also blocks sysfs writes.
268 */
269#define kparam_block_sysfs_read(name) \
270 do { \
271 BUG_ON(!(__param_##name.perm & 0444)); \
272 __kernel_param_lock(); \
273 } while (0)
274
275/**
276 * kparam_unblock_sysfs_read - allows sysfs to read a parameter again.
277 * @name: the name of the parameter
278 */
279#define kparam_unblock_sysfs_read(name) \
280 do { \
281 BUG_ON(!(__param_##name.perm & 0444)); \
282 __kernel_param_unlock(); \
283 } while (0)
284
285#ifdef CONFIG_SYSFS 242#ifdef CONFIG_SYSFS
286extern void __kernel_param_lock(void); 243extern void kernel_param_lock(struct module *mod);
287extern void __kernel_param_unlock(void); 244extern void kernel_param_unlock(struct module *mod);
288#else 245#else
289static inline void __kernel_param_lock(void) 246static inline void kernel_param_lock(struct module *mod)
290{ 247{
291} 248}
292static inline void __kernel_param_unlock(void) 249static inline void kernel_param_unlock(struct module *mod)
293{ 250{
294} 251}
295#endif 252#endif
diff --git a/kernel/module.c b/kernel/module.c
index 427b99f1a4b3..8ec33ce202a6 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3442,6 +3442,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
3442 if (err) 3442 if (err)
3443 goto unlink_mod; 3443 goto unlink_mod;
3444 3444
3445 mutex_init(&mod->param_lock);
3446
3445 /* Now we've got everything in the final locations, we can 3447 /* Now we've got everything in the final locations, we can
3446 * find optional sections. */ 3448 * find optional sections. */
3447 err = find_module_sections(mod, info); 3449 err = find_module_sections(mod, info);
diff --git a/kernel/params.c b/kernel/params.c
index a8b09f6c87dc..8890d0b8dffc 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -25,15 +25,20 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/ctype.h> 26#include <linux/ctype.h>
27 27
28/* Protects all parameters, and incidentally kmalloced_param list. */ 28/* Protects all built-in parameters, modules use their own param_lock */
29static DEFINE_MUTEX(param_lock); 29static DEFINE_MUTEX(param_lock);
30 30
31/* 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_IS_LOCKED(mod) mutex_is_locked(KPARAM_MUTEX(mod))
34
31/* This just allows us to keep track of which parameters are kmalloced. */ 35/* This just allows us to keep track of which parameters are kmalloced. */
32struct kmalloced_param { 36struct kmalloced_param {
33 struct list_head list; 37 struct list_head list;
34 char val[]; 38 char val[];
35}; 39};
36static LIST_HEAD(kmalloced_params); 40static LIST_HEAD(kmalloced_params);
41static DEFINE_SPINLOCK(kmalloced_params_lock);
37 42
38static void *kmalloc_parameter(unsigned int size) 43static void *kmalloc_parameter(unsigned int size)
39{ 44{
@@ -43,7 +48,10 @@ static void *kmalloc_parameter(unsigned int size)
43 if (!p) 48 if (!p)
44 return NULL; 49 return NULL;
45 50
51 spin_lock(&kmalloced_params_lock);
46 list_add(&p->list, &kmalloced_params); 52 list_add(&p->list, &kmalloced_params);
53 spin_unlock(&kmalloced_params_lock);
54
47 return p->val; 55 return p->val;
48} 56}
49 57
@@ -52,6 +60,7 @@ static void maybe_kfree_parameter(void *param)
52{ 60{
53 struct kmalloced_param *p; 61 struct kmalloced_param *p;
54 62
63 spin_lock(&kmalloced_params_lock);
55 list_for_each_entry(p, &kmalloced_params, list) { 64 list_for_each_entry(p, &kmalloced_params, list) {
56 if (p->val == param) { 65 if (p->val == param) {
57 list_del(&p->list); 66 list_del(&p->list);
@@ -59,6 +68,7 @@ static void maybe_kfree_parameter(void *param)
59 break; 68 break;
60 } 69 }
61 } 70 }
71 spin_unlock(&kmalloced_params_lock);
62} 72}
63 73
64static char dash2underscore(char c) 74static char dash2underscore(char c)
@@ -118,10 +128,10 @@ static int parse_one(char *param,
118 return -EINVAL; 128 return -EINVAL;
119 pr_debug("handling %s with %p\n", param, 129 pr_debug("handling %s with %p\n", param,
120 params[i].ops->set); 130 params[i].ops->set);
121 mutex_lock(&param_lock); 131 kernel_param_lock(params[i].mod);
122 param_check_unsafe(&params[i]); 132 param_check_unsafe(&params[i]);
123 err = params[i].ops->set(val, &params[i]); 133 err = params[i].ops->set(val, &params[i]);
124 mutex_unlock(&param_lock); 134 kernel_param_unlock(params[i].mod);
125 return err; 135 return err;
126 } 136 }
127 } 137 }
@@ -417,7 +427,8 @@ const struct kernel_param_ops param_ops_bint = {
417EXPORT_SYMBOL(param_ops_bint); 427EXPORT_SYMBOL(param_ops_bint);
418 428
419/* We break the rule and mangle the string. */ 429/* We break the rule and mangle the string. */
420static int param_array(const char *name, 430static int param_array(struct module *mod,
431 const char *name,
421 const char *val, 432 const char *val,
422 unsigned int min, unsigned int max, 433 unsigned int min, unsigned int max,
423 void *elem, int elemsize, 434 void *elem, int elemsize,
@@ -448,7 +459,7 @@ static int param_array(const char *name,
448 /* nul-terminate and parse */ 459 /* nul-terminate and parse */
449 save = val[len]; 460 save = val[len];
450 ((char *)val)[len] = '\0'; 461 ((char *)val)[len] = '\0';
451 BUG_ON(!mutex_is_locked(&param_lock)); 462 BUG_ON(!KPARAM_IS_LOCKED(mod));
452 ret = set(val, &kp); 463 ret = set(val, &kp);
453 464
454 if (ret != 0) 465 if (ret != 0)
@@ -470,7 +481,7 @@ static int param_array_set(const char *val, const struct kernel_param *kp)
470 const struct kparam_array *arr = kp->arr; 481 const struct kparam_array *arr = kp->arr;
471 unsigned int temp_num; 482 unsigned int temp_num;
472 483
473 return param_array(kp->name, val, 1, arr->max, arr->elem, 484 return param_array(kp->mod, kp->name, val, 1, arr->max, arr->elem,
474 arr->elemsize, arr->ops->set, kp->level, 485 arr->elemsize, arr->ops->set, kp->level,
475 arr->num ?: &temp_num); 486 arr->num ?: &temp_num);
476} 487}
@@ -485,7 +496,7 @@ static int param_array_get(char *buffer, const struct kernel_param *kp)
485 if (i) 496 if (i)
486 buffer[off++] = ','; 497 buffer[off++] = ',';
487 p.arg = arr->elem + arr->elemsize * i; 498 p.arg = arr->elem + arr->elemsize * i;
488 BUG_ON(!mutex_is_locked(&param_lock)); 499 BUG_ON(!KPARAM_IS_LOCKED(p.mod));
489 ret = arr->ops->get(buffer + off, &p); 500 ret = arr->ops->get(buffer + off, &p);
490 if (ret < 0) 501 if (ret < 0)
491 return ret; 502 return ret;
@@ -568,9 +579,9 @@ static ssize_t param_attr_show(struct module_attribute *mattr,
568 if (!attribute->param->ops->get) 579 if (!attribute->param->ops->get)
569 return -EPERM; 580 return -EPERM;
570 581
571 mutex_lock(&param_lock); 582 kernel_param_lock(mk->mod);
572 count = attribute->param->ops->get(buf, attribute->param); 583 count = attribute->param->ops->get(buf, attribute->param);
573 mutex_unlock(&param_lock); 584 kernel_param_unlock(mk->mod);
574 if (count > 0) { 585 if (count > 0) {
575 strcat(buf, "\n"); 586 strcat(buf, "\n");
576 ++count; 587 ++count;
@@ -580,7 +591,7 @@ static ssize_t param_attr_show(struct module_attribute *mattr,
580 591
581/* sysfs always hands a nul-terminated string in buf. We rely on that. */ 592/* sysfs always hands a nul-terminated string in buf. We rely on that. */
582static ssize_t param_attr_store(struct module_attribute *mattr, 593static ssize_t param_attr_store(struct module_attribute *mattr,
583 struct module_kobject *km, 594 struct module_kobject *mk,
584 const char *buf, size_t len) 595 const char *buf, size_t len)
585{ 596{
586 int err; 597 int err;
@@ -589,10 +600,10 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
589 if (!attribute->param->ops->set) 600 if (!attribute->param->ops->set)
590 return -EPERM; 601 return -EPERM;
591 602
592 mutex_lock(&param_lock); 603 kernel_param_lock(mk->mod);
593 param_check_unsafe(attribute->param); 604 param_check_unsafe(attribute->param);
594 err = attribute->param->ops->set(buf, attribute->param); 605 err = attribute->param->ops->set(buf, attribute->param);
595 mutex_unlock(&param_lock); 606 kernel_param_unlock(mk->mod);
596 if (!err) 607 if (!err)
597 return len; 608 return len;
598 return err; 609 return err;
@@ -605,18 +616,19 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
605#define __modinit __init 616#define __modinit __init
606#endif 617#endif
607 618
608#ifdef CONFIG_SYSFS 619void kernel_param_lock(struct module *mod)
609void __kernel_param_lock(void)
610{ 620{
611 mutex_lock(&param_lock); 621 mutex_lock(KPARAM_MUTEX(mod));
612} 622}
613EXPORT_SYMBOL(__kernel_param_lock);
614 623
615void __kernel_param_unlock(void) 624void kernel_param_unlock(struct module *mod)
616{ 625{
617 mutex_unlock(&param_lock); 626 mutex_unlock(KPARAM_MUTEX(mod));
618} 627}
619EXPORT_SYMBOL(__kernel_param_unlock); 628
629#ifdef CONFIG_SYSFS
630EXPORT_SYMBOL(kernel_param_lock);
631EXPORT_SYMBOL(kernel_param_unlock);
620 632
621/* 633/*
622 * add_sysfs_param - add a parameter to sysfs 634 * add_sysfs_param - add a parameter to sysfs
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index d53355b011f5..8544e2eb570e 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -103,7 +103,7 @@ ieee80211_rate_control_ops_get(const char *name)
103 const struct rate_control_ops *ops; 103 const struct rate_control_ops *ops;
104 const char *alg_name; 104 const char *alg_name;
105 105
106 kparam_block_sysfs_write(ieee80211_default_rc_algo); 106 kernel_param_lock(THIS_MODULE);
107 if (!name) 107 if (!name)
108 alg_name = ieee80211_default_rc_algo; 108 alg_name = ieee80211_default_rc_algo;
109 else 109 else
@@ -117,7 +117,7 @@ ieee80211_rate_control_ops_get(const char *name)
117 /* try built-in one if specific alg requested but not found */ 117 /* try built-in one if specific alg requested but not found */
118 if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT)) 118 if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT))
119 ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT); 119 ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT);
120 kparam_unblock_sysfs_write(ieee80211_default_rc_algo); 120 kernel_param_unlock(THIS_MODULE);
121 121
122 return ops; 122 return ops;
123} 123}