aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c77
1 files changed, 31 insertions, 46 deletions
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,