diff options
-rw-r--r-- | arch/um/drivers/hostaudio_kern.c | 20 | ||||
-rw-r--r-- | drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/libertas_tf/if_usb.c | 6 | ||||
-rw-r--r-- | drivers/usb/atm/ueagle-atm.c | 4 | ||||
-rw-r--r-- | drivers/video/fbdev/vt8623fb.c | 4 | ||||
-rw-r--r-- | include/linux/module.h | 1 | ||||
-rw-r--r-- | include/linux/moduleparam.h | 61 | ||||
-rw-r--r-- | kernel/module.c | 2 | ||||
-rw-r--r-- | kernel/params.c | 50 | ||||
-rw-r--r-- | net/mac80211/rate.c | 4 |
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 | ||
327 | static int __init hostaudio_init_module(void) | 327 | static 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"); | |||
279 | MODULE_FIRMWARE("myri10ge_rss_ethp_z8e.dat"); | 279 | MODULE_FIRMWARE("myri10ge_rss_ethp_z8e.dat"); |
280 | MODULE_FIRMWARE("myri10ge_rss_eth_z8e.dat"); | 280 | MODULE_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() */ |
283 | static char *myri10ge_fw_name = NULL; | 283 | static char *myri10ge_fw_name = NULL; |
284 | module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR); | 284 | module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR); |
285 | MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name"); | 285 | MODULE_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 | ||
1624 | static int request_cmvs_old(struct uea_softc *sc, | 1624 | static 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 | ||
68 | struct kernel_param { | 68 | struct 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 |
286 | extern void __kernel_param_lock(void); | 243 | extern void kernel_param_lock(struct module *mod); |
287 | extern void __kernel_param_unlock(void); | 244 | extern void kernel_param_unlock(struct module *mod); |
288 | #else | 245 | #else |
289 | static inline void __kernel_param_lock(void) | 246 | static inline void kernel_param_lock(struct module *mod) |
290 | { | 247 | { |
291 | } | 248 | } |
292 | static inline void __kernel_param_unlock(void) | 249 | static 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 */ |
29 | static DEFINE_MUTEX(param_lock); | 29 | static 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 : ¶m_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. */ |
32 | struct kmalloced_param { | 36 | struct kmalloced_param { |
33 | struct list_head list; | 37 | struct list_head list; |
34 | char val[]; | 38 | char val[]; |
35 | }; | 39 | }; |
36 | static LIST_HEAD(kmalloced_params); | 40 | static LIST_HEAD(kmalloced_params); |
41 | static DEFINE_SPINLOCK(kmalloced_params_lock); | ||
37 | 42 | ||
38 | static void *kmalloc_parameter(unsigned int size) | 43 | static 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 | ||
64 | static char dash2underscore(char c) | 74 | static 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(¶m_lock); | 131 | kernel_param_lock(params[i].mod); |
122 | param_check_unsafe(¶ms[i]); | 132 | param_check_unsafe(¶ms[i]); |
123 | err = params[i].ops->set(val, ¶ms[i]); | 133 | err = params[i].ops->set(val, ¶ms[i]); |
124 | mutex_unlock(¶m_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 = { | |||
417 | EXPORT_SYMBOL(param_ops_bint); | 427 | EXPORT_SYMBOL(param_ops_bint); |
418 | 428 | ||
419 | /* We break the rule and mangle the string. */ | 429 | /* We break the rule and mangle the string. */ |
420 | static int param_array(const char *name, | 430 | static 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(¶m_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(¶m_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(¶m_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(¶m_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. */ |
582 | static ssize_t param_attr_store(struct module_attribute *mattr, | 593 | static 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(¶m_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(¶m_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 | 619 | void kernel_param_lock(struct module *mod) |
609 | void __kernel_param_lock(void) | ||
610 | { | 620 | { |
611 | mutex_lock(¶m_lock); | 621 | mutex_lock(KPARAM_MUTEX(mod)); |
612 | } | 622 | } |
613 | EXPORT_SYMBOL(__kernel_param_lock); | ||
614 | 623 | ||
615 | void __kernel_param_unlock(void) | 624 | void kernel_param_unlock(struct module *mod) |
616 | { | 625 | { |
617 | mutex_unlock(¶m_lock); | 626 | mutex_unlock(KPARAM_MUTEX(mod)); |
618 | } | 627 | } |
619 | EXPORT_SYMBOL(__kernel_param_unlock); | 628 | |
629 | #ifdef CONFIG_SYSFS | ||
630 | EXPORT_SYMBOL(kernel_param_lock); | ||
631 | EXPORT_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 | } |