History

module: Move sysfs support into a separate file

No functional change. This patch migrates module sysfs support out of core code into kernel/module/sysfs.c. In addition simple code refactoring to make this possible.

Aaron Tomlin committed 4 years ago

Commit 44c09531 parent 0ffc40f4 files · +461 −466Browse files

Unified · Split

4 files
  1. kernel/module/Makefile +1 −0
  2. kernel/module/internal.h +21 −0
  3. kernel/module/main.c +3 −466
  4. kernel/module/sysfs.c +436 −0
kernel/module/Makefile+1−0
@@ -16,3 +16,4 @@ obj-$(CONFIG_STRICT_MODULE_RWX) += strict_rwx.o · 15 unmodified lines
1616 obj-$(CONFIG_DEBUG_KMEMLEAK) += debug_kmemleak.o
1717 obj-$(CONFIG_KALLSYMS) += kallsyms.o
1818 obj-$(CONFIG_PROC_FS) += procfs.o
19+obj-$(CONFIG_SYSFS) += sysfs.o
kernel/module/internal.h+21−0
@@ -34,6 +34,9 @@ · 33 unmodified lines
3434 extern struct mutex module_mutex;
3535 extern struct list_head modules;
3636
37+extern struct module_attribute *modinfo_attrs[];
38+extern size_t modinfo_attrs_count;
39+
3740 /* Provided by the linker */
3841 extern const struct kernel_symbol __start___ksymtab[];
3942 extern const struct kernel_symbol __stop___ksymtab[];
@@ -204,3 +207,21 @@ static inline void init_build_id(struct module *mod, const struct load_info *inf · 164 unmodified lines
204207 static inline void layout_symtab(struct module *mod, struct load_info *info) { }
205208 static inline void add_kallsyms(struct module *mod, const struct load_info *info) { }
206209 #endif /* CONFIG_KALLSYMS */
210+
211+#ifdef CONFIG_SYSFS
212+int mod_sysfs_setup(struct module *mod, const struct load_info *info,
213+ struct kernel_param *kparam, unsigned int num_params);
214+void mod_sysfs_teardown(struct module *mod);
215+void init_param_lock(struct module *mod);
216+#else /* !CONFIG_SYSFS */
217+static inline int mod_sysfs_setup(struct module *mod,
218+ const struct load_info *info,
219+ struct kernel_param *kparam,
220+ unsigned int num_params)
221+{
222+ return 0;
223+}
224+
225+static inline void mod_sysfs_teardown(struct module *mod) { }
226+static inline void init_param_lock(struct module *mod) { }
227+#endif /* CONFIG_SYSFS */
kernel/module/main.c+3−466
@@ -14,9 +14,7 @@ · 13 unmodified lines
1414 #include <linux/init.h>
1515 #include <linux/kallsyms.h>
1616 #include <linux/buildid.h>
17−#include <linux/file.h>
1817 #include <linux/fs.h>
19−#include <linux/sysfs.h>
2018 #include <linux/kernel.h>
2119 #include <linux/kernel_read_file.h>
2220 #include <linux/slab.h>
@@ -989,7 +987,7 @@ static ssize_t show_taint(struct module_attribute *mattr, · 966 unmodified lines
989987 static struct module_attribute modinfo_taint =
990988 __ATTR(taint, 0444, show_taint, NULL);
991989
992−static struct module_attribute *modinfo_attrs[] = {
990+struct module_attribute *modinfo_attrs[] = {
993991 &module_uevent,
994992 &modinfo_version,
995993 &modinfo_srcversion,
@@ -1003,6 +1001,8 @@ static struct module_attribute *modinfo_attrs[] = { · 7 unmodified lines
10031001 NULL,
10041002 };
10051003
1004+size_t modinfo_attrs_count = ARRAY_SIZE(modinfo_attrs);
1005+
10061006 static const char vermagic[] = VERMAGIC_STRING;
10071007
10081008 static int try_to_force_load(struct module *mod, const char *reason)
@@ -1253,469 +1253,6 @@ resolve_symbol_wait(struct module *mod, · 244 unmodified lines
12531253 return ksym;
12541254 }
12551255
1256−/*
1257− * /sys/module/foo/sections stuff
1258− * J. Corbet <corbet@lwn.net>
1259− */
1260−#ifdef CONFIG_SYSFS
1261−
1262−#ifdef CONFIG_KALLSYMS
1263−struct module_sect_attr {
1264− struct bin_attribute battr;
1265− unsigned long address;
1266−};
1267−
1268−struct module_sect_attrs {
1269− struct attribute_group grp;
1270− unsigned int nsections;
1271− struct module_sect_attr attrs[];
1272−};
1273−
1274−#define MODULE_SECT_READ_SIZE (3 /* "0x", "\n" */ + (BITS_PER_LONG / 4))
1275−static ssize_t module_sect_read(struct file *file, struct kobject *kobj,
1276− struct bin_attribute *battr,
1277− char *buf, loff_t pos, size_t count)
1278−{
1279− struct module_sect_attr *sattr =
1280− container_of(battr, struct module_sect_attr, battr);
1281− char bounce[MODULE_SECT_READ_SIZE + 1];
1282− size_t wrote;
1283−
1284− if (pos != 0)
1285− return -EINVAL;
1286−
1287− /*
1288− * Since we're a binary read handler, we must account for the
1289− * trailing NUL byte that sprintf will write: if "buf" is
1290− * too small to hold the NUL, or the NUL is exactly the last
1291− * byte, the read will look like it got truncated by one byte.
1292− * Since there is no way to ask sprintf nicely to not write
1293− * the NUL, we have to use a bounce buffer.
1294− */
1295− wrote = scnprintf(bounce, sizeof(bounce), "0x%px\n",
1296− kallsyms_show_value(file->f_cred)
1297− ? (void *)sattr->address : NULL);
1298− count = min(count, wrote);
1299− memcpy(buf, bounce, count);
1300−
1301− return count;
1302−}
1303−
1304−static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
1305−{
1306− unsigned int section;
1307−
1308− for (section = 0; section < sect_attrs->nsections; section++)
1309− kfree(sect_attrs->attrs[section].battr.attr.name);
1310− kfree(sect_attrs);
1311−}
1312−
1313−static void add_sect_attrs(struct module *mod, const struct load_info *info)
1314−{
1315− unsigned int nloaded = 0, i, size[2];
1316− struct module_sect_attrs *sect_attrs;
1317− struct module_sect_attr *sattr;
1318− struct bin_attribute **gattr;
1319−
1320− /* Count loaded sections and allocate structures */
1321− for (i = 0; i < info->hdr->e_shnum; i++)
1322− if (!sect_empty(&info->sechdrs[i]))
1323− nloaded++;
1324− size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded),
1325− sizeof(sect_attrs->grp.bin_attrs[0]));
1326− size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);
1327− sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
1328− if (sect_attrs == NULL)
1329− return;
1330−
1331− /* Setup section attributes. */
1332− sect_attrs->grp.name = "sections";
1333− sect_attrs->grp.bin_attrs = (void *)sect_attrs + size[0];
1334−
1335− sect_attrs->nsections = 0;
1336− sattr = &sect_attrs->attrs[0];
1337− gattr = &sect_attrs->grp.bin_attrs[0];
1338− for (i = 0; i < info->hdr->e_shnum; i++) {
1339− Elf_Shdr *sec = &info->sechdrs[i];
1340− if (sect_empty(sec))
1341− continue;
1342− sysfs_bin_attr_init(&sattr->battr);
1343− sattr->address = sec->sh_addr;
1344− sattr->battr.attr.name =
1345− kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL);
1346− if (sattr->battr.attr.name == NULL)
1347− goto out;
1348− sect_attrs->nsections++;
1349− sattr->battr.read = module_sect_read;
1350− sattr->battr.size = MODULE_SECT_READ_SIZE;
1351− sattr->battr.attr.mode = 0400;
1352− *(gattr++) = &(sattr++)->battr;
1353− }
1354− *gattr = NULL;
1355−
1356− if (sysfs_create_group(&mod->mkobj.kobj, &sect_attrs->grp))
1357− goto out;
1358−
1359− mod->sect_attrs = sect_attrs;
1360− return;
1361− out:
1362− free_sect_attrs(sect_attrs);
1363−}
1364−
1365−static void remove_sect_attrs(struct module *mod)
1366−{
1367− if (mod->sect_attrs) {
1368− sysfs_remove_group(&mod->mkobj.kobj,
1369− &mod->sect_attrs->grp);
1370− /*
1371− * We are positive that no one is using any sect attrs
1372− * at this point. Deallocate immediately.
1373− */
1374− free_sect_attrs(mod->sect_attrs);
1375− mod->sect_attrs = NULL;
1376− }
1377−}
1378−
1379−/*
1380− * /sys/module/foo/notes/.section.name gives contents of SHT_NOTE sections.
1381− */
1382−
1383−struct module_notes_attrs {
1384− struct kobject *dir;
1385− unsigned int notes;
1386− struct bin_attribute attrs[];
1387−};
1388−
1389−static ssize_t module_notes_read(struct file *filp, struct kobject *kobj,
1390− struct bin_attribute *bin_attr,
1391− char *buf, loff_t pos, size_t count)
1392−{
1393− /*
1394− * The caller checked the pos and count against our size.
1395− */
1396− memcpy(buf, bin_attr->private + pos, count);
1397− return count;
1398−}
1399−
1400−static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
1401− unsigned int i)
1402−{
1403− if (notes_attrs->dir) {
1404− while (i-- > 0)
1405− sysfs_remove_bin_file(notes_attrs->dir,
1406− &notes_attrs->attrs[i]);
1407− kobject_put(notes_attrs->dir);
1408− }
1409− kfree(notes_attrs);
1410−}
1411−
1412−static void add_notes_attrs(struct module *mod, const struct load_info *info)
1413−{
1414− unsigned int notes, loaded, i;
1415− struct module_notes_attrs *notes_attrs;
1416− struct bin_attribute *nattr;
1417−
1418− /* failed to create section attributes, so can't create notes */
1419− if (!mod->sect_attrs)
1420− return;
1421−
1422− /* Count notes sections and allocate structures. */
1423− notes = 0;
1424− for (i = 0; i < info->hdr->e_shnum; i++)
1425− if (!sect_empty(&info->sechdrs[i]) &&
1426− (info->sechdrs[i].sh_type == SHT_NOTE))
1427− ++notes;
1428−
1429− if (notes == 0)
1430− return;
1431−
1432− notes_attrs = kzalloc(struct_size(notes_attrs, attrs, notes),
1433− GFP_KERNEL);
1434− if (notes_attrs == NULL)
1435− return;
1436−
1437− notes_attrs->notes = notes;
1438− nattr = &notes_attrs->attrs[0];
1439− for (loaded = i = 0; i < info->hdr->e_shnum; ++i) {
1440− if (sect_empty(&info->sechdrs[i]))
1441− continue;
1442− if (info->sechdrs[i].sh_type == SHT_NOTE) {
1443− sysfs_bin_attr_init(nattr);
1444− nattr->attr.name = mod->sect_attrs->attrs[loaded].battr.attr.name;
1445− nattr->attr.mode = S_IRUGO;
1446− nattr->size = info->sechdrs[i].sh_size;
1447− nattr->private = (void *) info->sechdrs[i].sh_addr;
1448− nattr->read = module_notes_read;
1449− ++nattr;
1450− }
1451− ++loaded;
1452− }
1453−
1454− notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj);
1455− if (!notes_attrs->dir)
1456− goto out;
1457−
1458− for (i = 0; i < notes; ++i)
1459− if (sysfs_create_bin_file(notes_attrs->dir,
1460− &notes_attrs->attrs[i]))
1461− goto out;
1462−
1463− mod->notes_attrs = notes_attrs;
1464− return;
1465−
1466− out:
1467− free_notes_attrs(notes_attrs, i);
1468−}
1469−
1470−static void remove_notes_attrs(struct module *mod)
1471−{
1472− if (mod->notes_attrs)
1473− free_notes_attrs(mod->notes_attrs, mod->notes_attrs->notes);
1474−}
1475−
1476−#else
1477−
1478−static inline void add_sect_attrs(struct module *mod,
1479− const struct load_info *info)
1480−{
1481−}
1482−
1483−static inline void remove_sect_attrs(struct module *mod)
1484−{
1485−}
1486−
1487−static inline void add_notes_attrs(struct module *mod,
1488− const struct load_info *info)
1489−{
1490−}
1491−
1492−static inline void remove_notes_attrs(struct module *mod)
1493−{
1494−}
1495−#endif /* CONFIG_KALLSYMS */
1496−
1497−static void del_usage_links(struct module *mod)
1498−{
1499−#ifdef CONFIG_MODULE_UNLOAD
1500− struct module_use *use;
1501−
1502− mutex_lock(&module_mutex);
1503− list_for_each_entry(use, &mod->target_list, target_list)
1504− sysfs_remove_link(use->target->holders_dir, mod->name);
1505− mutex_unlock(&module_mutex);
1506−#endif
1507−}
1508−
1509−static int add_usage_links(struct module *mod)
1510−{
1511− int ret = 0;
1512−#ifdef CONFIG_MODULE_UNLOAD
1513− struct module_use *use;
1514−
1515− mutex_lock(&module_mutex);
1516− list_for_each_entry(use, &mod->target_list, target_list) {
1517− ret = sysfs_create_link(use->target->holders_dir,
1518− &mod->mkobj.kobj, mod->name);
1519− if (ret)
1520− break;
1521− }
1522− mutex_unlock(&module_mutex);
1523− if (ret)
1524− del_usage_links(mod);
1525−#endif
1526− return ret;
1527−}
1528−
1529−static void module_remove_modinfo_attrs(struct module *mod, int end);
1530−
1531−static int module_add_modinfo_attrs(struct module *mod)
1532−{
1533− struct module_attribute *attr;
1534− struct module_attribute *temp_attr;
1535− int error = 0;
1536− int i;
1537−
1538− mod->modinfo_attrs = kzalloc((sizeof(struct module_attribute) *
1539− (ARRAY_SIZE(modinfo_attrs) + 1)),
1540− GFP_KERNEL);
1541− if (!mod->modinfo_attrs)
1542− return -ENOMEM;
1543−
1544− temp_attr = mod->modinfo_attrs;
1545− for (i = 0; (attr = modinfo_attrs[i]); i++) {
1546− if (!attr->test || attr->test(mod)) {
1547− memcpy(temp_attr, attr, sizeof(*temp_attr));
1548− sysfs_attr_init(&temp_attr->attr);
1549− error = sysfs_create_file(&mod->mkobj.kobj,
1550− &temp_attr->attr);
1551− if (error)
1552− goto error_out;
1553− ++temp_attr;
1554− }
1555− }
1556−
1557− return 0;
1558−
1559−error_out:
1560− if (i > 0)
1561− module_remove_modinfo_attrs(mod, --i);
1562− else
1563− kfree(mod->modinfo_attrs);
1564− return error;
1565−}
1566−
1567−static void module_remove_modinfo_attrs(struct module *mod, int end)
1568−{
1569− struct module_attribute *attr;
1570− int i;
1571−
1572− for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) {
1573− if (end >= 0 && i > end)
1574− break;
1575− /* pick a field to test for end of list */
1576− if (!attr->attr.name)
1577− break;
1578− sysfs_remove_file(&mod->mkobj.kobj, &attr->attr);
1579− if (attr->free)
1580− attr->free(mod);
1581− }
1582− kfree(mod->modinfo_attrs);
1583−}
1584−
1585−static void mod_kobject_put(struct module *mod)
1586−{
1587− DECLARE_COMPLETION_ONSTACK(c);
1588− mod->mkobj.kobj_completion = &c;
1589− kobject_put(&mod->mkobj.kobj);
1590− wait_for_completion(&c);
1591−}
1592−
1593−static int mod_sysfs_init(struct module *mod)
1594−{
1595− int err;
1596− struct kobject *kobj;
1597−
1598− if (!module_sysfs_initialized) {
1599− pr_err("%s: module sysfs not initialized\n", mod->name);
1600− err = -EINVAL;
1601− goto out;
1602− }
1603−
1604− kobj = kset_find_obj(module_kset, mod->name);
1605− if (kobj) {
1606− pr_err("%s: module is already loaded\n", mod->name);
1607− kobject_put(kobj);
1608− err = -EINVAL;
1609− goto out;
1610− }
1611−
1612− mod->mkobj.mod = mod;
1613−
1614− memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj));
1615− mod->mkobj.kobj.kset = module_kset;
1616− err = kobject_init_and_add(&mod->mkobj.kobj, &module_ktype, NULL,
1617− "%s", mod->name);
1618− if (err)
1619− mod_kobject_put(mod);
1620−
1621−out:
1622− return err;
1623−}
1624−
1625−static int mod_sysfs_setup(struct module *mod,
1626− const struct load_info *info,
1627− struct kernel_param *kparam,
1628− unsigned int num_params)
1629−{
1630− int err;
1631−
1632− err = mod_sysfs_init(mod);
1633− if (err)
1634− goto out;
1635−
1636− mod->holders_dir = kobject_create_and_add("holders", &mod->mkobj.kobj);
1637− if (!mod->holders_dir) {
1638− err = -ENOMEM;
1639− goto out_unreg;
1640− }
1641−
1642− err = module_param_sysfs_setup(mod, kparam, num_params);
1643− if (err)
1644− goto out_unreg_holders;
1645−
1646− err = module_add_modinfo_attrs(mod);
1647− if (err)
1648− goto out_unreg_param;
1649−
1650− err = add_usage_links(mod);
1651− if (err)
1652− goto out_unreg_modinfo_attrs;
1653−
1654− add_sect_attrs(mod, info);
1655− add_notes_attrs(mod, info);
1656−
1657− return 0;
1658−
1659−out_unreg_modinfo_attrs:
1660− module_remove_modinfo_attrs(mod, -1);
1661−out_unreg_param:
1662− module_param_sysfs_remove(mod);
1663−out_unreg_holders:
1664− kobject_put(mod->holders_dir);
1665−out_unreg:
1666− mod_kobject_put(mod);
1667−out:
1668− return err;
1669−}
1670−
1671−static void mod_sysfs_fini(struct module *mod)
1672−{
1673− remove_notes_attrs(mod);
1674− remove_sect_attrs(mod);
1675− mod_kobject_put(mod);
1676−}
1677−
1678−static void init_param_lock(struct module *mod)
1679−{
1680− mutex_init(&mod->param_lock);
1681−}
1682−#else /* !CONFIG_SYSFS */
1683−
1684−static int mod_sysfs_setup(struct module *mod,
1685− const struct load_info *info,
1686− struct kernel_param *kparam,
1687− unsigned int num_params)
1688−{
1689− return 0;
1690−}
1691−
1692−static void mod_sysfs_fini(struct module *mod)
1693−{
1694−}
1695−
1696−static void module_remove_modinfo_attrs(struct module *mod, int end)
1697−{
1698−}
1699−
1700−static void del_usage_links(struct module *mod)
1701−{
1702−}
1703−
1704−static void init_param_lock(struct module *mod)
1705−{
1706−}
1707−#endif /* CONFIG_SYSFS */
1708−
1709−static void mod_sysfs_teardown(struct module *mod)
1710−{
1711− del_usage_links(mod);
1712− module_remove_modinfo_attrs(mod, -1);
1713− module_param_sysfs_remove(mod);
1714− kobject_put(mod->mkobj.drivers_dir);
1715− kobject_put(mod->holders_dir);
1716− mod_sysfs_fini(mod);
1717−}
1718−
17191256 /*
17201257 * LKM RO/NX protection: protect module's text/ro-data
17211258 * from modification and any data from execution.
kernel/module/sysfs.c+436−0
@@ -0,0 +1,436 @@
1+// SPDX-License-Identifier: GPL-2.0-or-later
2+/*
3+ * Module sysfs support
4+ *
5+ * Copyright (C) 2008 Rusty Russell
6+ */
7+
8+#include <linux/module.h>
9+#include <linux/kernel.h>
10+#include <linux/fs.h>
11+#include <linux/sysfs.h>
12+#include <linux/slab.h>
13+#include <linux/kallsyms.h>
14+#include <linux/mutex.h>
15+#include "internal.h"
16+
17+/*
18+ * /sys/module/foo/sections stuff
19+ * J. Corbet <corbet@lwn.net>
20+ */
21+#ifdef CONFIG_KALLSYMS
22+struct module_sect_attr {
23+ struct bin_attribute battr;
24+ unsigned long address;
25+};
26+
27+struct module_sect_attrs {
28+ struct attribute_group grp;
29+ unsigned int nsections;
30+ struct module_sect_attr attrs[];
31+};
32+
33+#define MODULE_SECT_READ_SIZE (3 /* "0x", "\n" */ + (BITS_PER_LONG / 4))
34+static ssize_t module_sect_read(struct file *file, struct kobject *kobj,
35+ struct bin_attribute *battr,
36+ char *buf, loff_t pos, size_t count)
37+{
38+ struct module_sect_attr *sattr =
39+ container_of(battr, struct module_sect_attr, battr);
40+ char bounce[MODULE_SECT_READ_SIZE + 1];
41+ size_t wrote;
42+
43+ if (pos != 0)
44+ return -EINVAL;
45+
46+ /*
47+ * Since we're a binary read handler, we must account for the
48+ * trailing NUL byte that sprintf will write: if "buf" is
49+ * too small to hold the NUL, or the NUL is exactly the last
50+ * byte, the read will look like it got truncated by one byte.
51+ * Since there is no way to ask sprintf nicely to not write
52+ * the NUL, we have to use a bounce buffer.
53+ */
54+ wrote = scnprintf(bounce, sizeof(bounce), "0x%px\n",
55+ kallsyms_show_value(file->f_cred)
56+ ? (void *)sattr->address : NULL);
57+ count = min(count, wrote);
58+ memcpy(buf, bounce, count);
59+
60+ return count;
61+}
62+
63+static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
64+{
65+ unsigned int section;
66+
67+ for (section = 0; section < sect_attrs->nsections; section++)
68+ kfree(sect_attrs->attrs[section].battr.attr.name);
69+ kfree(sect_attrs);
70+}
71+
72+static void add_sect_attrs(struct module *mod, const struct load_info *info)
73+{
74+ unsigned int nloaded = 0, i, size[2];
75+ struct module_sect_attrs *sect_attrs;
76+ struct module_sect_attr *sattr;
77+ struct bin_attribute **gattr;
78+
79+ /* Count loaded sections and allocate structures */
80+ for (i = 0; i < info->hdr->e_shnum; i++)
81+ if (!sect_empty(&info->sechdrs[i]))
82+ nloaded++;
83+ size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded),
84+ sizeof(sect_attrs->grp.bin_attrs[0]));
85+ size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);
86+ sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
87+ if (!sect_attrs)
88+ return;
89+
90+ /* Setup section attributes. */
91+ sect_attrs->grp.name = "sections";
92+ sect_attrs->grp.bin_attrs = (void *)sect_attrs + size[0];
93+
94+ sect_attrs->nsections = 0;
95+ sattr = &sect_attrs->attrs[0];
96+ gattr = &sect_attrs->grp.bin_attrs[0];
97+ for (i = 0; i < info->hdr->e_shnum; i++) {
98+ Elf_Shdr *sec = &info->sechdrs[i];
99+
100+ if (sect_empty(sec))
101+ continue;
102+ sysfs_bin_attr_init(&sattr->battr);
103+ sattr->address = sec->sh_addr;
104+ sattr->battr.attr.name =
105+ kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL);
106+ if (!sattr->battr.attr.name)
107+ goto out;
108+ sect_attrs->nsections++;
109+ sattr->battr.read = module_sect_read;
110+ sattr->battr.size = MODULE_SECT_READ_SIZE;
111+ sattr->battr.attr.mode = 0400;
112+ *(gattr++) = &(sattr++)->battr;
113+ }
114+ *gattr = NULL;
115+
116+ if (sysfs_create_group(&mod->mkobj.kobj, &sect_attrs->grp))
117+ goto out;
118+
119+ mod->sect_attrs = sect_attrs;
120+ return;
121+out:
122+ free_sect_attrs(sect_attrs);
123+}
124+
125+static void remove_sect_attrs(struct module *mod)
126+{
127+ if (mod->sect_attrs) {
128+ sysfs_remove_group(&mod->mkobj.kobj,
129+ &mod->sect_attrs->grp);
130+ /*
131+ * We are positive that no one is using any sect attrs
132+ * at this point. Deallocate immediately.
133+ */
134+ free_sect_attrs(mod->sect_attrs);
135+ mod->sect_attrs = NULL;
136+ }
137+}
138+
139+/*
140+ * /sys/module/foo/notes/.section.name gives contents of SHT_NOTE sections.
141+ */
142+
143+struct module_notes_attrs {
144+ struct kobject *dir;
145+ unsigned int notes;
146+ struct bin_attribute attrs[];
147+};
148+
149+static ssize_t module_notes_read(struct file *filp, struct kobject *kobj,
150+ struct bin_attribute *bin_attr,
151+ char *buf, loff_t pos, size_t count)
152+{
153+ /*
154+ * The caller checked the pos and count against our size.
155+ */
156+ memcpy(buf, bin_attr->private + pos, count);
157+ return count;
158+}
159+
160+static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
161+ unsigned int i)
162+{
163+ if (notes_attrs->dir) {
164+ while (i-- > 0)
165+ sysfs_remove_bin_file(notes_attrs->dir,
166+ &notes_attrs->attrs[i]);
167+ kobject_put(notes_attrs->dir);
168+ }
169+ kfree(notes_attrs);
170+}
171+
172+static void add_notes_attrs(struct module *mod, const struct load_info *info)
173+{
174+ unsigned int notes, loaded, i;
175+ struct module_notes_attrs *notes_attrs;
176+ struct bin_attribute *nattr;
177+
178+ /* failed to create section attributes, so can't create notes */
179+ if (!mod->sect_attrs)
180+ return;
181+
182+ /* Count notes sections and allocate structures. */
183+ notes = 0;
184+ for (i = 0; i < info->hdr->e_shnum; i++)
185+ if (!sect_empty(&info->sechdrs[i]) &&
186+ info->sechdrs[i].sh_type == SHT_NOTE)
187+ ++notes;
188+
189+ if (notes == 0)
190+ return;
191+
192+ notes_attrs = kzalloc(struct_size(notes_attrs, attrs, notes),
193+ GFP_KERNEL);
194+ if (!notes_attrs)
195+ return;
196+
197+ notes_attrs->notes = notes;
198+ nattr = &notes_attrs->attrs[0];
199+ for (loaded = i = 0; i < info->hdr->e_shnum; ++i) {
200+ if (sect_empty(&info->sechdrs[i]))
201+ continue;
202+ if (info->sechdrs[i].sh_type == SHT_NOTE) {
203+ sysfs_bin_attr_init(nattr);
204+ nattr->attr.name = mod->sect_attrs->attrs[loaded].battr.attr.name;
205+ nattr->attr.mode = 0444;
206+ nattr->size = info->sechdrs[i].sh_size;
207+ nattr->private = (void *)info->sechdrs[i].sh_addr;
208+ nattr->read = module_notes_read;
209+ ++nattr;
210+ }
211+ ++loaded;
212+ }
213+
214+ notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj);
215+ if (!notes_attrs->dir)
216+ goto out;
217+
218+ for (i = 0; i < notes; ++i)
219+ if (sysfs_create_bin_file(notes_attrs->dir,
220+ &notes_attrs->attrs[i]))
221+ goto out;
222+
223+ mod->notes_attrs = notes_attrs;
224+ return;
225+
226+out:
227+ free_notes_attrs(notes_attrs, i);
228+}
229+
230+static void remove_notes_attrs(struct module *mod)
231+{
232+ if (mod->notes_attrs)
233+ free_notes_attrs(mod->notes_attrs, mod->notes_attrs->notes);
234+}
235+
236+#else /* !CONFIG_KALLSYMS */
237+static inline void add_sect_attrs(struct module *mod, const struct load_info *info) { }
238+static inline void remove_sect_attrs(struct module *mod) { }
239+static inline void add_notes_attrs(struct module *mod, const struct load_info *info) { }
240+static inline void remove_notes_attrs(struct module *mod) { }
241+#endif /* CONFIG_KALLSYMS */
242+
243+static void del_usage_links(struct module *mod)
244+{
245+#ifdef CONFIG_MODULE_UNLOAD
246+ struct module_use *use;
247+
248+ mutex_lock(&module_mutex);
249+ list_for_each_entry(use, &mod->target_list, target_list)
250+ sysfs_remove_link(use->target->holders_dir, mod->name);
251+ mutex_unlock(&module_mutex);
252+#endif
253+}
254+
255+static int add_usage_links(struct module *mod)
256+{
257+ int ret = 0;
258+#ifdef CONFIG_MODULE_UNLOAD
259+ struct module_use *use;
260+
261+ mutex_lock(&module_mutex);
262+ list_for_each_entry(use, &mod->target_list, target_list) {
263+ ret = sysfs_create_link(use->target->holders_dir,
264+ &mod->mkobj.kobj, mod->name);
265+ if (ret)
266+ break;
267+ }
268+ mutex_unlock(&module_mutex);
269+ if (ret)
270+ del_usage_links(mod);
271+#endif
272+ return ret;
273+}
274+
275+static void module_remove_modinfo_attrs(struct module *mod, int end)
276+{
277+ struct module_attribute *attr;
278+ int i;
279+
280+ for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) {
281+ if (end >= 0 && i > end)
282+ break;
283+ /* pick a field to test for end of list */
284+ if (!attr->attr.name)
285+ break;
286+ sysfs_remove_file(&mod->mkobj.kobj, &attr->attr);
287+ if (attr->free)
288+ attr->free(mod);
289+ }
290+ kfree(mod->modinfo_attrs);
291+}
292+
293+static int module_add_modinfo_attrs(struct module *mod)
294+{
295+ struct module_attribute *attr;
296+ struct module_attribute *temp_attr;
297+ int error = 0;
298+ int i;
299+
300+ mod->modinfo_attrs = kzalloc((sizeof(struct module_attribute) *
301+ (modinfo_attrs_count + 1)),
302+ GFP_KERNEL);
303+ if (!mod->modinfo_attrs)
304+ return -ENOMEM;
305+
306+ temp_attr = mod->modinfo_attrs;
307+ for (i = 0; (attr = modinfo_attrs[i]); i++) {
308+ if (!attr->test || attr->test(mod)) {
309+ memcpy(temp_attr, attr, sizeof(*temp_attr));
310+ sysfs_attr_init(&temp_attr->attr);
311+ error = sysfs_create_file(&mod->mkobj.kobj,
312+ &temp_attr->attr);
313+ if (error)
314+ goto error_out;
315+ ++temp_attr;
316+ }
317+ }
318+
319+ return 0;
320+
321+error_out:
322+ if (i > 0)
323+ module_remove_modinfo_attrs(mod, --i);
324+ else
325+ kfree(mod->modinfo_attrs);
326+ return error;
327+}
328+
329+static void mod_kobject_put(struct module *mod)
330+{
331+ DECLARE_COMPLETION_ONSTACK(c);
332+
333+ mod->mkobj.kobj_completion = &c;
334+ kobject_put(&mod->mkobj.kobj);
335+ wait_for_completion(&c);
336+}
337+
338+static int mod_sysfs_init(struct module *mod)
339+{
340+ int err;
341+ struct kobject *kobj;
342+
343+ if (!module_sysfs_initialized) {
344+ pr_err("%s: module sysfs not initialized\n", mod->name);
345+ err = -EINVAL;
346+ goto out;
347+ }
348+
349+ kobj = kset_find_obj(module_kset, mod->name);
350+ if (kobj) {
351+ pr_err("%s: module is already loaded\n", mod->name);
352+ kobject_put(kobj);
353+ err = -EINVAL;
354+ goto out;
355+ }
356+
357+ mod->mkobj.mod = mod;
358+
359+ memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj));
360+ mod->mkobj.kobj.kset = module_kset;
361+ err = kobject_init_and_add(&mod->mkobj.kobj, &module_ktype, NULL,
362+ "%s", mod->name);
363+ if (err)
364+ mod_kobject_put(mod);
365+
366+out:
367+ return err;
368+}
369+
370+int mod_sysfs_setup(struct module *mod,
371+ const struct load_info *info,
372+ struct kernel_param *kparam,
373+ unsigned int num_params)
374+{
375+ int err;
376+
377+ err = mod_sysfs_init(mod);
378+ if (err)
379+ goto out;
380+
381+ mod->holders_dir = kobject_create_and_add("holders", &mod->mkobj.kobj);
382+ if (!mod->holders_dir) {
383+ err = -ENOMEM;
384+ goto out_unreg;
385+ }
386+
387+ err = module_param_sysfs_setup(mod, kparam, num_params);
388+ if (err)
389+ goto out_unreg_holders;
390+
391+ err = module_add_modinfo_attrs(mod);
392+ if (err)
393+ goto out_unreg_param;
394+
395+ err = add_usage_links(mod);
396+ if (err)
397+ goto out_unreg_modinfo_attrs;
398+
399+ add_sect_attrs(mod, info);
400+ add_notes_attrs(mod, info);
401+
402+ return 0;
403+
404+out_unreg_modinfo_attrs:
405+ module_remove_modinfo_attrs(mod, -1);
406+out_unreg_param:
407+ module_param_sysfs_remove(mod);
408+out_unreg_holders:
409+ kobject_put(mod->holders_dir);
410+out_unreg:
411+ mod_kobject_put(mod);
412+out:
413+ return err;
414+}
415+
416+static void mod_sysfs_fini(struct module *mod)
417+{
418+ remove_notes_attrs(mod);
419+ remove_sect_attrs(mod);
420+ mod_kobject_put(mod);
421+}
422+
423+void mod_sysfs_teardown(struct module *mod)
424+{
425+ del_usage_links(mod);
426+ module_remove_modinfo_attrs(mod, -1);
427+ module_param_sysfs_remove(mod);
428+ kobject_put(mod->mkobj.drivers_dir);
429+ kobject_put(mod->holders_dir);
430+ mod_sysfs_fini(mod);
431+}
432+
433+void init_param_lock(struct module *mod)
434+{
435+ mutex_init(&mod->param_lock);
436+}