Re: [PATCH v2 5/7] modpost: Create modalias for builtin modules

From: Masahiro Yamada
Date: Thu May 08 2025 - 11:43:25 EST


On Mon, May 5, 2025 at 6:39 PM Alexey Gladkov <legion@xxxxxxxxxx> 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 <legion@xxxxxxxxxx>
> ---
>
> 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 <masahiroy@xxxxxxxxxx>
Date: Fri, 9 May 2025 00:22:46 +0900
Subject: [PATCH] Another simple implementation

Signed-off-by: Masahiro Yamada <masahiroy@xxxxxxxxxx>
---
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