On Mon, May 5, 2025 at 6:39 PM Alexey Gladkov <leg...@kernel.org> wrote: > > For some modules, modalias is generated using the modpost utility and > the section is added to the module file. > > When a module is added inside vmlinux, modpost does not generate > modalias for such modules and the information is lost. > > As a result kmod (which uses modules.builtin.modinfo in userspace) > cannot determine that modalias is handled by a builtin kernel module. > > $ cat /sys/devices/pci0000:00/0000:00:14.0/modalias > pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30 > > $ modinfo xhci_pci > name: xhci_pci > filename: (builtin) > license: GPL > file: drivers/usb/host/xhci-pci > description: xHCI PCI Host Controller Driver > > Missing modalias "pci:v*d*sv*sd*bc0Csc03i30*" which will be generated by > modpost if the module is built separately. > > To fix this it is necessary to generate the same modalias for vmlinux as > for the individual modules. Fortunately '.vmlinux.export.o' is already > generated from which '.modinfo' can be extracted in the same way as for > vmlinux.o. > > Signed-off-by: Alexey Gladkov <leg...@kernel.org> > --- > > v2: As Petr Pavlu suggested, I separated the builtin modules from the external > modules. I've also added a search for duplicate modules. >
> --- > include/linux/module.h | 4 ---- > scripts/mod/file2alias.c | 5 +++++ > scripts/mod/modpost.c | 35 +++++++++++++++++++++++++++-------- > scripts/mod/modpost.h | 15 ++++++++++++++- > 4 files changed, 46 insertions(+), 13 deletions(-) I can implement this with less code change. I attached my patch. -- Best Regards Masahiro Yamada
From 28b8431db696b15a5812d6ca0a7372a30e060cfb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada <masahi...@kernel.org> Date: Fri, 9 May 2025 00:22:46 +0900 Subject: [PATCH] Another simple implementation Signed-off-by: Masahiro Yamada <masahi...@kernel.org> --- include/linux/module.h | 4 ---- scripts/mod/file2alias.c | 16 ++++++++++++++++ scripts/mod/modpost.c | 14 +++++++++++++- scripts/mod/modpost.h | 2 ++ 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index 01fceca47a5b..17e69e4a1802 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -259,14 +259,10 @@ struct module_kobject *lookup_or_create_module_kobject(const char *name); __PASTE(type, \ __PASTE(__, name))))))) -#ifdef MODULE /* Creates an alias so file2alias.c can find device table. */ #define MODULE_DEVICE_TABLE(type, name) \ extern typeof(name) __mod_device_table(type, name) \ __attribute__ ((unused, alias(__stringify(name)))) -#else /* !MODULE */ -#define MODULE_DEVICE_TABLE(type, name) -#endif /* Version of form [<epoch>:]<version>[-<extra-version>]. * Or for CVS/RCS ID version, everything but the number is stripped. diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index dff1799a4c79..d42f2c742fd6 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1527,5 +1527,21 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, } } + if (mod->is_vmlinux) { + struct module_alias *alias; + + /* + * If this is vmlinux, record the name of the builtin module. + * Traverse the linked list in the reverse order, and set the + * builtin_modname unless it has already been set in the + * previous call. + */ + list_for_each_entry_reverse(alias, &mod->aliases, node) { + if (alias->builtin_modname) + break; + alias->builtin_modname = xstrndup(modname, modnamelen); + } + } + free(zeros); } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index be89921d60b6..285b6c20c760 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2021,11 +2021,23 @@ static void write_if_changed(struct buffer *b, const char *fname) static void write_vmlinux_export_c_file(struct module *mod) { struct buffer buf = { }; + struct module_alias *alias, *next; buf_printf(&buf, - "#include <linux/export-internal.h>\n"); + "#include <linux/export-internal.h>\n" + "#include <linux/module.h>\n"); add_exported_symbols(&buf, mod); + + list_for_each_entry_safe(alias, next, &mod->aliases, node) { + buf_printf(&buf, "MODULE_ALIAS_MODNAME(\"%s\", \"%s\");\n", + alias->builtin_modname, alias->str); + list_del(&alias->node); + printf("builtin modname = %s\n", alias->builtin_modname); + free(alias->builtin_modname); + free(alias); + } + write_if_changed(&buf, ".vmlinux.export.c"); free(buf.p); } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 9133e4c3803f..2aecb8f25c87 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -99,10 +99,12 @@ buf_write(struct buffer *buf, const char *s, int len); * struct module_alias - auto-generated MODULE_ALIAS() * * @node: linked to module::aliases + * @modname: name of the builtin module (only for vmlinux) * @str: a string for MODULE_ALIAS() */ struct module_alias { struct list_head node; + char *builtin_modname; char str[]; }; -- 2.43.0