Re: [PATCH v2 5/7] modpost: Create modalias for builtin modules
On Fri, May 09, 2025 at 12:42:39AM +0900, Masahiro Yamada wrote: > On Mon, May 5, 2025 at 6:39 PM Alexey Gladkov 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/pci:00/:00:14.0/modalias > > pci:v8086dA36Dsv1043sd8694bc0Csc03i30 > > > > $ 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 > > --- > > > > 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. That is a good point. I'm gonna do it this way. Thanks! -- Rgrds, legion
Re: [PATCH v2 5/7] modpost: Create modalias for builtin modules
On Mon, May 5, 2025 at 6:39 PM Alexey Gladkov 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/pci:00/:00:14.0/modalias
> pci:v8086dA36Dsv1043sd8694bc0Csc03i30
>
> $ 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
> ---
>
> 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
Date: Fri, 9 May 2025 00:22:46 +0900
Subject: [PATCH] Another simple implementation
Signed-off-by: Masahiro Yamada
---
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 [:][-].
* 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 \n");
+ "#include \n"
+ "#include \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
Re: [PATCH v2 5/7] modpost: Create modalias for builtin modules
On Mon, May 05, 2025 at 11:38:29AM +0200, Alexey Gladkov 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/pci:00/:00:14.0/modalias
> pci:v8086dA36Dsv1043sd8694bc0Csc03i30
>
> $ 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
> ---
>
> 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(-)
>
> diff --git a/include/linux/module.h b/include/linux/module.h
> index 7250b4a527ec..6225793ddcd4 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -257,14 +257,10 @@ extern void cleanup_module(void);
> __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 [:][-].
> * 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..be221923f582 100644
> --- a/scripts/mod/file2alias.c
> +++ b/scripts/mod/file2alias.c
> @@ -1509,6 +1509,11 @@ void handle_moddevtable(struct module *mod, struct
> elf_info *info,
> typelen = name - type;
> name += strlen("__");
>
> + if (mod->is_vmlinux) {
> + mod = find_module(NULL, modname, modnamelen);
> + mod = mod ?: new_builtin_module(modname, modnamelen);
> + }
> +
> /* Handle all-NULL symbols allocated into .bss */
> if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
> zeros = calloc(1, sym->st_size);
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index be89921d60b6..db3c172d4528 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -168,22 +168,26 @@ char *get_line(char **stringp)
> return orig;
> }
>
> -/* A list of all modules we processed */
> +/* A list of all modules (vmlinux or *.ko) we processed */
> LIST_HEAD(modules);
>
> -static struct module *find_module(const char *filename, const char *modname)
> +/* A list of all builtin modules we processed */
> +LIST_HEAD(builtin_modules);
> +
> +struct module *find_module(const char *filename, const char *name, size_t
> namelen)
> {
> struct module *mod;
>
> list_for_each_entry(mod, &modules, list) {
> - if (!strcmp(mod->dump_file, filename) &&
> - !strcmp(mod->name, modname))
> + if ((mod->dump_file && !strcmp(mod->dump_file, filename)) &&
> + namelen != strlen(mod->name) &&
Of course there has to be an '==' here. I'll fix it if this patch fits.
> + !strncmp(mod->name, name, namelen))
> return mod;
> }
> return NULL;
> }
>
> -static struct module *new_module(const char *name, size_t namelen)
> +struct module *create_module(const char *name, size_t namelen, bool
> is_builtin)
> {
> struct module *mod;
>
> @@ -207,7 +211,10 @@ static struct module *new_module(const char *name,
> size_t namelen)
>*/
> mod->is_gpl_compatible = true;
>
> - list_add_tail(&mod->list, &modules);
> + if (is_builtin)
> + list_add_tail(&mod->list, &builtin_modules);
> + else
> + list_add_tail(&mod->list, &modules);
>
> return mod;
> }
> @@ -2021,11 +2028,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_p

