From nobody Sat Sep 27 20:31:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F3B22FC037; Thu, 18 Sep 2025 08:07:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758182841; cv=none; b=mON1fBALqn1vy7GlOsHxzwWMTWJ9UyApCIA2eHV9hLjqdAzd0Uk4BLu1LeKJyNZ4DzsxD6el4gayl2wvDBJbrifekG+l+cj0qKSyVr3fP4KVs6r5mN+TwZzeyFfEW6WxEAwlD4/msqdISo8MB+pOQVi7iX9WPVtaVgeMwF/YOro= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758182841; c=relaxed/simple; bh=vYbqTyhJdpmnCLgTyUedk6SBL2Lx8JJ3nF6Bgw6/JdM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K83JL19N7zz0pIbRmWmKctoNyyLXCAZRongL50U3JfBOQXn3xR5OEoNPqsxjYd+Sy2jLx8FzoF2A8QCAUtbrHB1nLwiIeXCaInEpvedUCMg5lvXR8B3ToVfoturjjctIa8TuacT3JqMxumg4mUjnthUGIUfjyMi6sjxfDPtCsro= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Kfp10cVK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Kfp10cVK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 148C0C4CEF0; Thu, 18 Sep 2025 08:07:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1758182838; bh=vYbqTyhJdpmnCLgTyUedk6SBL2Lx8JJ3nF6Bgw6/JdM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Kfp10cVKPJAwhRmUiL7ulatniuhZhlDLOQ73Aib603FIqO8k38K/zNntb9/2ZMaXd JcypoFnwFItghUpJZ5iSYXSVqBMlO6T0jCDRLo9AnPV1vPqH6PeDW/jQEWVrVuNq8j xx8lCNk3zpHSKqjOgLn8L5MHFkUv3PUaCO288pECbFJ+wG5+UI95KAAziCA/Fa8q0q U7T2G8/dBgUdCGMpH1GTqvfYWcsg3JYdUyOK3Se6lbITaLQVKAuJpTmT2pPaFz+13I eoeX9oGjaxtEzl09LRp8OwKrhI1nPJc3hq2IdkVDFJ51YGGbhZ32VZEdbZhTb6i8V3 aYKQKNmnDbxeg== From: Alexey Gladkov To: Nathan Chancellor , Nicolas Schier , Petr Pavlu , Luis Chamberlain , Sami Tolvanen , Daniel Gomez Cc: linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, linux-kbuild@vger.kernel.org, Alexey Gladkov , Masahiro Yamada , Stephen Rothwell Subject: [PATCH v8 7/8] modpost: Create modalias for builtin modules Date: Thu, 18 Sep 2025 10:05:51 +0200 Message-ID: <28d4da3b0e3fc8474142746bcf469e03752c3208.1758182101.git.legion@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" For some modules, modalias is generated using the modpost utility and the section is added to the module file. When a module is added inside vmlinux, modpost does not generate modalias for such modules and the information is lost. As a result kmod (which uses modules.builtin.modinfo in userspace) cannot determine that modalias is handled by a builtin kernel module. $ cat /sys/devices/pci0000:00/0000:00:14.0/modalias pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30 $ modinfo xhci_pci name: xhci_pci filename: (builtin) license: GPL file: drivers/usb/host/xhci-pci description: xHCI PCI Host Controller Driver Missing modalias "pci:v*d*sv*sd*bc0Csc03i30*" which will be generated by modpost if the module is built separately. To fix this it is necessary to generate the same modalias for vmlinux as for the individual modules. Fortunately '.vmlinux.export.o' is already generated from which '.modinfo' can be extracted in the same way as for vmlinux.o. Signed-off-by: Masahiro Yamada Signed-off-by: Alexey Gladkov Tested-by: Stephen Rothwell Reviewed-by: Nicolas Schier --- include/linux/module.h | 4 ---- scripts/Makefile.vmlinux | 4 +++- scripts/mksysmap | 3 +++ scripts/mod/file2alias.c | 19 ++++++++++++++++++- scripts/mod/modpost.c | 15 +++++++++++++++ scripts/mod/modpost.h | 2 ++ 6 files changed, 41 insertions(+), 6 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index e31ee29fac6b7..e135cc79aceea 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -256,14 +256,10 @@ struct module_kobject *lookup_or_create_module_kobjec= t(const char *name); __PASTE(type, \ __PASTE(__, name))))) =20 -#ifdef MODULE /* Creates an alias so file2alias.c can find device table. */ #define MODULE_DEVICE_TABLE(type, name) \ static typeof(name) __mod_device_table(type, name) \ __attribute__ ((used, alias(__stringify(name)))) -#else /* !MODULE */ -#define MODULE_DEVICE_TABLE(type, name) -#endif =20 /* Version of form [:][-]. * Or for CVS/RCS ID version, everything but the number is stripped. diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index ce79461714979..1e5e37aadcd05 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -89,11 +89,13 @@ endif remove-section-y :=3D .modinfo remove-section-$(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS) +=3D '.rel*' =20 +remove-symbols :=3D -w --strip-symbol=3D'__mod_device_table__*' + # To avoid warnings: "empty loadable segment detected at ..." from GNU obj= copy, # it is necessary to remove the PT_LOAD flag from the segment. quiet_cmd_strip_relocs =3D OBJCOPY $@ cmd_strip_relocs =3D $(OBJCOPY) $(patsubst %,--set-section-flags %= =3Dnoload,$(remove-section-y)) $< $@; \ - $(OBJCOPY) $(addprefix --remove-section=3D,$(remo= ve-section-y)) $@ + $(OBJCOPY) $(addprefix --remove-section=3D,$(remo= ve-section-y)) $(remove-symbols) $@ =20 targets +=3D vmlinux vmlinux: vmlinux.unstripped FORCE diff --git a/scripts/mksysmap b/scripts/mksysmap index a607a0059d119..c4531eacde202 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -59,6 +59,9 @@ # EXPORT_SYMBOL (namespace) / __kstrtabns_/d =20 +# MODULE_DEVICE_TABLE (symbol name) +/ __mod_device_table__/d + # ------------------------------------------------------------------------= --- # Ignored suffixes # (do not forget '$' after each pattern) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 1260bc2287fba..7da9735e7ab3e 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1477,7 +1477,7 @@ void handle_moddevtable(struct module *mod, struct el= f_info *info, void *symval; char *zeros =3D NULL; const char *type, *name, *modname; - size_t typelen; + size_t typelen, modnamelen; static const char *prefix =3D "__mod_device_table__"; =20 /* We're looking for a section relative symbol */ @@ -1500,6 +1500,7 @@ void handle_moddevtable(struct module *mod, struct el= f_info *info, type =3D strstr(modname, "__"); if (!type) return; + modnamelen =3D type - modname; type +=3D strlen("__"); =20 name =3D strstr(type, "__"); @@ -1526,5 +1527,21 @@ void handle_moddevtable(struct module *mod, struct e= lf_info *info, } } =20 + 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 =3D xstrndup(modname, modnamelen); + } + } + free(zeros); } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 5ca7c268294eb..47c8aa2a69392 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2067,11 +2067,26 @@ static void write_if_changed(struct buffer *b, cons= t char *fname) static void write_vmlinux_export_c_file(struct module *mod) { struct buffer buf =3D { }; + struct module_alias *alias, *next; =20 buf_printf(&buf, "#include \n"); =20 add_exported_symbols(&buf, mod); + + buf_printf(&buf, + "#include \n" + "#undef __MODULE_INFO_PREFIX\n" + "#define __MODULE_INFO_PREFIX\n"); + + list_for_each_entry_safe(alias, next, &mod->aliases, node) { + buf_printf(&buf, "MODULE_INFO(%s.alias, \"%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); } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 9133e4c3803f0..2aecb8f25c87e 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[]; }; =20 --=20 2.51.0