Add generated modalias to modules.builtin.modinfo
Subsystems (6)
cover Add generated modalias to modules.builtin.modinfo
The modules.builtin.modinfo file is used by userspace (kmod to be specific) to get information about builtin modules. Among other information about the module, information about module aliases is stored. This is very important to determine that a particular modalias will be handled by a module that is inside the kernel.
There are several mechanisms for creating modalias for modules:
The first is to explicitly specify the MODULE_ALIAS of the macro. In this case, the aliases go into the '.modinfo' section of the module if it is compiled separately or into vmlinux.o if it is builtin into the kernel.
The second is the use of MODULE_DEVICE_TABLE followed by the use of the modpost utility. In this case, vmlinux.o no longer has this information and does not get it into modules.builtin.modinfo.
For example:
$ modinfo pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30 modinfo: ERROR: Module pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30 not found.
$ modinfo xhci_pci name: xhci_pci filename: (builtin) license: GPL file: drivers/usb/host/xhci-pci description: xHCI PCI Host Controller Driver
The builtin module is missing alias "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 add the generated by modpost modalias to modules.builtin.modinfo.
Fortunately modpost already generates .vmlinux.export.c for exported symbols. It is possible to use this file to create a '.modinfo' section for builtin modules. The modules.builtin.modinfo file becomes a composite file. One part is extracted from vmlinux.o, the other part from .vmlinux.export.o.
Alexey Gladkov (7):
mfd: stmpe-spi: Correct the name used in MODULE_DEVICE_TABLE
scsi: Define MODULE_DEVICE_TABLE only if necessary
modules: Add macros to specify modinfo prefix
modpost: Make mod_device_table aliases more unique
modpost: Create modalias for builtin modules
kbuild: Move modules.builtin.modinfo to another makefile
kbuild: Create modules.builtin.modinfo for modpost results
drivers/mfd/stmpe-spi.c | 2 +- drivers/scsi/BusLogic.c | 2 +- include/linux/module.h | 21 +++++++++++----- include/linux/moduleparam.h | 7 ++++-- scripts/Makefile.vmlinux | 50 +++++++++++++++++++++++++++++++++++++ scripts/Makefile.vmlinux_o | 26 +------------------ scripts/mod/file2alias.c | 31 +++++++++++++++++++---- scripts/mod/modpost.c | 21 +++++++++++++--- scripts/mod/modpost.h | 7 +++++- 9 files changed, 123 insertions(+), 44 deletions(-)
Signature · 1 line
2.49.0
PATCH 1/7 mfd: stmpe-spi: Correct the name used in MODULE_DEVICE_TABLE
The name used in the macro does not exist.
drivers/mfd/stmpe-spi.c:132:26: error: use of undeclared identifier 'stmpe_id'
132 | MODULE_DEVICE_TABLE(spi, stmpe_id);
| ^
1 error generated.
--- drivers/mfd/stmpe-spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mfd/stmpe-spi.c +1 -1
@@ -129,7 +129,7 @@ static const struct spi_device_id stmpe_spi_id[] = { { "stmpe2403", STMPE2403 }, { } }; -MODULE_DEVICE_TABLE(spi, stmpe_id); +MODULE_DEVICE_TABLE(spi, stmpe_spi_id); static struct spi_driver stmpe_spi_driver = { .driver = {
Signature · 1 line
2.49.0
Re: [PATCH v1 1/7] mfd: stmpe-spi: Correct the name used in MODULE_DEVICE_TABLE
Quoted 6 lines · Alexey Gladkov
The name used in the macro does not exist.
drivers/mfd/stmpe-spi.c:132:26: error: use of undeclared identifier 'stmpe_id'
132 |MODULE_DEVICE_TABLE(spi, stmpe_id);
| ^
1 error generated.
P.S. You can trim the error messages to relevant parts, e.g. "1 error generated" is really redundant and not needed to store in git history.
Quoted 1 line
Best regards,
Krzysztof
Lee Jones
maintainerRe: [PATCH v1 1/7] mfd: stmpe-spi: Correct the name used in MODULE_DEVICE_TABLE
Quoted 9 lines · Krzysztof Kozlowski
Quoted 6 lines · Alexey Gladkov
The name used in the macro does not exist.
drivers/mfd/stmpe-spi.c:132:26: error: use of undeclared identifier 'stmpe_id'
132 |MODULE_DEVICE_TABLE(spi, stmpe_id);
| ^
1 error generated.
Quoted 4 lines
Reviewed-by Krzysztof Kozlowski <[email protected]>
P.S. You can trim the error messages to relevant parts, e.g. "1 error generated" is really redundant and not needed to store in git history.
Trimmed on apply, thanks.
Signature · 1 line
Lee Jones [李琼斯]
Re: (subset) [PATCH v1 1/7] mfd: stmpe-spi: Correct the name used in MODULE_DEVICE_TABLE
In reply to Alexey GladkovQuoted 8 lines · Alexey Gladkov
The name used in the macro does not exist.
drivers/mfd/stmpe-spi.c:132:26: error: use of undeclared identifier 'stmpe_id'
132 |MODULE_DEVICE_TABLE(spi, stmpe_id);
| ^
1 error generated.[...]
Applied, thanks!
[1/7] mfd: stmpe-spi: Correct the name used in MODULE_DEVICE_TABLE
commit: 7e5d7dcd96e29bb30fe7b105c53ae63a8edcd3e1
--
Lee Jones [李琼斯]
PATCH 2/7 scsi: Define MODULE_DEVICE_TABLE only if necessary
In reply to Alexey GladkovDefine MODULE_DEVICE_TABLE only if a structure is defined for it.
drivers/scsi/BusLogic.c:3735:26: error: use of undeclared identifier 'blogic_pci_tbl'
3735 | MODULE_DEVICE_TABLE(pci, blogic_pci_tbl);
| ^
1 error generated.
--- drivers/scsi/BusLogic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/BusLogic.c +1 -1
@@ -3731,8 +3731,8 @@ static const struct pci_device_id blogic_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)}, {0, }, }; -#endif MODULE_DEVICE_TABLE(pci, blogic_pci_tbl); +#endif module_init(blogic_init); module_exit(blogic_exit);
Signature · 1 line
2.49.0
PATCH 3/7 modules: Add macros to specify modinfo prefix
In reply to Alexey GladkovThe __MODULE_INFO macros always use __MODULE_INFO_PREFIX. The only way to use a different prefix is to override __MODULE_INFO_PREFIX, which is not very useful.
The new macro will be used in file2alias.c to generate modalias for builtin modules.
--- include/linux/module.h | 3 +++ include/linux/moduleparam.h | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-)
include/linux/module.h +3 -0
@@ -168,6 +168,9 @@ extern void cleanup_module(void);/* For userspace: you can also call me... */ #define MODULE_ALIAS (_alias) MODULE_INFO(alias, _alias) +#define MODULE_ALIAS_MODNAME (_modname, _alias) \ + __MODULE_INFO_WITH_PREFIX(_modname ".", alias, alias, _alias) +/* Soft module dependencies. See man modprobe.d for details. * Example: MODULE_SOFTDEP("pre: module-foo module-bar post: module-baz") */
include/linux/moduleparam.h +5 -2
@@ -20,10 +20,13 @@/* Chosen so that structs with an unsigned long line up. */ #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) -#define __MODULE_INFO (tag, name, info) \ +#define __MODULE_INFO_WITH_PREFIX (prefix, tag, name, info) \ static const char __UNIQUE_ID(name)[] \ __used __section(".modinfo") __aligned(1) \ - = __MODULE_INFO_PREFIX __stringify(tag) "=" info + = prefix __stringify(tag) "=" info + +#define __MODULE_INFO (tag, name, info) \ + __MODULE_INFO_WITH_PREFIX(__MODULE_INFO_PREFIX, tag, name, info)#define __MODULE_PARM_TYPE (name, _type) \ __MODULE_INFO(parmtype, name##type, #name ":" _type)
Signature · 1 line
2.49.0
PATCH 4/7 modpost: Make mod_device_table aliases more unique
In reply to Alexey GladkovIn order to avoid symbol conflicts if they appear in the same binary, a more unique alias identifier can be generated.
--- include/linux/module.h | 14 ++++++++++++-- scripts/mod/file2alias.c | 18 ++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-)
include/linux/module.h +12 -2
@@ -247,10 +247,20 @@ extern void cleanup_module(void);/* What your module does. */ #define MODULE_DESCRIPTION (_description) MODULE_INFO(description, _description) +/* Format: __mod_device_table__<counter>__kmod_<modname>__<type>__<name> */ +#define __mod_device_table (type, name) \ + __PASTE(__mod_device_table__, \ + __PASTE(__COUNTER__, \ + __PASTE(__, \ + __PASTE(__KBUILD_MODNAME, \ + __PASTE(__, \ + __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 \ +#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)
scripts/mod/file2alias.c +14 -4
@@ -1476,8 +1476,8 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, {void *symval;char *zeros =NULL ; -const char *type, *name; -size_t typelen; +const char *type, *name, *modname; +size_t typelen, modnamelen;static const char *prefix ="__mod_device_table__" ;/* We're looking for a section relative symbol */
@@ -1488,10 +1488,20 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,if (ELF_ST_TYPE (sym->st_info) !=STT_OBJECT )return ; -/* All our symbols are of form __mod_device_table__<type>__<name>. */ +/* All our symbols are of form __mod_device_table__<counter>__kmod_<modname>__<type>__<name>. */ if (!strstarts (symname, prefix))return ; - type = symname +strlen (prefix); + + modname =strstr (symname,"__kmod_" ); +if (!modname) +return ; + modname +=strlen ("__kmod_" ); + + type =strstr (modname,"__" ); +if (!type) +return ; + modnamelen = type - modname; + type +=strlen ("__" ); name =strstr (type,"__" );if (!name)
Signature · 1 line
2.49.0
PATCH 5/7 modpost: Create modalias for builtin modules
In reply to Alexey GladkovFor 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.
--- include/linux/module.h | 4 ---- scripts/mod/file2alias.c | 13 ++++++++++++- scripts/mod/modpost.c | 21 ++++++++++++++++++--- scripts/mod/modpost.h | 7 ++++++- 4 files changed, 36 insertions(+), 9 deletions(-)
include/linux/module.h +0 -4
@@ -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 [<epoch>:]<version>[-<extra-version>]. * Or for CVS/RCS ID version, everything but the number is stripped.
scripts/mod/file2alias.c +12 -1
@@ -1471,7 +1471,8 @@ static const struct devtable devtable[] = {/* Create MODULE_ALIAS() statements. * At this time, we cannot write the actual output C source yet, * so we write into the mod->dev_table_buf buffer. */ -void handle_moddevtable (struct module *mod,struct elf_info *info, +void handle_moddevtable (struct list_head *modules, +struct module *mod,struct elf_info *info,Elf_Sym *sym,const char *symname) {void *symval;
@@ -1509,6 +1510,16 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, typelen = name - type; name +=strlen ("__" ); +if (mod->is_vmlinux) { +struct module *builtin_mod; + + builtin_mod =new_module (modname, modnamelen); + builtin_mod->is_vmlinux = mod->is_vmlinux; + builtin_mod->dump_file =MODULE_BUILTIN_FNAME ; + + mod = builtin_mod; + } +/* Handle all-NULL symbols allocated into .bss */ if (info->sechdrs[get_secindex (info, sym)].sh_type &SHT_NOBITS ) { zeros =calloc (1 , sym->st_size);
scripts/mod/modpost.c +18 -3
@@ -183,7 +183,7 @@ static struct module *find_module(const char *filename, const char *modname)return NULL ; } -static struct module *new_module (const char *name,size_t namelen) +struct module *new_module (const char *name,size_t namelen) {struct module *mod;
@@ -1610,7 +1610,7 @@ static void read_symbols(const char *modname) symname =remove_dot (info.strtab + sym->st_name);handle_symbol (mod, &info, sym, symname); -handle_moddevtable (mod, &info, sym, symname); +handle_moddevtable (&modules, mod, &info, sym, symname); }check_sec_ref (mod, &info);
@@ -2021,11 +2021,26 @@ 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 (mod, &modules, list) { +if (!mod->is_vmlinux || !mod->dump_file || +strcmp (mod->dump_file,MODULE_BUILTIN_FNAME )) +continue ; +list_for_each_entry_safe (alias, next, &mod->aliases, node) { +buf_printf (&buf,"MODULE_ALIAS_MODNAME(\"%s\", \"%s\");\n" , + mod->name, alias->str); +list_del (&alias->node); +free (alias); + } + } +write_if_changed (&buf,".vmlinux.export.c" );free (buf.p); }
scripts/mod/modpost.h +6 -1
@@ -199,6 +199,10 @@ static inline bool is_valid_name(struct elf_info *elf, Elf_Sym *sym)return !is_mapping_symbol (name); } +#define MODULE_BUILTIN_FNAME "(builtin)" + +struct module *new_module (const char *name,size_t namelen); +/* symsearch.c */ void symsearch_init (struct elf_info *elf);void symsearch_finish (struct elf_info *elf);
@@ -207,7 +211,8 @@ Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr, Elf_Addr min_distance);/* file2alias.c */ -void handle_moddevtable (struct module *mod,struct elf_info *info, +void handle_moddevtable (struct list_head *modules, +struct module *mod,struct elf_info *info,Elf_Sym *sym,const char *symname);/* sumversion.c */
Signature · 1 line
2.49.0
kernel test robot
build botRe: [PATCH v1 5/7] modpost: Create modalias for builtin modules
kernel test robot noticed the following build errors:
Hi Alexey,
kernel test robot noticed the following build errors:
[auto build test ERROR on masahiroy-kbuild/for-next]
[also build test ERROR on masahiroy-kbuild/fixes lee-mfd/for-mfd-next mkp-scsi/for-next jejb-scsi/for-next linus/master v6.15-rc3 next-20250424] [cannot apply to mcgrof/modules-next lee-mfd/for-mfd-fixes]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Alexey-Gladkov/mfd-stmpe-spi-Correct-the-name-used-in-MODULE_DEVICE_TABLE/20250427-002149 base: https://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git for-next patch link: https://lore.kernel.org/r/bb0d887760a474e5e7f9db0e9933eee81a5d9ea3.1745591072.git.legion%40kernel.org patch subject: [PATCH v1 5/7] modpost: Create modalias for builtin modules config: alpha-defconfig (https://download.01.org/0day-ci/archive/20250428/[email protected]/config) compiler: alpha-linux-gcc (GCC) 14.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250428/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
{standard input}: Assembler messages:
>> {standard input}:79363: Error: symbol `__kstrtab___memset' is already defined
>> {standard input}:79365: Error: symbol `__kstrtabns___memset' is already defined{standard input}:79370: Error: symbol `__ksymtab___memset' is already defined
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Petr Pavlu
maintainerRe: [PATCH v1 5/7] modpost: Create modalias for builtin modules
In reply to Alexey GladkovQuoted 59 lines · Alexey Gladkov
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 DriverMissing 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 <[email protected]>--- include/linux/module.h | 4 ---- scripts/mod/file2alias.c | 13 ++++++++++++- scripts/mod/modpost.c | 21 ++++++++++++++++++--- scripts/mod/modpost.h | 7 ++++++- 4 files changed, 36 insertions(+), 9 deletions(-)include/linux/module.h +0
-4@@ -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 [<epoch>:]<version>[-<extra-version>]. * Or for CVS/RCS ID version, everything but the number is stripped. scripts/mod/file2alias.c +0
-0
scripts/mod/file2alias.c static const struct devtable devtable[] = { · line 1478
Quoted 9 lines
scripts/mod/file2alias.c +2
-1@@ -1471,7 +1471,8 @@ static const struct devtable devtable[] = {/* Create MODULE_ALIAS() statements. * At this time, we cannot write the actual output C source yet, * so we write into the mod->dev_table_buf buffer. */ -void handle_moddevtable (struct module *mod,struct elf_info *info, +void handle_moddevtable (struct list_head *modules, +struct module *mod,struct elf_info *info,Elf_Sym *sym,const char *symname) {void *symval;
The new modules parameter is unused.
scripts/mod/file2alias.c void handle_moddevtable(struct module *mod, struct elf_info *info, · line 1518
Quoted 10 lines
scripts/mod/file2alias.c +6
-0@@ -1509,6 +1510,16 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, typelen = name - type; name +=strlen ("__" ); +if (mod->is_vmlinux) { +struct module *builtin_mod; + + builtin_mod =new_module (modname, modnamelen); + builtin_mod->is_vmlinux = mod->is_vmlinux; + builtin_mod->dump_file =MODULE_BUILTIN_FNAME ;
The module.dump_file member is described in scripts/mod/modpost.h as "path to the .symvers file if loaded from a file". However, that is not the case here.
Similarly, the module struct in scripts/mod/modpost.h is commented as "represent a module (vmlinux or *.ko)", but this patch expands its scope to also include builtin modules.
I'm not sure it's best to overload this data in this way. I think mixing actual files and "logical" modules in the modules list is somewhat confusing.
An alternative would be to keep a single module struct for vmlinux and record the discovered aliases under it?
Signature · 2 lines
Thanks, Petr
Re: [PATCH v1 5/7] modpost: Create modalias for builtin modules
Quoted 63 lines · Petr Pavlu
Quoted 62 lines · Alexey Gladkov
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 DriverMissing 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 <[email protected]>--- include/linux/module.h | 4 ---- scripts/mod/file2alias.c | 13 ++++++++++++- scripts/mod/modpost.c | 21 ++++++++++++++++++--- scripts/mod/modpost.h | 7 ++++++- 4 files changed, 36 insertions(+), 9 deletions(-)include/linux/module.h +0
-4@@ -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 [<epoch>:]<version>[-<extra-version>]. * Or for CVS/RCS ID version, everything but the number is stripped. scripts/mod/file2alias.c +0
-0@@ -1471,7 +1471,8 @@ static const struct devtable devtable[] = {/* Create MODULE_ALIAS() statements. * At this time, we cannot write the actual output C source yet, * so we write into the mod->dev_table_buf buffer. */
Quoted 8 lines
scripts/mod/file2alias.c static const struct devtable devtable[] = { · line 1478
Quoted 6 lines
scripts/mod/file2alias.c +2
-1-void handle_moddevtable (struct module *mod,struct elf_info *info, +void handle_moddevtable (struct list_head *modules, +struct module *mod,struct elf_info *info,Elf_Sym *sym,const char *symname) {void *symval;The new modules parameter is unused.
Indeed. It is no longer needed after the optimization. Thank you.
Quoted 15 lines
scripts/mod/file2alias.c void handle_moddevtable(struct module *mod, struct elf_info *info, · line 1518
Quoted 10 lines
scripts/mod/file2alias.c +6
-0@@ -1509,6 +1510,16 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, typelen = name - type; name +=strlen ("__" ); +if (mod->is_vmlinux) { +struct module *builtin_mod; + + builtin_mod =new_module (modname, modnamelen); + builtin_mod->is_vmlinux = mod->is_vmlinux; + builtin_mod->dump_file =MODULE_BUILTIN_FNAME ;The module.dump_file member is described in
scripts/mod/modpost.has "path to the .symvers file if loaded from a file". However, that is not the case here.
Quoted 3 lines
Similarly, the module struct in
scripts/mod/modpost.his commented as "represent a module (vmlinux or *.ko)", but this patch expands its scope to also include builtin modules.
Well, an alternative would be to add a separate flag. I used dump_file because it allows you to exclude such "builtin" modules from processing in write_dump(), write_namespace_deps_files(), etc.
But yes, I agree that it's an abuse.
Quoted 6 lines
I'm not sure it's best to overload this data in this way. I think mixing actual files and "logical" modules in the modules list is somewhat confusing.
An alternative would be to keep a single module struct for vmlinux and record the discovered aliases under it?
It is possible to extend struct module_alias and add the module name. The problem is that alias is added by module_alias_printf() and we will have to add the module name to the arguments to each do_entry handler in addition to struct module where there is already a name (but in our case it is vmlinux).
I can do that if you think it's a better way.
Signature · 1 line
Rgrds, legion
Re: [PATCH v1 5/7] modpost: Create modalias for builtin modules
Quoted 7 lines · Alexey Gladkov
Quoted 6 lines
I'm not sure it's best to overload this data in this way. I think mixing actual files and "logical" modules in the modules list is somewhat confusing.
An alternative would be to keep a single module struct for vmlinux and record the discovered aliases under it?
Quoted 7 lines
It is possible to extend struct
module_aliasand add the module name. The problem is that alias is added bymodule_alias_printf()and we will have to add the module name to the arguments to eachdo_entryhandler in addition to struct module where there is already a name (but in our case it is vmlinux).I can do that if you think it's a better way.
If I don't add separate entries for each builtin module, the patch will look like this:
include/linux/module.h +0 -4
@@ -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 [<epoch>:]<version>[-<extra-version>]. * Or for CVS/RCS ID version, everything but the number is stripped.
scripts/mod/file2alias.c +109 -71
612 lines not on this page · raw message
scripts/mod/modpost.c +11 -1
@@ -2021,11 +2021,21 @@ 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->modname, alias->alias); +list_del (&alias->node); +free (alias); + } +write_if_changed (&buf,".vmlinux.export.c" );free (buf.p); }
scripts/mod/modpost.h +2 -0
@@ -103,6 +103,8 @@ buf_write(struct buffer *buf, const char *s, int len);*/ struct module_alias {struct list_head node; +const char *modname; +const char *alias;char str[]; };
Signature · 1 line
Rgrds, legion
Petr Pavlu
maintainerRe: [PATCH v1 5/7] modpost: Create modalias for builtin modules
Quoted 14 lines · Alexey Gladkov
Quoted 13 lines · Alexey Gladkov
Quoted 6 lines
I'm not sure it's best to overload this data in this way. I think mixing actual files and "logical" modules in the modules list is somewhat confusing.
An alternative would be to keep a single module struct for vmlinux and record the discovered aliases under it?
It is possible to extend struct
module_aliasand add the module name. The problem is that alias is added bymodule_alias_printf()and we will have to add the module name to the arguments to eachdo_entryhandler in addition to struct module where there is already a name (but in our case it is vmlinux).
Quoted 5 lines
Quoted 1 line
I can do that if you think it's a better way.
If I don't add separate entries for each builtin module, the patch will look like this:
[...]
I see, that didn't turn out as well as I envisioned. One more approach would be to track builtin modules separately. A patch is below. I'm not sure if it's better.
include/linux/module.h +0 -4
@@ -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 [<epoch>:]<version>[-<extra-version>]. * Or for CVS/RCS ID version, everything but the number is stripped.
scripts/mod/file2alias.c +6 -2
@@ -1471,8 +1471,8 @@ static const struct devtable devtable[] = {/* Create MODULE_ALIAS() statements. * At this time, we cannot write the actual output C source yet, * so we write into the mod->dev_table_buf buffer. */ -void handle_moddevtable (struct module *mod,struct elf_info *info, -Elf_Sym *sym,const char *symname) +void handle_moddevtable (struct module *mod,struct elf_info *info,Elf_Sym *sym, +const char *symname) {void *symval;char *zeros =NULL ;
@@ -1509,6 +1509,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, typelen = name - type; name +=strlen ("__" ); +if (mod->is_vmlinux) +// XXX Check if the module doesn't already exist? + mod =new_module (modname, modnamelen, true); +/* Handle all-NULL symbols allocated into .bss */ if (info->sechdrs[get_secindex (info, sym)].sh_type &SHT_NOBITS ) { zeros =calloc (1 , sym->st_size);
scripts/mod/modpost.c +24 -6
@@ -168,9 +168,12 @@ 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); +/* A list of all builtin modules we processed */ +LIST_HEAD (builtin_modules); +static struct module *find_module (const char *filename,const char *modname) {struct module *mod;
@@ -183,7 +186,7 @@ static struct module *find_module(const char *filename, const char *modname)return NULL ; } -static struct module *new_module (const char *name,size_t namelen) +struct module *new_module (const char *name,size_t namelen,bool is_builtin) {struct module *mod;
@@ -207,7 +210,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; }
@@ -1573,7 +1579,7 @@ static void read_symbols(const char *modname) }/* strip trailing .o */ - mod =new_module (modname,strlen (modname) -strlen (".o" )); + mod =new_module (modname,strlen (modname) -strlen (".o" ), false);/* save .no_trim_symbol section for later use */ if (info.no_trim_symbol_len) {
@@ -2021,11 +2027,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 (mod, &builtin_modules, list) { +list_for_each_entry_safe (alias, next, &mod->aliases, node) { +buf_printf (&buf,"MODULE_ALIAS_MODNAME(\"%s\", \"%s\");\n" , + mod->name, alias->str); +list_del (&alias->node); +free (alias); + } + } +write_if_changed (&buf,".vmlinux.export.c" );free (buf.p); }
@@ -2114,7 +2132,7 @@ static void read_dump(const char *fname) mod =find_module (fname, modname);if (!mod) { - mod =new_module (modname,strlen (modname)); + mod =new_module (modname,strlen (modname), false); mod->dump_file = fname; } s =sym_add_exported (symname, mod, gpl_only, namespace);
scripts/mod/modpost.h +3 -1
@@ -107,7 +107,7 @@ struct module_alias { };/** -* struct module - represent a module (vmlinux or *.ko) +* struct module - represent a module (vmlinux, a builtin module, or *.ko) * * @dump_file: path to the .symvers file if loaded from a file * @aliases: list head for module_aliases
@@ -199,6 +199,8 @@ static inline bool is_valid_name(struct elf_info *elf, Elf_Sym *sym)return !is_mapping_symbol (name); } +struct module *new_module (const char *name,size_t namelen,bool is_builtin); +/* symsearch.c */ void symsearch_init (struct elf_info *elf);void symsearch_finish (struct elf_info *elf);
Signature · 2 lines
Cheers, Petr
Re: [PATCH v1 5/7] modpost: Create modalias for builtin modules
Quoted 17 lines · Petr Pavlu
Quoted 16 lines · Alexey Gladkov
Quoted 14 lines · Alexey Gladkov
Quoted 6 lines
I'm not sure it's best to overload this data in this way. I think mixing actual files and "logical" modules in the modules list is somewhat confusing.
An alternative would be to keep a single module struct for vmlinux and record the discovered aliases under it?
It is possible to extend struct
module_aliasand add the module name. The problem is that alias is added bymodule_alias_printf()and we will have to add the module name to the arguments to eachdo_entryhandler in addition to struct module where there is already a name (but in our case it is vmlinux).I can do that if you think it's a better way.
Quoted 7 lines
Quoted 3 lines
If I don't add separate entries for each builtin module, the patch will look like this:
[...]I see, that didn't turn out as well as I envisioned. One more approach would be to track builtin modules separately. A patch is below. I'm not sure if it's better.
I'm not sure I get it. What do you mean when you say I need to track builtin modules separately ?
Signature · 1 line
Rgrds, legion
Petr Pavlu
maintainerRe: [PATCH v1 5/7] modpost: Create modalias for builtin modules
Quoted 22 lines · Alexey Gladkov
Quoted 21 lines · Petr Pavlu
Quoted 19 lines · Alexey Gladkov
Quoted 7 lines · Alexey Gladkov
Quoted 6 lines
I'm not sure it's best to overload this data in this way. I think mixing actual files and "logical" modules in the modules list is somewhat confusing.
An alternative would be to keep a single module struct for vmlinux and record the discovered aliases under it?
Quoted 7 lines
It is possible to extend struct
module_aliasand add the module name. The problem is that alias is added bymodule_alias_printf()and we will have to add the module name to the arguments to eachdo_entryhandler in addition to struct module where there is already a name (but in our case it is vmlinux).I can do that if you think it's a better way.
If I don't add separate entries for each builtin module, the patch will look like this:
[...]
Quoted 6 lines
Quoted 3 lines
I see, that didn't turn out as well as I envisioned. One more approach would be to track builtin modules separately. A patch is below. I'm not sure if it's better.
I'm not sure I get it. What do you mean when you say I need to track builtin modules separately ?
The patch that I sent in my reply introduces a new list called builtin_modules. This is what I meant by tracking builtin modules separately. This implementation has the advantage of not conceptually mixing the modules and allows the function write_vmlinux_export_c_file() to directly use the new list.
On the other hand, keeping everything in one list and introducing a flag for builtin modules (or maybe replacing module.is_vmlinux with some module.type enum) allows functions that take only a module pointer to know which module they are dealing with, which I imagine could be useful.
I don't have a clear preference, as long as we avoid misusing module.dump_file.
Signature · 2 lines
Thanks, Petr
PATCH v2 5/7 modpost: Create modalias for builtin modules
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.
---
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(-)
include/linux/module.h +0 -4
@@ -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 [<epoch>:]<version>[-<extra-version>]. * Or for CVS/RCS ID version, everything but the number is stripped.
scripts/mod/file2alias.c +5 -0
@@ -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);
scripts/mod/modpost.c +27 -8
@@ -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) && + !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_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 (mod, &builtin_modules, list) { +list_for_each_entry_safe (alias, next, &mod->aliases, node) { +buf_printf (&buf,"MODULE_ALIAS_MODNAME(\"%s\", \"%s\");\n" , + mod->name, alias->str); +list_del (&alias->node); +free (alias); + } + } +write_if_changed (&buf,".vmlinux.export.c" );free (buf.p); }
@@ -2112,7 +2131,7 @@ static void read_dump(const char *fname)continue ; } - mod =find_module (fname, modname); + mod =find_module (fname, modname,strlen (modname));if (!mod) { mod =new_module (modname,strlen (modname)); mod->dump_file = fname;
scripts/mod/modpost.h +14 -1
@@ -107,7 +107,7 @@ struct module_alias { };/** -* struct module - represent a module (vmlinux or *.ko) +* struct module - represent a module (vmlinux, a builtin module, or *.ko) * * @dump_file: path to the .symvers file if loaded from a file * @aliases: list head for module_aliases
@@ -199,6 +199,19 @@ static inline bool is_valid_name(struct elf_info *elf, Elf_Sym *sym)return !is_mapping_symbol (name); } +struct module *find_module (const char *filename,const char *name,size_t namelen); +struct module *create_module (const char *name,size_t namelen,bool is_builtin); + +static inline struct module *new_module (const char *name,size_t namelen) +{ +return create_module (name, namelen, false); +} + +static inline struct module *new_builtin_module (const char *name,size_t namelen) +{ +return create_module (name, namelen, true); +} +/* symsearch.c */ void symsearch_init (struct elf_info *elf);void symsearch_finish (struct elf_info *elf);
Signature · 1 line
2.49.0
Re: [PATCH v2 5/7] modpost: Create modalias for builtin modules
Quoted 90 lines · Alexey Gladkov
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 DriverMissing 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 <[email protected]>---
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(-)include/linux/module.h +0
-4@@ -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 [<epoch>:]<version>[-<extra-version>]. * Or for CVS/RCS ID version, everything but the number is stripped. scripts/mod/file2alias.c +5
-0@@ -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);scripts/mod/modpost.c +3
-2@@ -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);
scripts/mod/modpost.c char *get_line(char **stringp) · line 183
Quoted 10 lines
scripts/mod/modpost.c +4
-2+ +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.
Quoted 93 lines
scripts/mod/modpost.c +20
-4+ !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_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 (mod, &builtin_modules, list) { +list_for_each_entry_safe (alias, next, &mod->aliases, node) { +buf_printf (&buf,"MODULE_ALIAS_MODNAME(\"%s\", \"%s\");\n" , + mod->name, alias->str); +list_del (&alias->node); +free (alias); + } + } +write_if_changed (&buf,".vmlinux.export.c" );free (buf.p); }@@ -2112,7 +2131,7 @@ static void read_dump(const char *fname)continue ; } - mod =find_module (fname, modname); + mod =find_module (fname, modname,strlen (modname));if (!mod) { mod =new_module (modname,strlen (modname)); mod->dump_file = fname;scripts/mod/modpost.h +14
-1@@ -107,7 +107,7 @@ struct module_alias { };/** -* struct module - represent a module (vmlinux or *.ko) +* struct module - represent a module (vmlinux, a builtin module, or *.ko) * * @dump_file: path to the .symvers file if loaded from a file * @aliases: list head for module_aliases @@ -199,6 +199,19 @@ static inline bool is_valid_name(struct elf_info *elf, Elf_Sym *sym)return !is_mapping_symbol (name); } +struct module *find_module (const char *filename,const char *name,size_t namelen); +struct module *create_module (const char *name,size_t namelen,bool is_builtin); + +static inline struct module *new_module (const char *name,size_t namelen) +{ +return create_module (name, namelen, false); +} + +static inline struct module *new_builtin_module (const char *name,size_t namelen) +{ +return create_module (name, namelen, true); +} +/* symsearch.c */ void symsearch_init (struct elf_info *elf);void symsearch_finish (struct elf_info *elf);Signature · 1 line
2.49.0
Signature · 1 line
Rgrds, legion
Re: [PATCH v2 5/7] modpost: Create modalias for builtin modules
In reply to Alexey GladkovQuoted 37 lines · Alexey Gladkov
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 DriverMissing 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 <[email protected]>---
v2: As Petr Pavlu suggested, I separated the builtin modules from the external
modules. I've also added a search for duplicate modules.
Quoted 6 lines
--- 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.
Signature · 2 lines
Best Regards Masahiro Yamada
From 28b8431db696b15a5812d6ca0a7372a30e060cfb Mon Sep 17 00:00:00 2001
From: Masahiro Yamada <[email protected]>
Date: Fri, 9 May 2025 00:22:46 +0900
Subject: [PATCH] Another simple implementation
--- 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(-)
include/linux/module.h +0 -4
@@ -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.
scripts/mod/file2alias.c +16 -0
@@ -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); }
scripts/mod/modpost.c +13 -1
@@ -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); }
scripts/mod/modpost.h +2 -0
@@ -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[]; };
Signature · 1 line
2.43.0
Re: [PATCH v2 5/7] modpost: Create modalias for builtin modules
Quoted 46 lines · Masahiro Yamada
Quoted 37 lines · Alexey Gladkov
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 DriverMissing 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 <[email protected]>---
v2: As Petr Pavlu suggested, I separated the builtin modules from the external
modules. I've also added a search for duplicate modules.Quoted 6 lines
--- 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(-)
Quoted 3 lines
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!
Signature · 1 line
Rgrds, legion
PATCH 6/7 kbuild: Move modules.builtin.modinfo to another makefile
In reply to Alexey GladkovThe creation of modules.builtin.modinfo is going to depend on .vmlinux.export.o so it is worth moving its creation closer to it.
--- scripts/Makefile.vmlinux | 26 ++++++++++++++++++++++++++ scripts/Makefile.vmlinux_o | 26 +------------------------- 2 files changed, 27 insertions(+), 25 deletions(-)
scripts/Makefile.vmlinux +26 -0
@@ -97,6 +97,32 @@ ifdef CONFIG_BUILDTIME_TABLE_SORT vmlinux: scripts/sorttable endif +# module.builtin.modinfo +# --------------------------------------------------------------------------- +__default: modules.builtin.modinfo + +OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary + +targets += modules.builtin.modinfo +modules.builtin.modinfo: vmlinux.o FORCE + $(call if_changed,objcopy) + +# module.builtin +# --------------------------------------------------------------------------- +__default: modules.builtin + +# The second line aids cases where multiple modules share the same object. + +quiet_cmd_modules_builtin = GEN $@ + cmd_modules_builtin = \ + tr '\0' '\n' < $< | \ + sed -n 's/^[[:alnum:]:_]*\.file=//p' | \ + tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@ + +targets += modules.builtin +modules.builtin: modules.builtin.modinfo FORCE + $(call if_changed,modules_builtin) + # module.builtin.ranges # --------------------------------------------------------------------------- ifdef CONFIG_BUILTIN_MODULE_RANGES
scripts/Makefile.vmlinux_o +1 -25
@@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only PHONY := __default -__default: vmlinux.o modules.builtin.modinfo modules.builtin +__default: vmlinux.o include include/config/auto.conf include $(srctree)/scripts/Kbuild.include
@@ -73,30 +73,6 @@ vmlinux.o: $(initcalls-lds) vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE targets += vmlinux.o -# module.builtin.modinfo -# --------------------------------------------------------------------------- - -OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary - -targets += modules.builtin.modinfo -modules.builtin.modinfo: vmlinux.o FORCE - $(call if_changed,objcopy) - -# module.builtin -# --------------------------------------------------------------------------- - -# The second line aids cases where multiple modules share the same object. - -quiet_cmd_modules_builtin = GEN $@ - cmd_modules_builtin = \ - tr '\0' '\n' < $< | \ - sed -n 's/^[[:alnum:]:_]*\.file=//p' | \ - tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@ - -targets += modules.builtin -modules.builtin: modules.builtin.modinfo FORCE - $(call if_changed,modules_builtin) - # Add FORCE to the prerequisites of a target to force it to be always rebuilt. # ---------------------------------------------------------------------------
Signature · 1 line
2.49.0
PATCH 7/7 kbuild: Create modules.builtin.modinfo for modpost results
In reply to Alexey GladkovCreate modules.builtin.modinfo as a combination of modinfo from vmlinux and the result of generating modalias by modpost.
--- scripts/Makefile.vmlinux | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-)
scripts/Makefile.vmlinux +27 -3
@@ -70,6 +70,18 @@ endif ifdef CONFIG_MODULES targets += .vmlinux.export.o $(vmlinux-final): .vmlinux.export.o + +# .module.builtin.modinfo.modpost +# --------------------------------------------------------------------------- +__default: .modules.builtin.modinfo.modpost + +OBJCOPYFLAGS_.modules.builtin.modinfo.modpost := -j .modinfo -O binary + +targets += .modules.builtin.modinfo.modpost +.modules.builtin.modinfo.modpost: .vmlinux.export.o FORCE + $(call if_changed,objcopy) + +modules.builtin.modinfo: .modules.builtin.modinfo.modpost endif ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX
@@ -97,15 +109,27 @@ ifdef CONFIG_BUILDTIME_TABLE_SORT vmlinux: scripts/sorttable endif +# .module.builtin.modinfo.vmlinux +# --------------------------------------------------------------------------- +__default: .modules.builtin.modinfo.vmlinux + +OBJCOPYFLAGS_.modules.builtin.modinfo.vmlinux := -j .modinfo -O binary + +targets += .modules.builtin.modinfo.vmlinux +.modules.builtin.modinfo.vmlinux: vmlinux.o FORCE + $(call if_changed,objcopy) + # module.builtin.modinfo # --------------------------------------------------------------------------- __default: modules.builtin.modinfo -OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary +quiet_cmd_modules_builtin_modinfo = GEN $@ + cmd_modules_builtin_modinfo = \ + cat $< $(wildcard .modules.builtin.modinfo.modpost) > $@ targets += modules.builtin.modinfo -modules.builtin.modinfo: vmlinux.o FORCE - $(call if_changed,objcopy) +modules.builtin.modinfo: .modules.builtin.modinfo.vmlinux FORCE + $(call if_changed,modules_builtin_modinfo) # module.builtin # ---------------------------------------------------------------------------
Signature · 1 line
2.49.0
Petr Pavlu
maintainerQuoted 28 lines · Alexey Gladkov
The modules.builtin.modinfo file is used by userspace (kmod to be specific) to get information about builtin modules. Among other information about the module, information about module aliases is stored. This is very important to determine that a particular modalias will be handled by a module that is inside the kernel.
There are several mechanisms for creating modalias for modules:
The first is to explicitly specify the
MODULE_ALIASof the macro. In this case, the aliases go into the '.modinfo' section of the module if it is compiled separately or into vmlinux.o if it is builtin into the kernel.The second is the use of
MODULE_DEVICE_TABLEfollowed by the use of the modpost utility. In this case, vmlinux.o no longer has this information and does not get it into modules.builtin.modinfo.For example:
$ modinfo pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30 modinfo: ERROR: Module pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30 not found.$ modinfo xhci_pci name: xhci_pci filename: (builtin) license: GPL file: drivers/usb/host/xhci-pci description: xHCI PCI Host Controller Driver
Quoted 2 lines
The builtin module is missing alias "pci:v*d*sv*sd*bc0Csc03i30*" which will be generated by modpost if the module is built separately.
Could you explain what is currently broken because the device-table alias information isn't available? I think adding this information is reasonable, both for consistency and so kmod can display accurate information, but is there more that I'm missing?
Signature · 2 lines
Thanks, Petr
Quoted 29 lines · Petr Pavlu
Quoted 28 lines · Alexey Gladkov
The modules.builtin.modinfo file is used by userspace (kmod to be specific) to get information about builtin modules. Among other information about the module, information about module aliases is stored. This is very important to determine that a particular modalias will be handled by a module that is inside the kernel.
There are several mechanisms for creating modalias for modules:
The first is to explicitly specify the
MODULE_ALIASof the macro. In this case, the aliases go into the '.modinfo' section of the module if it is compiled separately or into vmlinux.o if it is builtin into the kernel.The second is the use of
MODULE_DEVICE_TABLEfollowed by the use of the modpost utility. In this case, vmlinux.o no longer has this information and does not get it into modules.builtin.modinfo.For example:
$ modinfo pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30 modinfo: ERROR: Module pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30 not found.$ modinfo xhci_pci name: xhci_pci filename: (builtin) license: GPL file: drivers/usb/host/xhci-pci description: xHCI PCI Host Controller Driver
Quoted 7 lines
Quoted 2 lines
The builtin module is missing alias "pci:v*d*sv*sd*bc0Csc03i30*" which will be generated by modpost if the module is built separately.
Could you explain what is currently broken because the device-table alias information isn't available? I think adding this information is reasonable, both for consistency and so kmod can display accurate information, but is there more that I'm missing?
Yes. Right now, aliases that are generated by modpost are not available for kmod because it's not in the modules.builtin.modinfo.
Signature · 1 line
Rgrds, legion
v2 cover Add generated modalias to modules.builtin.modinfo
In reply to Alexey GladkovThe modules.builtin.modinfo file is used by userspace (kmod to be specific) to get information about builtin modules. Among other information about the module, information about module aliases is stored. This is very important to determine that a particular modalias will be handled by a module that is inside the kernel.
There are several mechanisms for creating modalias for modules:
The first is to explicitly specify the MODULE_ALIAS of the macro. In this case, the aliases go into the '.modinfo' section of the module if it is compiled separately or into vmlinux.o if it is builtin into the kernel.
The second is the use of MODULE_DEVICE_TABLE followed by the use of the modpost utility. In this case, vmlinux.o no longer has this information and does not get it into modules.builtin.modinfo.
For example:
$ modinfo pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30 modinfo: ERROR: Module pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30 not found.
$ modinfo xhci_pci name: xhci_pci filename: (builtin) license: GPL file: drivers/usb/host/xhci-pci description: xHCI PCI Host Controller Driver
The builtin module is missing alias "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 add the generated by modpost modalias to modules.builtin.modinfo.
Fortunately modpost already generates .vmlinux.export.c for exported symbols. It is possible to use this file to create a '.modinfo' section for builtin modules. The modules.builtin.modinfo file becomes a composite file. One part is extracted from vmlinux.o, the other part from .vmlinux.export.o.
Notes:
- v2:
* Drop patch for mfd because it was already applied and is in linux-next.
* The generation of aliases for builtin modules has been redone as suggested by Masahiro Yamada.
* Rebase to v6.15-rc5-136-g9c69f8884904
* v1: https://lore.kernel.org/all/[email protected]/
Alexey Gladkov (6):
scsi: Define MODULE_DEVICE_TABLE only if necessary
modules: Add macros to specify modinfo prefix
modpost: Make mod_device_table aliases more unique
modpost: Create modalias for builtin modules
kbuild: Move modules.builtin.modinfo to another makefile
kbuild: Create modules.builtin.modinfo for modpost results
drivers/scsi/BusLogic.c | 2 +- include/linux/module.h | 21 +++++++++++----- include/linux/moduleparam.h | 7 ++++-- scripts/Makefile.vmlinux | 50 +++++++++++++++++++++++++++++++++++++ scripts/Makefile.vmlinux_o | 26 +------------------ scripts/mod/file2alias.c | 34 ++++++++++++++++++++++--- scripts/mod/modpost.c | 13 +++++++++- scripts/mod/modpost.h | 2 ++ 8 files changed, 116 insertions(+), 39 deletions(-)
Signature · 1 line
2.49.0
PATCH v2 1/6 scsi: Define MODULE_DEVICE_TABLE only if necessary
In reply to Alexey GladkovDefine MODULE_DEVICE_TABLE only if a structure is defined for it.
drivers/scsi/BusLogic.c:3735:26: error: use of undeclared identifier 'blogic_pci_tbl'
3735 | MODULE_DEVICE_TABLE(pci, blogic_pci_tbl);
--- drivers/scsi/BusLogic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/BusLogic.c +1 -1
@@ -3731,8 +3731,8 @@ static const struct pci_device_id blogic_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)}, {0, }, }; -#endif MODULE_DEVICE_TABLE(pci, blogic_pci_tbl); +#endif module_init(blogic_init); module_exit(blogic_exit);
Signature · 1 line
2.49.0
PATCH v2 2/6 modules: Add macros to specify modinfo prefix
In reply to Alexey GladkovThe __MODULE_INFO macros always use __MODULE_INFO_PREFIX. The only way to use a different prefix is to override __MODULE_INFO_PREFIX, which is not very useful.
The new macro will be used in file2alias.c to generate modalias for builtin modules.
--- include/linux/module.h | 3 +++ include/linux/moduleparam.h | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-)
include/linux/module.h +3 -0
@@ -170,6 +170,9 @@ struct module_kobject *lookup_or_create_module_kobject(const char *name);/* For userspace: you can also call me... */ #define MODULE_ALIAS (_alias) MODULE_INFO(alias, _alias) +#define MODULE_ALIAS_MODNAME (_modname, _alias) \ + __MODULE_INFO_WITH_PREFIX(_modname ".", alias, alias, _alias) +/* Soft module dependencies. See man modprobe.d for details. * Example: MODULE_SOFTDEP("pre: module-foo module-bar post: module-baz") */
include/linux/moduleparam.h +5 -2
@@ -20,10 +20,13 @@/* Chosen so that structs with an unsigned long line up. */ #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) -#define __MODULE_INFO (tag, name, info) \ +#define __MODULE_INFO_WITH_PREFIX (prefix, tag, name, info) \ static const char __UNIQUE_ID(name)[] \ __used __section(".modinfo") __aligned(1) \ - = __MODULE_INFO_PREFIX __stringify(tag) "=" info + = prefix __stringify(tag) "=" info + +#define __MODULE_INFO (tag, name, info) \ + __MODULE_INFO_WITH_PREFIX(__MODULE_INFO_PREFIX, tag, name, info)#define __MODULE_PARM_TYPE (name, _type) \ __MODULE_INFO(parmtype, name##type, #name ":" _type)
Signature · 1 line
2.49.0
Re: [PATCH v2 2/6] modules: Add macros to specify modinfo prefix
Quoted 8 lines · Alexey Gladkov
The
__MODULE_INFOmacros always use__MODULE_INFO_PREFIX. The only way to use a different prefix is to override__MODULE_INFO_PREFIX, which is not very useful.The new macro will be used in
file2alias.cto generate modalias for builtin modules.Signed-off-by Alexey Gladkov <[email protected]>
-- Petr
PATCH v2 3/6 modpost: Make mod_device_table aliases more unique
In reply to Alexey GladkovIn order to avoid symbol conflicts if they appear in the same binary, a more unique alias identifier can be generated.
--- include/linux/module.h | 14 ++++++++++++-- scripts/mod/file2alias.c | 18 ++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-)
include/linux/module.h +12 -2
@@ -249,10 +249,20 @@ struct module_kobject *lookup_or_create_module_kobject(const char *name);/* What your module does. */ #define MODULE_DESCRIPTION (_description) MODULE_INFO(description, _description) +/* Format: __mod_device_table__<counter>__kmod_<modname>__<type>__<name> */ +#define __mod_device_table (type, name) \ + __PASTE(__mod_device_table__, \ + __PASTE(__COUNTER__, \ + __PASTE(__, \ + __PASTE(__KBUILD_MODNAME, \ + __PASTE(__, \ + __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 \ +#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)
scripts/mod/file2alias.c +14 -4
@@ -1476,8 +1476,8 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, {void *symval;char *zeros =NULL ; -const char *type, *name; -size_t typelen; +const char *type, *name, *modname; +size_t typelen, modnamelen;static const char *prefix ="__mod_device_table__" ;/* We're looking for a section relative symbol */
@@ -1488,10 +1488,20 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,if (ELF_ST_TYPE (sym->st_info) !=STT_OBJECT )return ; -/* All our symbols are of form __mod_device_table__<type>__<name>. */ +/* All our symbols are of form __mod_device_table__<counter>__kmod_<modname>__<type>__<name>. */ if (!strstarts (symname, prefix))return ; - type = symname +strlen (prefix); + + modname =strstr (symname,"__kmod_" ); +if (!modname) +return ; + modname +=strlen ("__kmod_" ); + + type =strstr (modname,"__" ); +if (!type) +return ; + modnamelen = type - modname; + type +=strlen ("__" ); name =strstr (type,"__" );if (!name)
Signature · 1 line
2.49.0
Re: [PATCH v2 3/6] modpost: Make mod_device_table aliases more unique
Quoted 4 lines · Alexey Gladkov
In order to avoid symbol conflicts if they appear in the same binary, a more unique alias identifier can be generated.
Signed-off-by Alexey Gladkov <[email protected]>
-- Petr
PATCH v2 4/6 modpost: Create modalias for builtin modules
In reply to Alexey GladkovFor 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.
--- include/linux/module.h | 4 ---- scripts/mod/file2alias.c | 16 ++++++++++++++++ scripts/mod/modpost.c | 13 ++++++++++++- scripts/mod/modpost.h | 2 ++ 4 files changed, 30 insertions(+), 5 deletions(-)
include/linux/module.h +0 -4
@@ -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.
scripts/mod/file2alias.c +16 -0
@@ -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); }
scripts/mod/modpost.c +12 -1
@@ -2021,11 +2021,22 @@ 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); +free (alias->builtin_modname); +free (alias); + } +write_if_changed (&buf,".vmlinux.export.c" );free (buf.p); }
scripts/mod/modpost.h +2 -0
@@ -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[]; };
Signature · 1 line
2.49.0
Re: [PATCH v2 4/6] modpost: Create modalias for builtin modules
Quoted 22 lines · Alexey Gladkov
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 DriverMissing modalias "pci:v*d*sv*sd*bc0Csc03i30*" which will be generated by modpost if the module is built separately.
Quoted 7 lines
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 Masahiro Yamada <[email protected]>Signed-off-by Alexey Gladkov <[email protected]>
-- Petr
PATCH v2 5/6 kbuild: Move modules.builtin.modinfo to another makefile
In reply to Alexey GladkovThe creation of modules.builtin.modinfo is going to depend on .vmlinux.export.o so it is worth moving its creation closer to it.
--- scripts/Makefile.vmlinux | 26 ++++++++++++++++++++++++++ scripts/Makefile.vmlinux_o | 26 +------------------------- 2 files changed, 27 insertions(+), 25 deletions(-)
scripts/Makefile.vmlinux +26 -0
@@ -97,6 +97,32 @@ ifdef CONFIG_BUILDTIME_TABLE_SORT vmlinux: scripts/sorttable endif +# module.builtin.modinfo +# --------------------------------------------------------------------------- +__default: modules.builtin.modinfo + +OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary + +targets += modules.builtin.modinfo +modules.builtin.modinfo: vmlinux.o FORCE + $(call if_changed,objcopy) + +# module.builtin +# --------------------------------------------------------------------------- +__default: modules.builtin + +# The second line aids cases where multiple modules share the same object. + +quiet_cmd_modules_builtin = GEN $@ + cmd_modules_builtin = \ + tr '\0' '\n' < $< | \ + sed -n 's/^[[:alnum:]:_]*\.file=//p' | \ + tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@ + +targets += modules.builtin +modules.builtin: modules.builtin.modinfo FORCE + $(call if_changed,modules_builtin) + # module.builtin.ranges # --------------------------------------------------------------------------- ifdef CONFIG_BUILTIN_MODULE_RANGES
scripts/Makefile.vmlinux_o +1 -25
@@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only PHONY := __default -__default: vmlinux.o modules.builtin.modinfo modules.builtin +__default: vmlinux.o include include/config/auto.conf include $(srctree)/scripts/Kbuild.include
@@ -73,30 +73,6 @@ vmlinux.o: $(initcalls-lds) vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE targets += vmlinux.o -# module.builtin.modinfo -# --------------------------------------------------------------------------- - -OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary - -targets += modules.builtin.modinfo -modules.builtin.modinfo: vmlinux.o FORCE - $(call if_changed,objcopy) - -# module.builtin -# --------------------------------------------------------------------------- - -# The second line aids cases where multiple modules share the same object. - -quiet_cmd_modules_builtin = GEN $@ - cmd_modules_builtin = \ - tr '\0' '\n' < $< | \ - sed -n 's/^[[:alnum:]:_]*\.file=//p' | \ - tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@ - -targets += modules.builtin -modules.builtin: modules.builtin.modinfo FORCE - $(call if_changed,modules_builtin) - # Add FORCE to the prerequisites of a target to force it to be always rebuilt. # ---------------------------------------------------------------------------
Signature · 1 line
2.49.0
PATCH v2 6/6 kbuild: Create modules.builtin.modinfo for modpost results
In reply to Alexey GladkovCreate modules.builtin.modinfo as a combination of modinfo from vmlinux and the result of generating modalias by modpost.
--- scripts/Makefile.vmlinux | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-)
scripts/Makefile.vmlinux +27 -3
@@ -70,6 +70,18 @@ endif ifdef CONFIG_MODULES targets += .vmlinux.export.o $(vmlinux-final): .vmlinux.export.o + +# .module.builtin.modinfo.modpost +# --------------------------------------------------------------------------- +__default: .modules.builtin.modinfo.modpost + +OBJCOPYFLAGS_.modules.builtin.modinfo.modpost := -j .modinfo -O binary + +targets += .modules.builtin.modinfo.modpost +.modules.builtin.modinfo.modpost: .vmlinux.export.o FORCE + $(call if_changed,objcopy) + +modules.builtin.modinfo: .modules.builtin.modinfo.modpost endif ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX
@@ -97,15 +109,27 @@ ifdef CONFIG_BUILDTIME_TABLE_SORT vmlinux: scripts/sorttable endif +# .module.builtin.modinfo.vmlinux +# --------------------------------------------------------------------------- +__default: .modules.builtin.modinfo.vmlinux + +OBJCOPYFLAGS_.modules.builtin.modinfo.vmlinux := -j .modinfo -O binary + +targets += .modules.builtin.modinfo.vmlinux +.modules.builtin.modinfo.vmlinux: vmlinux.o FORCE + $(call if_changed,objcopy) + # module.builtin.modinfo # --------------------------------------------------------------------------- __default: modules.builtin.modinfo -OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary +quiet_cmd_modules_builtin_modinfo = GEN $@ + cmd_modules_builtin_modinfo = \ + cat $< $(wildcard .modules.builtin.modinfo.modpost) > $@ targets += modules.builtin.modinfo -modules.builtin.modinfo: vmlinux.o FORCE - $(call if_changed,objcopy) +modules.builtin.modinfo: .modules.builtin.modinfo.vmlinux FORCE + $(call if_changed,modules_builtin_modinfo) # module.builtin # ---------------------------------------------------------------------------
Signature · 1 line
2.49.0