From 3675a926feefdf3afabea12f806f31ea582065e5 Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Sat, 28 Dec 2024 09:43:41 +0100 Subject: sysfs: constify bin_attribute argument of sysfs_bin_attr_simple_read() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most users use this function through the BIN_ATTR_SIMPLE* macros, they can handle the switch transparently. Also adapt the two non-macro users in the same change. Signed-off-by: Thomas Weißschuh Acked-by: Madhavan Srinivasan Reviewed-by: Mahesh Salgaonkar Tested-by: Aditya Gupta Link: https://lore.kernel.org/r/20241228-sysfs-const-bin_attr-simple-v2-1-7c6f3f1767a3@weissschuh.net Signed-off-by: Greg Kroah-Hartman --- kernel/module/sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel/module/sysfs.c') diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c index 456358e1fdc4..254017b58b64 100644 --- a/kernel/module/sysfs.c +++ b/kernel/module/sysfs.c @@ -196,7 +196,7 @@ static int add_notes_attrs(struct module *mod, const struct load_info *info) nattr->attr.mode = 0444; nattr->size = info->sechdrs[i].sh_size; nattr->private = (void *)info->sechdrs[i].sh_addr; - nattr->read = sysfs_bin_attr_simple_read; + nattr->read_new = sysfs_bin_attr_simple_read; ++nattr; } ++loaded; -- cgit v1.2.3 From f3227ffda07470848abe3cfa2039b21816ce3090 Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Mon, 16 Dec 2024 18:25:10 +0100 Subject: module: Constify 'struct module_attribute' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These structs are never modified, move them to read-only memory. This makes the API clearer and also prepares for the constification of 'struct attribute' itself. While at it, also constify 'modinfo_attrs_count'. Signed-off-by: Thomas Weißschuh Reviewed-by: Petr Pavlu Link: https://lore.kernel.org/r/20241216-sysfs-const-attr-module-v1-3-3790b53e0abf@weissschuh.net Signed-off-by: Petr Pavlu --- include/linux/module.h | 8 ++++---- kernel/module/internal.h | 4 ++-- kernel/module/main.c | 40 ++++++++++++++++++++-------------------- kernel/module/sysfs.c | 4 ++-- kernel/params.c | 12 ++++++------ 5 files changed, 34 insertions(+), 34 deletions(-) (limited to 'kernel/module/sysfs.c') diff --git a/include/linux/module.h b/include/linux/module.h index 5001c166c74f..37eb5d88f6eb 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -52,9 +52,9 @@ struct module_kobject { struct module_attribute { struct attribute attr; - ssize_t (*show)(struct module_attribute *, struct module_kobject *, + ssize_t (*show)(const struct module_attribute *, struct module_kobject *, char *); - ssize_t (*store)(struct module_attribute *, struct module_kobject *, + ssize_t (*store)(const struct module_attribute *, struct module_kobject *, const char *, size_t count); void (*setup)(struct module *, const char *); int (*test)(struct module *); @@ -67,10 +67,10 @@ struct module_version_attribute { const char *version; }; -extern ssize_t __modver_version_show(struct module_attribute *, +extern ssize_t __modver_version_show(const struct module_attribute *, struct module_kobject *, char *); -extern struct module_attribute module_uevent; +extern const struct module_attribute module_uevent; /* These are either module local, or the kernel's dummy ones. */ extern int init_module(void); diff --git a/kernel/module/internal.h b/kernel/module/internal.h index daef2be83902..ac73da5f15bc 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -47,8 +47,8 @@ struct kernel_symbol { extern struct mutex module_mutex; extern struct list_head modules; -extern struct module_attribute *modinfo_attrs[]; -extern size_t modinfo_attrs_count; +extern const struct module_attribute *const modinfo_attrs[]; +extern const size_t modinfo_attrs_count; /* Provided by the linker */ extern const struct kernel_symbol __start___ksymtab[]; diff --git a/kernel/module/main.c b/kernel/module/main.c index fd483d436e43..8154e1665cdb 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -538,7 +538,7 @@ static void setup_modinfo_##field(struct module *mod, const char *s) \ { \ mod->field = kstrdup(s, GFP_KERNEL); \ } \ -static ssize_t show_modinfo_##field(struct module_attribute *mattr, \ +static ssize_t show_modinfo_##field(const struct module_attribute *mattr, \ struct module_kobject *mk, char *buffer) \ { \ return scnprintf(buffer, PAGE_SIZE, "%s\n", mk->mod->field); \ @@ -552,7 +552,7 @@ static void free_modinfo_##field(struct module *mod) \ kfree(mod->field); \ mod->field = NULL; \ } \ -static struct module_attribute modinfo_##field = { \ +static const struct module_attribute modinfo_##field = { \ .attr = { .name = __stringify(field), .mode = 0444 }, \ .show = show_modinfo_##field, \ .setup = setup_modinfo_##field, \ @@ -842,13 +842,13 @@ void symbol_put_addr(void *addr) } EXPORT_SYMBOL_GPL(symbol_put_addr); -static ssize_t show_refcnt(struct module_attribute *mattr, +static ssize_t show_refcnt(const struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { return sprintf(buffer, "%i\n", module_refcount(mk->mod)); } -static struct module_attribute modinfo_refcnt = +static const struct module_attribute modinfo_refcnt = __ATTR(refcnt, 0444, show_refcnt, NULL); void __module_get(struct module *module) @@ -917,7 +917,7 @@ size_t module_flags_taint(unsigned long taints, char *buf) return l; } -static ssize_t show_initstate(struct module_attribute *mattr, +static ssize_t show_initstate(const struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { const char *state = "unknown"; @@ -938,10 +938,10 @@ static ssize_t show_initstate(struct module_attribute *mattr, return sprintf(buffer, "%s\n", state); } -static struct module_attribute modinfo_initstate = +static const struct module_attribute modinfo_initstate = __ATTR(initstate, 0444, show_initstate, NULL); -static ssize_t store_uevent(struct module_attribute *mattr, +static ssize_t store_uevent(const struct module_attribute *mattr, struct module_kobject *mk, const char *buffer, size_t count) { @@ -951,10 +951,10 @@ static ssize_t store_uevent(struct module_attribute *mattr, return rc ? rc : count; } -struct module_attribute module_uevent = +const struct module_attribute module_uevent = __ATTR(uevent, 0200, NULL, store_uevent); -static ssize_t show_coresize(struct module_attribute *mattr, +static ssize_t show_coresize(const struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { unsigned int size = mk->mod->mem[MOD_TEXT].size; @@ -966,11 +966,11 @@ static ssize_t show_coresize(struct module_attribute *mattr, return sprintf(buffer, "%u\n", size); } -static struct module_attribute modinfo_coresize = +static const struct module_attribute modinfo_coresize = __ATTR(coresize, 0444, show_coresize, NULL); #ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC -static ssize_t show_datasize(struct module_attribute *mattr, +static ssize_t show_datasize(const struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { unsigned int size = 0; @@ -980,11 +980,11 @@ static ssize_t show_datasize(struct module_attribute *mattr, return sprintf(buffer, "%u\n", size); } -static struct module_attribute modinfo_datasize = +static const struct module_attribute modinfo_datasize = __ATTR(datasize, 0444, show_datasize, NULL); #endif -static ssize_t show_initsize(struct module_attribute *mattr, +static ssize_t show_initsize(const struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { unsigned int size = 0; @@ -994,10 +994,10 @@ static ssize_t show_initsize(struct module_attribute *mattr, return sprintf(buffer, "%u\n", size); } -static struct module_attribute modinfo_initsize = +static const struct module_attribute modinfo_initsize = __ATTR(initsize, 0444, show_initsize, NULL); -static ssize_t show_taint(struct module_attribute *mattr, +static ssize_t show_taint(const struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { size_t l; @@ -1007,10 +1007,10 @@ static ssize_t show_taint(struct module_attribute *mattr, return l; } -static struct module_attribute modinfo_taint = +static const struct module_attribute modinfo_taint = __ATTR(taint, 0444, show_taint, NULL); -struct module_attribute *modinfo_attrs[] = { +const struct module_attribute *const modinfo_attrs[] = { &module_uevent, &modinfo_version, &modinfo_srcversion, @@ -1027,7 +1027,7 @@ struct module_attribute *modinfo_attrs[] = { NULL, }; -size_t modinfo_attrs_count = ARRAY_SIZE(modinfo_attrs); +const size_t modinfo_attrs_count = ARRAY_SIZE(modinfo_attrs); static const char vermagic[] = VERMAGIC_STRING; @@ -1681,7 +1681,7 @@ static void module_license_taint_check(struct module *mod, const char *license) static void setup_modinfo(struct module *mod, struct load_info *info) { - struct module_attribute *attr; + const struct module_attribute *attr; int i; for (i = 0; (attr = modinfo_attrs[i]); i++) { @@ -1692,7 +1692,7 @@ static void setup_modinfo(struct module *mod, struct load_info *info) static void free_modinfo(struct module *mod) { - struct module_attribute *attr; + const struct module_attribute *attr; int i; for (i = 0; (attr = modinfo_attrs[i]); i++) { diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c index 456358e1fdc4..31e7f3055407 100644 --- a/kernel/module/sysfs.c +++ b/kernel/module/sysfs.c @@ -275,7 +275,7 @@ static int add_usage_links(struct module *mod) static void module_remove_modinfo_attrs(struct module *mod, int end) { - struct module_attribute *attr; + const struct module_attribute *attr; int i; for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) { @@ -293,7 +293,7 @@ static void module_remove_modinfo_attrs(struct module *mod, int end) static int module_add_modinfo_attrs(struct module *mod) { - struct module_attribute *attr; + const struct module_attribute *attr; struct module_attribute *temp_attr; int error = 0; int i; diff --git a/kernel/params.c b/kernel/params.c index 763261a7fef9..0074d29c9b80 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -538,7 +538,7 @@ const struct kernel_param_ops param_ops_string = { EXPORT_SYMBOL(param_ops_string); /* sysfs output in /sys/modules/XYZ/parameters/ */ -#define to_module_attr(n) container_of(n, struct module_attribute, attr) +#define to_module_attr(n) container_of_const(n, struct module_attribute, attr) #define to_module_kobject(n) container_of(n, struct module_kobject, kobj) struct param_attribute @@ -557,7 +557,7 @@ struct module_param_attrs #ifdef CONFIG_SYSFS #define to_param_attr(n) container_of_const(n, struct param_attribute, mattr) -static ssize_t param_attr_show(struct module_attribute *mattr, +static ssize_t param_attr_show(const struct module_attribute *mattr, struct module_kobject *mk, char *buf) { int count; @@ -573,7 +573,7 @@ static ssize_t param_attr_show(struct module_attribute *mattr, } /* sysfs always hands a nul-terminated string in buf. We rely on that. */ -static ssize_t param_attr_store(struct module_attribute *mattr, +static ssize_t param_attr_store(const struct module_attribute *mattr, struct module_kobject *mk, const char *buf, size_t len) { @@ -857,7 +857,7 @@ static void __init param_sysfs_builtin(void) } } -ssize_t __modver_version_show(struct module_attribute *mattr, +ssize_t __modver_version_show(const struct module_attribute *mattr, struct module_kobject *mk, char *buf) { const struct module_version_attribute *vattr = @@ -892,7 +892,7 @@ static ssize_t module_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { - struct module_attribute *attribute; + const struct module_attribute *attribute; struct module_kobject *mk; int ret; @@ -911,7 +911,7 @@ static ssize_t module_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t len) { - struct module_attribute *attribute; + const struct module_attribute *attribute; struct module_kobject *mk; int ret; -- cgit v1.2.3 From d8959b947a8dfab1047c6fd5e982808f65717bfe Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Fri, 27 Dec 2024 14:23:20 +0100 Subject: module: sysfs: Drop member 'module_sect_attrs::nsections' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The member is only used to iterate over all attributes in free_sect_attrs(). However the attribute group can already be used for that. Use the group and drop 'nsections'. Signed-off-by: Thomas Weißschuh Reviewed-by: Petr Pavlu Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20241227-sysfs-const-bin_attr-module-v2-1-e267275f0f37@weissschuh.net Signed-off-by: Petr Pavlu --- kernel/module/sysfs.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'kernel/module/sysfs.c') diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c index 31e7f3055407..31351591e8e0 100644 --- a/kernel/module/sysfs.c +++ b/kernel/module/sysfs.c @@ -26,7 +26,6 @@ struct module_sect_attr { struct module_sect_attrs { struct attribute_group grp; - unsigned int nsections; struct module_sect_attr attrs[]; }; @@ -62,10 +61,10 @@ static ssize_t module_sect_read(struct file *file, struct kobject *kobj, static void free_sect_attrs(struct module_sect_attrs *sect_attrs) { - unsigned int section; + struct bin_attribute **bin_attr; - for (section = 0; section < sect_attrs->nsections; section++) - kfree(sect_attrs->attrs[section].battr.attr.name); + for (bin_attr = sect_attrs->grp.bin_attrs; *bin_attr; bin_attr++) + kfree((*bin_attr)->attr.name); kfree(sect_attrs); } @@ -92,7 +91,6 @@ static int add_sect_attrs(struct module *mod, const struct load_info *info) sect_attrs->grp.name = "sections"; sect_attrs->grp.bin_attrs = (void *)sect_attrs + size[0]; - sect_attrs->nsections = 0; sattr = §_attrs->attrs[0]; gattr = §_attrs->grp.bin_attrs[0]; for (i = 0; i < info->hdr->e_shnum; i++) { @@ -108,7 +106,6 @@ static int add_sect_attrs(struct module *mod, const struct load_info *info) ret = -ENOMEM; goto out; } - sect_attrs->nsections++; sattr->battr.read = module_sect_read; sattr->battr.size = MODULE_SECT_READ_SIZE; sattr->battr.attr.mode = 0400; -- cgit v1.2.3 From 4b2c11e4aaf7e3d7fd9ce8e5995a32ff5e27d74f Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Fri, 27 Dec 2024 14:23:21 +0100 Subject: module: sysfs: Drop member 'module_sect_attr::address' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'struct bin_attribute' already contains the member 'private' to pass custom data to the attribute handlers. Use that instead of the custom 'address' member. Signed-off-by: Thomas Weißschuh Reviewed-by: Petr Pavlu Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20241227-sysfs-const-bin_attr-module-v2-2-e267275f0f37@weissschuh.net Signed-off-by: Petr Pavlu --- kernel/module/sysfs.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'kernel/module/sysfs.c') diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c index 31351591e8e0..6941ecc941d7 100644 --- a/kernel/module/sysfs.c +++ b/kernel/module/sysfs.c @@ -21,7 +21,6 @@ #ifdef CONFIG_KALLSYMS struct module_sect_attr { struct bin_attribute battr; - unsigned long address; }; struct module_sect_attrs { @@ -34,8 +33,6 @@ static ssize_t module_sect_read(struct file *file, struct kobject *kobj, struct bin_attribute *battr, char *buf, loff_t pos, size_t count) { - struct module_sect_attr *sattr = - container_of(battr, struct module_sect_attr, battr); char bounce[MODULE_SECT_READ_SIZE + 1]; size_t wrote; @@ -52,7 +49,7 @@ static ssize_t module_sect_read(struct file *file, struct kobject *kobj, */ wrote = scnprintf(bounce, sizeof(bounce), "0x%px\n", kallsyms_show_value(file->f_cred) - ? (void *)sattr->address : NULL); + ? battr->private : NULL); count = min(count, wrote); memcpy(buf, bounce, count); @@ -99,7 +96,6 @@ static int add_sect_attrs(struct module *mod, const struct load_info *info) if (sect_empty(sec)) continue; sysfs_bin_attr_init(&sattr->battr); - sattr->address = sec->sh_addr; sattr->battr.attr.name = kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL); if (!sattr->battr.attr.name) { @@ -107,6 +103,7 @@ static int add_sect_attrs(struct module *mod, const struct load_info *info) goto out; } sattr->battr.read = module_sect_read; + sattr->battr.private = (void *)sec->sh_addr; sattr->battr.size = MODULE_SECT_READ_SIZE; sattr->battr.attr.mode = 0400; *(gattr++) = &(sattr++)->battr; -- cgit v1.2.3 From 34f5ec0f8252e2ba83fa5da05d56b6fdb0ebef59 Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Fri, 27 Dec 2024 14:23:22 +0100 Subject: module: sysfs: Drop 'struct module_sect_attr' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is now an otherwise empty wrapper around a 'struct bin_attribute', not providing any functionality. Remove it. Signed-off-by: Thomas Weißschuh Reviewed-by: Petr Pavlu Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20241227-sysfs-const-bin_attr-module-v2-3-e267275f0f37@weissschuh.net Signed-off-by: Petr Pavlu --- kernel/module/sysfs.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'kernel/module/sysfs.c') diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c index 6941ecc941d7..89797c556e8c 100644 --- a/kernel/module/sysfs.c +++ b/kernel/module/sysfs.c @@ -19,13 +19,9 @@ * J. Corbet */ #ifdef CONFIG_KALLSYMS -struct module_sect_attr { - struct bin_attribute battr; -}; - struct module_sect_attrs { struct attribute_group grp; - struct module_sect_attr attrs[]; + struct bin_attribute attrs[]; }; #define MODULE_SECT_READ_SIZE (3 /* "0x", "\n" */ + (BITS_PER_LONG / 4)) @@ -69,8 +65,8 @@ static int add_sect_attrs(struct module *mod, const struct load_info *info) { unsigned int nloaded = 0, i, size[2]; struct module_sect_attrs *sect_attrs; - struct module_sect_attr *sattr; struct bin_attribute **gattr; + struct bin_attribute *sattr; int ret; /* Count loaded sections and allocate structures */ @@ -95,18 +91,18 @@ static int add_sect_attrs(struct module *mod, const struct load_info *info) if (sect_empty(sec)) continue; - sysfs_bin_attr_init(&sattr->battr); - sattr->battr.attr.name = + sysfs_bin_attr_init(sattr); + sattr->attr.name = kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL); - if (!sattr->battr.attr.name) { + if (!sattr->attr.name) { ret = -ENOMEM; goto out; } - sattr->battr.read = module_sect_read; - sattr->battr.private = (void *)sec->sh_addr; - sattr->battr.size = MODULE_SECT_READ_SIZE; - sattr->battr.attr.mode = 0400; - *(gattr++) = &(sattr++)->battr; + sattr->read = module_sect_read; + sattr->private = (void *)sec->sh_addr; + sattr->size = MODULE_SECT_READ_SIZE; + sattr->attr.mode = 0400; + *(gattr++) = sattr++; } *gattr = NULL; @@ -186,7 +182,7 @@ static int add_notes_attrs(struct module *mod, const struct load_info *info) continue; if (info->sechdrs[i].sh_type == SHT_NOTE) { sysfs_bin_attr_init(nattr); - nattr->attr.name = mod->sect_attrs->attrs[loaded].battr.attr.name; + nattr->attr.name = mod->sect_attrs->attrs[loaded].attr.name; nattr->attr.mode = 0444; nattr->size = info->sechdrs[i].sh_size; nattr->private = (void *)info->sechdrs[i].sh_addr; -- cgit v1.2.3 From f47c0bebed44673c54a6a1870f04a2261db28ca0 Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Fri, 27 Dec 2024 14:23:23 +0100 Subject: module: sysfs: Simplify section attribute allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing allocation logic manually stuffs two allocations into one. This is hard to understand and of limited value, given that all the section names are allocated on their own anyways. Une one allocation per datastructure. Signed-off-by: Thomas Weißschuh Reviewed-by: Petr Pavlu Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20241227-sysfs-const-bin_attr-module-v2-4-e267275f0f37@weissschuh.net Signed-off-by: Petr Pavlu --- kernel/module/sysfs.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'kernel/module/sysfs.c') diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c index 89797c556e8c..05b1e3a6b644 100644 --- a/kernel/module/sysfs.c +++ b/kernel/module/sysfs.c @@ -58,34 +58,37 @@ static void free_sect_attrs(struct module_sect_attrs *sect_attrs) for (bin_attr = sect_attrs->grp.bin_attrs; *bin_attr; bin_attr++) kfree((*bin_attr)->attr.name); + kfree(sect_attrs->grp.bin_attrs); kfree(sect_attrs); } static int add_sect_attrs(struct module *mod, const struct load_info *info) { - unsigned int nloaded = 0, i, size[2]; struct module_sect_attrs *sect_attrs; struct bin_attribute **gattr; struct bin_attribute *sattr; + unsigned int nloaded = 0, i; int ret; /* Count loaded sections and allocate structures */ for (i = 0; i < info->hdr->e_shnum; i++) if (!sect_empty(&info->sechdrs[i])) nloaded++; - size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded), - sizeof(sect_attrs->grp.bin_attrs[0])); - size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]); - sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL); + sect_attrs = kzalloc(struct_size(sect_attrs, attrs, nloaded), GFP_KERNEL); if (!sect_attrs) return -ENOMEM; + gattr = kcalloc(nloaded + 1, sizeof(*gattr), GFP_KERNEL); + if (!gattr) { + kfree(sect_attrs); + return -ENOMEM; + } + /* Setup section attributes. */ sect_attrs->grp.name = "sections"; - sect_attrs->grp.bin_attrs = (void *)sect_attrs + size[0]; + sect_attrs->grp.bin_attrs = gattr; sattr = §_attrs->attrs[0]; - gattr = §_attrs->grp.bin_attrs[0]; for (i = 0; i < info->hdr->e_shnum; i++) { Elf_Shdr *sec = &info->sechdrs[i]; @@ -104,7 +107,6 @@ static int add_sect_attrs(struct module *mod, const struct load_info *info) sattr->attr.mode = 0400; *(gattr++) = sattr++; } - *gattr = NULL; ret = sysfs_create_group(&mod->mkobj.kobj, §_attrs->grp); if (ret) -- cgit v1.2.3 From 4723f16de64e1580ec5dc15173f8da0b316b2257 Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Fri, 27 Dec 2024 14:23:24 +0100 Subject: module: sysfs: Add notes attributes through attribute_group MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A kobject is meant to manage the lifecycle of some resource. However the module sysfs code only creates a kobject to get a "notes" subdirectory in sysfs. This can be achieved easier and cheaper by using a sysfs group. Switch the notes attribute code to such a group, similar to how the section allocation in the same file already works. Signed-off-by: Thomas Weißschuh Reviewed-by: Petr Pavlu Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20241227-sysfs-const-bin_attr-module-v2-5-e267275f0f37@weissschuh.net Signed-off-by: Petr Pavlu --- kernel/module/sysfs.c | 54 ++++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) (limited to 'kernel/module/sysfs.c') diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c index 05b1e3a6b644..fc2ad7e17cbd 100644 --- a/kernel/module/sysfs.c +++ b/kernel/module/sysfs.c @@ -138,20 +138,13 @@ static void remove_sect_attrs(struct module *mod) */ struct module_notes_attrs { - struct kobject *dir; - unsigned int notes; - struct bin_attribute attrs[] __counted_by(notes); + struct attribute_group grp; + struct bin_attribute attrs[]; }; -static void free_notes_attrs(struct module_notes_attrs *notes_attrs, - unsigned int i) +static void free_notes_attrs(struct module_notes_attrs *notes_attrs) { - if (notes_attrs->dir) { - while (i-- > 0) - sysfs_remove_bin_file(notes_attrs->dir, - ¬es_attrs->attrs[i]); - kobject_put(notes_attrs->dir); - } + kfree(notes_attrs->grp.bin_attrs); kfree(notes_attrs); } @@ -159,6 +152,7 @@ static int add_notes_attrs(struct module *mod, const struct load_info *info) { unsigned int notes, loaded, i; struct module_notes_attrs *notes_attrs; + struct bin_attribute **gattr; struct bin_attribute *nattr; int ret; @@ -177,7 +171,15 @@ static int add_notes_attrs(struct module *mod, const struct load_info *info) if (!notes_attrs) return -ENOMEM; - notes_attrs->notes = notes; + gattr = kcalloc(notes + 1, sizeof(*gattr), GFP_KERNEL); + if (!gattr) { + kfree(notes_attrs); + return -ENOMEM; + } + + notes_attrs->grp.name = "notes"; + notes_attrs->grp.bin_attrs = gattr; + nattr = ¬es_attrs->attrs[0]; for (loaded = i = 0; i < info->hdr->e_shnum; ++i) { if (sect_empty(&info->sechdrs[i])) @@ -189,35 +191,35 @@ static int add_notes_attrs(struct module *mod, const struct load_info *info) nattr->size = info->sechdrs[i].sh_size; nattr->private = (void *)info->sechdrs[i].sh_addr; nattr->read = sysfs_bin_attr_simple_read; - ++nattr; + *(gattr++) = nattr++; } ++loaded; } - notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj); - if (!notes_attrs->dir) { - ret = -ENOMEM; + ret = sysfs_create_group(&mod->mkobj.kobj, ¬es_attrs->grp); + if (ret) goto out; - } - - for (i = 0; i < notes; ++i) { - ret = sysfs_create_bin_file(notes_attrs->dir, ¬es_attrs->attrs[i]); - if (ret) - goto out; - } mod->notes_attrs = notes_attrs; return 0; out: - free_notes_attrs(notes_attrs, i); + free_notes_attrs(notes_attrs); return ret; } static void remove_notes_attrs(struct module *mod) { - if (mod->notes_attrs) - free_notes_attrs(mod->notes_attrs, mod->notes_attrs->notes); + if (mod->notes_attrs) { + sysfs_remove_group(&mod->mkobj.kobj, + &mod->notes_attrs->grp); + /* + * We are positive that no one is using any notes attrs + * at this point. Deallocate immediately. + */ + free_notes_attrs(mod->notes_attrs); + mod->notes_attrs = NULL; + } } #else /* !CONFIG_KALLSYMS */ -- cgit v1.2.3 From b83815afaeecf4448cdd54b3f9dc2623ebbc3576 Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Fri, 27 Dec 2024 14:23:25 +0100 Subject: module: sysfs: Use const 'struct bin_attribute' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sysfs core is switching to 'const struct bin_attribute's. Prepare for that. Signed-off-by: Thomas Weißschuh Reviewed-by: Petr Pavlu Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20241227-sysfs-const-bin_attr-module-v2-6-e267275f0f37@weissschuh.net Signed-off-by: Petr Pavlu --- kernel/module/sysfs.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'kernel/module/sysfs.c') diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c index fc2ad7e17cbd..f99616499e2e 100644 --- a/kernel/module/sysfs.c +++ b/kernel/module/sysfs.c @@ -26,7 +26,7 @@ struct module_sect_attrs { #define MODULE_SECT_READ_SIZE (3 /* "0x", "\n" */ + (BITS_PER_LONG / 4)) static ssize_t module_sect_read(struct file *file, struct kobject *kobj, - struct bin_attribute *battr, + const struct bin_attribute *battr, char *buf, loff_t pos, size_t count) { char bounce[MODULE_SECT_READ_SIZE + 1]; @@ -54,18 +54,18 @@ static ssize_t module_sect_read(struct file *file, struct kobject *kobj, static void free_sect_attrs(struct module_sect_attrs *sect_attrs) { - struct bin_attribute **bin_attr; + const struct bin_attribute *const *bin_attr; - for (bin_attr = sect_attrs->grp.bin_attrs; *bin_attr; bin_attr++) + for (bin_attr = sect_attrs->grp.bin_attrs_new; *bin_attr; bin_attr++) kfree((*bin_attr)->attr.name); - kfree(sect_attrs->grp.bin_attrs); + kfree(sect_attrs->grp.bin_attrs_new); kfree(sect_attrs); } static int add_sect_attrs(struct module *mod, const struct load_info *info) { struct module_sect_attrs *sect_attrs; - struct bin_attribute **gattr; + const struct bin_attribute **gattr; struct bin_attribute *sattr; unsigned int nloaded = 0, i; int ret; @@ -86,7 +86,7 @@ static int add_sect_attrs(struct module *mod, const struct load_info *info) /* Setup section attributes. */ sect_attrs->grp.name = "sections"; - sect_attrs->grp.bin_attrs = gattr; + sect_attrs->grp.bin_attrs_new = gattr; sattr = §_attrs->attrs[0]; for (i = 0; i < info->hdr->e_shnum; i++) { @@ -101,7 +101,7 @@ static int add_sect_attrs(struct module *mod, const struct load_info *info) ret = -ENOMEM; goto out; } - sattr->read = module_sect_read; + sattr->read_new = module_sect_read; sattr->private = (void *)sec->sh_addr; sattr->size = MODULE_SECT_READ_SIZE; sattr->attr.mode = 0400; @@ -144,7 +144,7 @@ struct module_notes_attrs { static void free_notes_attrs(struct module_notes_attrs *notes_attrs) { - kfree(notes_attrs->grp.bin_attrs); + kfree(notes_attrs->grp.bin_attrs_new); kfree(notes_attrs); } @@ -152,7 +152,7 @@ static int add_notes_attrs(struct module *mod, const struct load_info *info) { unsigned int notes, loaded, i; struct module_notes_attrs *notes_attrs; - struct bin_attribute **gattr; + const struct bin_attribute **gattr; struct bin_attribute *nattr; int ret; @@ -178,7 +178,7 @@ static int add_notes_attrs(struct module *mod, const struct load_info *info) } notes_attrs->grp.name = "notes"; - notes_attrs->grp.bin_attrs = gattr; + notes_attrs->grp.bin_attrs_new = gattr; nattr = ¬es_attrs->attrs[0]; for (loaded = i = 0; i < info->hdr->e_shnum; ++i) { -- cgit v1.2.3