Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp3180839pxb; Tue, 19 Jan 2021 16:25:18 -0800 (PST) X-Google-Smtp-Source: ABdhPJwQDL8djykocI2MVFe/GuCg4NqW+IElVYmY7Zpe9UdxqAVVjXo2254uuyztrWNpPVS7B4AF X-Received: by 2002:a17:906:a84a:: with SMTP id dx10mr4619185ejb.13.1611102317801; Tue, 19 Jan 2021 16:25:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1611102317; cv=none; d=google.com; s=arc-20160816; b=s6ou6zwYuCdsfZfgT+9IROWNjbsfjkLsCVLCySWq078uv7NCk4UPW02yfDMOxKEPh2 2zBoJW/UnRFrNaL0WQxuSmVCsrCRZ/04429Cd63dtfthnuRFKSTNxSjgXwdPQlctfd2R Tlv4JBuH+3WO8A4+KfaP34tU5KNFc8j9LNsOHADXSPDWc8h1Cf19qWrk9ytYuRp+3GTW NbIcteMvGRTiD6MiwWxvok1k82w3rwe9vWVzCk4V4og3i63jh/o8mRiXalgESN3AqWRB CiW1zXZv53anf90MHSYfCANRHzeoaYp8ncmsoe/vA9rwy/SVrNrsAcR9rmk7mV7gpxN6 7dCg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=7kfbV0Qzt+pmUiMe0QaaqHxOAXEcZkVZL3jAdqBSxAI=; b=fmGemC8hKPr0KbFZ384wwYCX1qbvE7TXm0PFvemgDrgKnMyeBeGg+jbwh0ZDPRHc0y dSTq7iFSLzdtgZUz6pp4bSPZgtQKUHOvlhMWtXQHAzI2rEvuXYVJ0dVWfmC+gdfSAEXu QhCCrlDwznCWue0auzuEVgCwWGycqItXo0aOP7n12huQa+TDN++3aHbxa9SJIecyvSlr lTooWtm87apay9KUBco/Tir4ZgF7NHJlOn8/h9jTtGCb5YeGww6SBDMZaapL93DZR3J+ vyTIOMc6w1+CFIGQLQD3JdK64vFqSaMpi88cDqRTk/reoDpmJZicDcAl7ngia1mYZXmj DYNQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=OXI7W5ud; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c13si183563ede.559.2021.01.19.16.24.49; Tue, 19 Jan 2021 16:25:17 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=OXI7W5ud; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729187AbhATAUr (ORCPT + 99 others); Tue, 19 Jan 2021 19:20:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39348 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730831AbhATAT7 (ORCPT ); Tue, 19 Jan 2021 19:19:59 -0500 Received: from mail-lj1-x229.google.com (mail-lj1-x229.google.com [IPv6:2a00:1450:4864:20::229]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4EA10C061796 for ; Tue, 19 Jan 2021 16:19:05 -0800 (PST) Received: by mail-lj1-x229.google.com with SMTP id 3so3829151ljc.4 for ; Tue, 19 Jan 2021 16:19:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=7kfbV0Qzt+pmUiMe0QaaqHxOAXEcZkVZL3jAdqBSxAI=; b=OXI7W5ude/vwnzkqquQyKprdR/f5Ld6hQOFx7BAtL7uCFIFWfhIGtRqrKtOY6ziiOm xcMhEbeOOjj2kBToRdFRIOkNBsZbHXz2xe3l9am39i7xWtT/naVntPKS0kaF/bJqm/4z tErmcnHQ5ih3bAPsDg5NPe0ysQrNT4nevhW5Ot2CpVvUJ9ebftxWDDVV8U3u30rRphNh 0+Y968aff0Fi4w9tmuFlfLStrZhrBEGJPY6XiXuAAB2lVGLkcSpDKF2qFKOTyoC7L1lJ DSUh6B20AyzYyX9Zpd2PzVjsPSIYIULSycgTCumL6SugkGKC7sZjYk8199kP2SQhfS5I 580Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=7kfbV0Qzt+pmUiMe0QaaqHxOAXEcZkVZL3jAdqBSxAI=; b=iCvoXOBq8zF955YtKXGb25R1yv5eFbDWmnN7LFpeMnuRYgWY12z/RXIS1QJiY5HlaE MMF9hUk2YX+6g3BE9VHqxnz6j5jvlR1unFLcNyI2F85kaYhOMe9Be24tNrEMdweBXs+i 3KgSbb8PiAoLICUaHmds+lsYBEzo7ZVHtd/koLIsrpYXqi6bB6K2jWhQvsQouF4pZH8A yak2rOZp16QhZIcRTk5edsEnMetqSr7Qm24gYtkxiy/62ds9GHi6EO8SG9B4oPisZFA7 IvCjWWnVAd3CTJxLYyGCwMW/7sppoHGc/04R8ygkLcQ0oyEJ63QyFSqLe3KRpPzchtjg 0mcA== X-Gm-Message-State: AOAM530LvpNWuKhh/ez+06vtcy1a+HyzD4jHS31WP9ado8V5csz3LaEu 70Oo8zPWXrovsOw2hZFZ6SA0YN2j7XNBRSdSqXotEg== X-Received: by 2002:a2e:240f:: with SMTP id k15mr3113707ljk.506.1611101943465; Tue, 19 Jan 2021 16:19:03 -0800 (PST) MIME-Version: 1.0 References: <20210108003035.1930475-1-willmcvicker@google.com> In-Reply-To: From: Will McVicker Date: Tue, 19 Jan 2021 16:18:47 -0800 Message-ID: Subject: Re: [PATCH v5] modules: introduce the MODULE_SCMVERSION config To: Masahiro Yamada Cc: Jessica Yu , Michal Marek , Greg Kroah-Hartman , Christoph Hellwig , Saravana Kannan , Linux Kernel Mailing List , Linux Kbuild mailing list , "Cc: Android Kernel" Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Masahiro, After testing your suggestions for module_srcpath, I remembered why I needed this: +ifneq ($(realpath $(srctree)/$(KBUILD_EXTMOD) 2>/dev/null),) + module_srcpath := $(srctree)/$(KBUILD_EXTMOD) +else + module_srcpath := $(KBUILD_EXTMOD) +endif Basically KBUILD_EXTMOD actually has two uses when defined as a relative path: (1) defines the path to the external module's source relative to $(srctree) (2) defines the path to the external module's build artifacts relative to $(objtree) Since setlocalversion is run from $(objtree), we need to use $(srctree)/$(KBUILD_EXTMOD) when it's a relative path. Just to note, if I do just use KBUILD_EXTMOD, then the script setlocalversion fails to find the srctree and returns an empty string. Please correct me if I'm wrong. I messed around with this by adding many prints to Makefile.modpost and setlocalversion to make sure everything was defined as expected. Thanks, Will On Tue, Jan 19, 2021 at 1:48 PM Will McVicker wrote: > > Thanks for the review Masahiro! I'll upload v6 shortly. > > --Will > > On Sun, Jan 17, 2021 at 7:21 AM Masahiro Yamada wrote: > > > > On Fri, Jan 8, 2021 at 9:30 AM Will McVicker wrote: > > > > > > Config MODULE_SCMVERSION introduces a new module attribute -- > > > `scmversion` -- which can be used to identify a given module's SCM > > > version. This is very useful for developers that update their kernel > > > independently from their kernel modules or vice-versa since the SCM > > > version provided by UTS_RELEASE (`uname -r`) will now differ from the > > > module's vermagic attribute. > > > > > > For example, we have a CI setup that tests new kernel changes on the > > > hikey960 and db845c devices without updating their kernel modules. When > > > these tests fail, we need to be able to identify the exact device > > > configuration the test was using. By including MODULE_SCMVERSION, we can > > > identify the exact kernel and modules' SCM versions for debugging the > > > failures. > > > > > > Additionally, by exposing the SCM version via the sysfs node > > > /sys/module/MODULENAME/scmversion, one can also verify the SCM versions > > > of the modules loaded from the initramfs. Currently, modinfo can only > > > retrieve module attributes from the module's ko on disk and not from the > > > actual module that is loaded in RAM. > > > > > > You can retrieve the SCM version in two ways, > > > > > > 1) By using modinfo: > > > > modinfo -F scmversion MODULENAME > > > 2) By module sysfs node: > > > > cat /sys/module/MODULENAME/scmversion > > > > > > Signed-off-by: Will McVicker > > > --- > > > Documentation/ABI/stable/sysfs-module | 18 ++++++++++++++++++ > > > include/linux/module.h | 1 + > > > init/Kconfig | 14 ++++++++++++++ > > > kernel/module.c | 2 ++ > > > scripts/Makefile.modpost | 22 ++++++++++++++++++++++ > > > scripts/mod/modpost.c | 24 +++++++++++++++++++++++- > > > 6 files changed, 80 insertions(+), 1 deletion(-) > > > > > > diff --git a/Documentation/ABI/stable/sysfs-module b/Documentation/ABI/stable/sysfs-module > > > index 6272ae5fb366..a75d137e79f4 100644 > > > --- a/Documentation/ABI/stable/sysfs-module > > > +++ b/Documentation/ABI/stable/sysfs-module > > > @@ -32,3 +32,21 @@ Description: > > > Note: If the module is built into the kernel, or if the > > > CONFIG_MODULE_UNLOAD kernel configuration value is not enabled, > > > this file will not be present. > > > + > > > +What: /sys/module/MODULENAME/scmversion > > > +Date: November 2020 > > > +KernelVersion: 5.12 > > > +Contact: Will McVicker > > > +Description: This read-only file will appear if modpost was supplied with an > > > + SCM version for the module. It can be enabled with the config > > > + MODULE_SCMVERSION. The SCM version is retrieved by > > > + scripts/setlocalversion, which means that the presence of this > > > + file depends on CONFIG_LOCALVERSION_AUTO=y. When read, the SCM > > > + version that the module was compiled with is returned. The SCM > > > + version is returned in the following format:: > > > + > > > + === > > > + Git: g[a-f0-9]\+(-dirty)\? > > > + Mercurial: hg[a-f0-9]\+(-dirty)\? > > > + Subversion: svn[0-9]\+ > > > + === > > > diff --git a/include/linux/module.h b/include/linux/module.h > > > index 7a0bcb5b1ffc..3b1612193cf9 100644 > > > --- a/include/linux/module.h > > > +++ b/include/linux/module.h > > > @@ -372,6 +372,7 @@ struct module { > > > struct module_attribute *modinfo_attrs; > > > const char *version; > > > const char *srcversion; > > > + const char *scmversion; > > > struct kobject *holders_dir; > > > > > > /* Exported symbols */ > > > diff --git a/init/Kconfig b/init/Kconfig > > > index b77c60f8b963..3d9dac3c4e8f 100644 > > > --- a/init/Kconfig > > > +++ b/init/Kconfig > > > @@ -2131,6 +2131,20 @@ config MODULE_SRCVERSION_ALL > > > the version). With this option, such a "srcversion" field > > > will be created for all modules. If unsure, say N. > > > > > > +config MODULE_SCMVERSION > > > + bool "SCM version for modules" > > > + depends on LOCALVERSION_AUTO > > > + help > > > + This enables the module attribute "scmversion" which can be used > > > + by developers to identify the SCM version of a given module, e.g. > > > + git sha1 or hg sha1. The SCM version can be queried by modinfo or > > > + via the sysfs node: /sys/modules/MODULENAME/scmversion. This is > > > + useful when the kernel or kernel modules are updated separately > > > + since that causes the vermagic of the kernel and the module to > > > + differ. > > > + > > > + If unsure, say N. > > > + > > > config MODULE_SIG > > > bool "Module signature verification" > > > select MODULE_SIG_FORMAT > > > diff --git a/kernel/module.c b/kernel/module.c > > > index 4bf30e4b3eaa..d0b359c7e9c9 100644 > > > --- a/kernel/module.c > > > +++ b/kernel/module.c > > > @@ -837,6 +837,7 @@ static struct module_attribute modinfo_##field = { \ > > > > > > MODINFO_ATTR(version); > > > MODINFO_ATTR(srcversion); > > > +MODINFO_ATTR(scmversion); > > > > > > static char last_unloaded_module[MODULE_NAME_LEN+1]; > > > > > > @@ -1298,6 +1299,7 @@ static struct module_attribute *modinfo_attrs[] = { > > > &module_uevent, > > > &modinfo_version, > > > &modinfo_srcversion, > > > + &modinfo_scmversion, > > > &modinfo_initstate, > > > &modinfo_coresize, > > > &modinfo_initsize, > > > diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost > > > index f54b6ac37ac2..f1126b60adb7 100644 > > > --- a/scripts/Makefile.modpost > > > +++ b/scripts/Makefile.modpost > > > @@ -66,6 +66,7 @@ ifeq ($(KBUILD_EXTMOD),) > > > > > > input-symdump := vmlinux.symvers > > > output-symdump := Module.symvers > > > +module_srcpath := $(srctree) > > > > > > else > > > > > > @@ -77,6 +78,17 @@ src := $(obj) > > > include $(if $(wildcard $(KBUILD_EXTMOD)/Kbuild), \ > > > $(KBUILD_EXTMOD)/Kbuild, $(KBUILD_EXTMOD)/Makefile) > > > > > > +# Get the external module's source path. KBUILD_EXTMOD could either be an > > > +# absolute path or relative path from $(srctree). > > > > > > No. > > KBUILD_EXTMOD could either be an absolute or relative path from $(objtree). > > > > > > > > > This makes sure that we > > > +# aren't using a relative path from a separate working directory (O= or > > > +# KBUILD_OUTPUT) since that may not be the actual module's SCM project path. > > > +# So check the path relative to $(srctree) first. > > > +ifneq ($(realpath $(srctree)/$(KBUILD_EXTMOD) 2>/dev/null),) > > > + module_srcpath := $(srctree)/$(KBUILD_EXTMOD) > > > +else > > > + module_srcpath := $(KBUILD_EXTMOD) > > > +endif > > > + > > > > This hunk is pointless in my view. > > > > The code should be much simpler, as follows: > > > > > > > > --- a/scripts/Makefile.modpost > > +++ b/scripts/Makefile.modpost > > @@ -66,6 +66,7 @@ ifeq ($(KBUILD_EXTMOD),) > > > > input-symdump := vmlinux.symvers > > output-symdump := Module.symvers > > +module_srcpath := $(srctree) > > > > else > > > > @@ -82,9 +83,20 @@ MODPOST += -e > > > > input-symdump := Module.symvers $(KBUILD_EXTRA_SYMBOLS) > > output-symdump := $(KBUILD_EXTMOD)/Module.symvers > > +module_srcpath := $(KBUILD_EXTMOD) > > > > endif > > > > > > > > > > > > > > > > > > > # modpost option for external modules > > > MODPOST += -e > > > > > > @@ -85,6 +97,16 @@ output-symdump := $(KBUILD_EXTMOD)/Module.symvers > > > > > > endif > > > > > > +ifeq ($(CONFIG_MODULE_SCMVERSION),y) > > > +# Get the SCM version of the module. Sed verifies setlocalversion returns > > > +# a proper revision based on the SCM type, e.g. git, mercurial, or svn. > > > +module_scmversion := $(shell $(srctree)/scripts/setlocalversion $(module_srcpath) | \ > > > + sed -n 's/.*-\(\(g\|hg\)[a-fA-F0-9]\+\(-dirty\)\?\|svn[0-9]\+\).*/\1/p') > > > +ifneq ($(module_scmversion),) > > > +MODPOST += -v$(module_scmversion) > > > > > > A space after -v for consistency. > > > > > > > > > +endif > > > +endif > > > + > > > # modpost options for modules (both in-kernel and external) > > > MODPOST += \ > > > $(addprefix -i ,$(wildcard $(input-symdump))) \ > > > diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c > > > index d6c81657d695..489b65bc37de 100644 > > > --- a/scripts/mod/modpost.c > > > +++ b/scripts/mod/modpost.c > > > @@ -30,6 +30,8 @@ static int have_vmlinux = 0; > > > static int all_versions = 0; > > > /* If we are modposting external module set to 1 */ > > > static int external_module = 0; > > > +#define MODULE_SCMVERSION_SIZE 64 > > > +static char module_scmversion[MODULE_SCMVERSION_SIZE]; > > > /* Only warn about unresolved symbols */ > > > static int warn_unresolved = 0; > > > /* How a symbol is exported */ > > > @@ -2264,6 +2266,20 @@ static void add_intree_flag(struct buffer *b, int is_intree) > > > buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n"); > > > } > > > > > > +/** > > > + * add_scmversion() - Adds the MODULE_INFO macro for the scmversion. > > > + * @b: Buffer to append to. > > > + * > > > + * This function fills in the module attribute `scmversion` for the kernel > > > + * module. This is useful for determining a given module's SCM version on > > > + * device via /sys/modules//scmversion and/or using the modinfo tool. > > > + */ > > > +static void add_scmversion(struct buffer *b) > > > +{ > > > + if (module_scmversion[0] != '\0') > > > + buf_printf(b, "\nMODULE_INFO(scmversion, \"%s\");\n", module_scmversion); > > > +} > > > + > > > /* Cannot check for assembler */ > > > static void add_retpoline(struct buffer *b) > > > { > > > @@ -2546,7 +2562,7 @@ int main(int argc, char **argv) > > > struct dump_list *dump_read_start = NULL; > > > struct dump_list **dump_read_iter = &dump_read_start; > > > > > > - while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) { > > > + while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:v:")) != -1) { > > > switch (opt) { > > > case 'e': > > > external_module = 1; > > > @@ -2584,6 +2600,11 @@ int main(int argc, char **argv) > > > case 'd': > > > missing_namespace_deps = optarg; > > > break; > > > + case 'v': > > > + if (!optarg) > > > + fatal("'-v' requires an argument defining the SCM version."); > > > > > > The existing -i, -T, -o, -d options take an argument as well. > > Why don't they have such a check as you added? > > The answer is because getopt() checks it. > > > > > > I applied your patch, and ran modpost directly > > with -v at the end of the command line. > > > > > > masahiro@oscar:~/workspace/linux$ ./scripts/mod/modpost -v > > ./scripts/mod/modpost: option requires an argument -- 'v' > > > > > > I see the error message from getopt() instead of > > your hand-made error check. > > > > > > > > > > > > > > > > > > > + strncpy(module_scmversion, optarg, sizeof(module_scmversion) - 1); > > > + break; > > > default: > > > exit(1); > > > } > > > @@ -2630,6 +2651,7 @@ int main(int argc, char **argv) > > > add_depends(&buf, mod); > > > add_moddevtable(&buf, mod); > > > add_srcversion(&buf, mod); > > > + add_scmversion(&buf); > > > > > > sprintf(fname, "%s.mod.c", mod->name); > > > write_if_changed(&buf, fname); > > > -- > > > 2.30.0.284.gd98b1dd5eaa7-goog > > > > > > > > > -- > > Best Regards > > Masahiro Yamada