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

2025-05-09 Thread Alexey Gladkov
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

2025-05-08 Thread Masahiro Yamada
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

2025-05-05 Thread Alexey Gladkov
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