aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/module.h1
-rw-r--r--kernel/module.c77
-rw-r--r--kernel/params.c10
3 files changed, 32 insertions, 56 deletions
diff --git a/include/linux/module.h b/include/linux/module.h
index a25d5f61548c..70bd843c71cb 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -245,6 +245,7 @@ struct module
245 /* Sysfs stuff. */ 245 /* Sysfs stuff. */
246 struct module_kobject mkobj; 246 struct module_kobject mkobj;
247 struct module_param_attrs *param_attrs; 247 struct module_param_attrs *param_attrs;
248 struct module_attribute *modinfo_attrs;
248 const char *version; 249 const char *version;
249 const char *srcversion; 250 const char *srcversion;
250 251
diff --git a/kernel/module.c b/kernel/module.c
index 5ca99fbe9f44..77764f22f021 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -429,7 +429,6 @@ static inline void percpu_modcopy(void *pcpudst, const void *src,
429} 429}
430#endif /* CONFIG_SMP */ 430#endif /* CONFIG_SMP */
431 431
432#ifdef CONFIG_MODULE_UNLOAD
433#define MODINFO_ATTR(field) \ 432#define MODINFO_ATTR(field) \
434static void setup_modinfo_##field(struct module *mod, const char *s) \ 433static void setup_modinfo_##field(struct module *mod, const char *s) \
435{ \ 434{ \
@@ -461,12 +460,7 @@ static struct module_attribute modinfo_##field = { \
461MODINFO_ATTR(version); 460MODINFO_ATTR(version);
462MODINFO_ATTR(srcversion); 461MODINFO_ATTR(srcversion);
463 462
464static struct module_attribute *modinfo_attrs[] = { 463#ifdef CONFIG_MODULE_UNLOAD
465 &modinfo_version,
466 &modinfo_srcversion,
467 NULL,
468};
469
470/* Init the unload section of the module. */ 464/* Init the unload section of the module. */
471static void module_unload_init(struct module *mod) 465static void module_unload_init(struct module *mod)
472{ 466{
@@ -781,6 +775,15 @@ static inline void module_unload_init(struct module *mod)
781} 775}
782#endif /* CONFIG_MODULE_UNLOAD */ 776#endif /* CONFIG_MODULE_UNLOAD */
783 777
778static struct module_attribute *modinfo_attrs[] = {
779 &modinfo_version,
780 &modinfo_srcversion,
781#ifdef CONFIG_MODULE_UNLOAD
782 &refcnt,
783#endif
784 NULL,
785};
786
784#ifdef CONFIG_OBSOLETE_MODPARM 787#ifdef CONFIG_OBSOLETE_MODPARM
785/* Bounds checking done below */ 788/* Bounds checking done below */
786static int obsparm_copy_string(const char *val, struct kernel_param *kp) 789static int obsparm_copy_string(const char *val, struct kernel_param *kp)
@@ -1106,37 +1109,28 @@ static inline void remove_sect_attrs(struct module *mod)
1106} 1109}
1107#endif /* CONFIG_KALLSYMS */ 1110#endif /* CONFIG_KALLSYMS */
1108 1111
1109
1110#ifdef CONFIG_MODULE_UNLOAD
1111static inline int module_add_refcnt_attr(struct module *mod)
1112{
1113 return sysfs_create_file(&mod->mkobj.kobj, &refcnt.attr);
1114}
1115static void module_remove_refcnt_attr(struct module *mod)
1116{
1117 return sysfs_remove_file(&mod->mkobj.kobj, &refcnt.attr);
1118}
1119#else
1120static inline int module_add_refcnt_attr(struct module *mod)
1121{
1122 return 0;
1123}
1124static void module_remove_refcnt_attr(struct module *mod)
1125{
1126}
1127#endif
1128
1129#ifdef CONFIG_MODULE_UNLOAD
1130static int module_add_modinfo_attrs(struct module *mod) 1112static int module_add_modinfo_attrs(struct module *mod)
1131{ 1113{
1132 struct module_attribute *attr; 1114 struct module_attribute *attr;
1115 struct module_attribute *temp_attr;
1133 int error = 0; 1116 int error = 0;
1134 int i; 1117 int i;
1135 1118
1119 mod->modinfo_attrs = kzalloc((sizeof(struct module_attribute) *
1120 (ARRAY_SIZE(modinfo_attrs) + 1)),
1121 GFP_KERNEL);
1122 if (!mod->modinfo_attrs)
1123 return -ENOMEM;
1124
1125 temp_attr = mod->modinfo_attrs;
1136 for (i = 0; (attr = modinfo_attrs[i]) && !error; i++) { 1126 for (i = 0; (attr = modinfo_attrs[i]) && !error; i++) {
1137 if (!attr->test || 1127 if (!attr->test ||
1138 (attr->test && attr->test(mod))) 1128 (attr->test && attr->test(mod))) {
1139 error = sysfs_create_file(&mod->mkobj.kobj,&attr->attr); 1129 memcpy(temp_attr, attr, sizeof(*temp_attr));
1130 temp_attr->attr.owner = mod;
1131 error = sysfs_create_file(&mod->mkobj.kobj,&temp_attr->attr);
1132 ++temp_attr;
1133 }
1140 } 1134 }
1141 return error; 1135 return error;
1142} 1136}
@@ -1146,12 +1140,16 @@ static void module_remove_modinfo_attrs(struct module *mod)
1146 struct module_attribute *attr; 1140 struct module_attribute *attr;
1147 int i; 1141 int i;
1148 1142
1149 for (i = 0; (attr = modinfo_attrs[i]); i++) { 1143 for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) {
1144 /* pick a field to test for end of list */
1145 if (!attr->attr.name)
1146 break;
1150 sysfs_remove_file(&mod->mkobj.kobj,&attr->attr); 1147 sysfs_remove_file(&mod->mkobj.kobj,&attr->attr);
1151 attr->free(mod); 1148 if (attr->free)
1149 attr->free(mod);
1152 } 1150 }
1151 kfree(mod->modinfo_attrs);
1153} 1152}
1154#endif
1155 1153
1156static int mod_sysfs_setup(struct module *mod, 1154static int mod_sysfs_setup(struct module *mod,
1157 struct kernel_param *kparam, 1155 struct kernel_param *kparam,
@@ -1169,19 +1167,13 @@ static int mod_sysfs_setup(struct module *mod,
1169 if (err) 1167 if (err)
1170 goto out; 1168 goto out;
1171 1169
1172 err = module_add_refcnt_attr(mod);
1173 if (err)
1174 goto out_unreg;
1175
1176 err = module_param_sysfs_setup(mod, kparam, num_params); 1170 err = module_param_sysfs_setup(mod, kparam, num_params);
1177 if (err) 1171 if (err)
1178 goto out_unreg; 1172 goto out_unreg;
1179 1173
1180#ifdef CONFIG_MODULE_UNLOAD
1181 err = module_add_modinfo_attrs(mod); 1174 err = module_add_modinfo_attrs(mod);
1182 if (err) 1175 if (err)
1183 goto out_unreg; 1176 goto out_unreg;
1184#endif
1185 1177
1186 return 0; 1178 return 0;
1187 1179
@@ -1193,10 +1185,7 @@ out:
1193 1185
1194static void mod_kobject_remove(struct module *mod) 1186static void mod_kobject_remove(struct module *mod)
1195{ 1187{
1196#ifdef CONFIG_MODULE_UNLOAD
1197 module_remove_modinfo_attrs(mod); 1188 module_remove_modinfo_attrs(mod);
1198#endif
1199 module_remove_refcnt_attr(mod);
1200 module_param_sysfs_remove(mod); 1189 module_param_sysfs_remove(mod);
1201 1190
1202 kobject_unregister(&mod->mkobj.kobj); 1191 kobject_unregister(&mod->mkobj.kobj);
@@ -1474,7 +1463,6 @@ static char *get_modinfo(Elf_Shdr *sechdrs,
1474 return NULL; 1463 return NULL;
1475} 1464}
1476 1465
1477#ifdef CONFIG_MODULE_UNLOAD
1478static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs, 1466static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
1479 unsigned int infoindex) 1467 unsigned int infoindex)
1480{ 1468{
@@ -1489,7 +1477,6 @@ static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
1489 attr->attr.name)); 1477 attr->attr.name));
1490 } 1478 }
1491} 1479}
1492#endif
1493 1480
1494#ifdef CONFIG_KALLSYMS 1481#ifdef CONFIG_KALLSYMS
1495int is_exported(const char *name, const struct module *mod) 1482int is_exported(const char *name, const struct module *mod)
@@ -1803,10 +1790,8 @@ static struct module *load_module(void __user *umod,
1803 if (strcmp(mod->name, "driverloader") == 0) 1790 if (strcmp(mod->name, "driverloader") == 0)
1804 add_taint(TAINT_PROPRIETARY_MODULE); 1791 add_taint(TAINT_PROPRIETARY_MODULE);
1805 1792
1806#ifdef CONFIG_MODULE_UNLOAD
1807 /* Set up MODINFO_ATTR fields */ 1793 /* Set up MODINFO_ATTR fields */
1808 setup_modinfo(mod, sechdrs, infoindex); 1794 setup_modinfo(mod, sechdrs, infoindex);
1809#endif
1810 1795
1811 /* Fix up syms, so that st_value is a pointer to location. */ 1796 /* Fix up syms, so that st_value is a pointer to location. */
1812 err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex, 1797 err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
diff --git a/kernel/params.c b/kernel/params.c
index c76ad25e6a21..a29150582310 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -638,13 +638,8 @@ static ssize_t module_attr_show(struct kobject *kobj,
638 if (!attribute->show) 638 if (!attribute->show)
639 return -EIO; 639 return -EIO;
640 640
641 if (!try_module_get(mk->mod))
642 return -ENODEV;
643
644 ret = attribute->show(attribute, mk->mod, buf); 641 ret = attribute->show(attribute, mk->mod, buf);
645 642
646 module_put(mk->mod);
647
648 return ret; 643 return ret;
649} 644}
650 645
@@ -662,13 +657,8 @@ static ssize_t module_attr_store(struct kobject *kobj,
662 if (!attribute->store) 657 if (!attribute->store)
663 return -EIO; 658 return -EIO;
664 659
665 if (!try_module_get(mk->mod))
666 return -ENODEV;
667
668 ret = attribute->store(attribute, mk->mod, buf, len); 660 ret = attribute->store(attribute, mk->mod, buf, len);
669 661
670 module_put(mk->mod);
671
672 return ret; 662 return ret;
673} 663}
674 664