Re: [PATCH v7 03/10] kbuild/modpost: create symbols.klp and integrate klp-convert

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Mar 06, 2023 at 09:08:17AM -0500, Joe Lawrence wrote:
> For automatic resolution of livepatch relocations, a file called
> symbols.klp is used. This file maps symbols within every compiled kernel
> object allowing the identification of symbols whose name is unique, thus
> relocation can be automatically inferred, or providing information that
> helps developers when code annotation is required for solving the
> matter.
> 
> Add support for creating symbols.klp in the main Makefile. First, ensure
> that built-in is compiled when CONFIG_LIVEPATCH is enabled (as required
> to achieve a complete symbols.klp file). Define the command to build
> symbols.klp (filechk_klp_map) and hook it in the modules rule. Save the
> list of livepatch modules in $(MODULES_LIVEPATCH).
> 
> As it is undesirable to have symbols from livepatch objects inside
> symbols.klp, filechk_klp_map filters out modules.livepatch from
> modules.order: `sort $(MODORDER) $(MODULES_LIVEPATCH) | uniq -u`.
> 
> The "clean" Makefile target may remove the modules.livepatch file,
> however, symbols.klp may be needed for building external modules, so
> defer its cleanup to the "mrproper" target.
> 
> Finally, update the modpost program so that it does not warn about
> unresolved symbols resolved by klp-convert.
> 

I don't have strong skills on Kbuild, but the changes makes sense.

Acked-by: Marcos Paulo de Souza <mpdesouza@xxxxxxxx>

> Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
> Signed-off-by: Konstantin Khlebnikov <khlebnikov@xxxxxxxxxxxxxx>
> Signed-off-by: Miroslav Benes <mbenes@xxxxxxx>
> Signed-off-by: Joao Moreira <jmoreira@xxxxxxx>
> Signed-off-by: Joe Lawrence <joe.lawrence@xxxxxxxxxx>
> ---
>  .gitignore                |  2 ++
>  Documentation/dontdiff    |  1 +
>  Makefile                  | 16 +++++++++++-----
>  scripts/Makefile.modfinal | 33 +++++++++++++++++++++++++++++++++
>  scripts/Makefile.modpost  |  5 +++++
>  scripts/mod/modpost.c     | 28 ++++++++++++++++++++++++++--
>  scripts/mod/modpost.h     |  1 +
>  7 files changed, 79 insertions(+), 7 deletions(-)
> 
> diff --git a/.gitignore b/.gitignore
> index 20dce5c3b9e0..fc9b2f13b049 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -53,6 +53,7 @@
>  *.xz
>  *.zst
>  Module.symvers
> +modules.livepatch
>  modules.order
>  
>  #
> @@ -66,6 +67,7 @@ modules.order
>  /vmlinux.symvers
>  /vmlinux-gdb.py
>  /vmlinuz
> +/symbols.klp
>  /System.map
>  /Module.markers
>  /modules.builtin
> diff --git a/Documentation/dontdiff b/Documentation/dontdiff
> index 352ff53a2306..23c2a89fb791 100644
> --- a/Documentation/dontdiff
> +++ b/Documentation/dontdiff
> @@ -76,6 +76,7 @@ Module.markers
>  Module.symvers
>  PENDING
>  SCCS
> +symbols.klp
>  System.map*
>  TAGS
>  aconf
> diff --git a/Makefile b/Makefile
> index 3f6628780eb2..dd5d6c258906 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -730,8 +730,13 @@ KBUILD_MODULES :=
>  KBUILD_BUILTIN := 1
>  
>  # If we have only "make modules", don't compile built-in objects.
> +# When we're building livepatch modules, we need to consider the
> +# built-in objects during the descend as well, as built-in objects may
> +# hold symbols which are referenced from livepatches and are required by
> +# klp-convert post-processing tool for resolving these cases.
> +
>  ifeq ($(MAKECMDGOALS),modules)
> -  KBUILD_BUILTIN :=
> +  KBUILD_BUILTIN := $(if $(CONFIG_LIVEPATCH),1)
>  endif
>  
>  # If we have "make <whatever> modules", compile modules
> @@ -1183,6 +1188,7 @@ PHONY += prepare0
>  export extmod_prefix = $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/)
>  export MODORDER := $(extmod_prefix)modules.order
>  export MODULES_NSDEPS := $(extmod_prefix)modules.nsdeps
> +export MODULES_LIVEPATCH := $(extmod-prefix)modules.livepatch
>  
>  ifeq ($(KBUILD_EXTMOD),)
>  
> @@ -1543,8 +1549,8 @@ endif
>  #
>  
>  # *.ko are usually independent of vmlinux, but CONFIG_DEBUG_INFOBTF_MODULES
> -# is an exception.
> -ifdef CONFIG_DEBUG_INFO_BTF_MODULES
> +# and CONFIG_LIVEPATCH are exceptions.
> +ifneq ($(or $(CONFIG_DEBUG_INFO_BTF_MODULES),$(CONFIG_LIVEPATCH)),)
>  KBUILD_BUILTIN := 1
>  modules: vmlinux
>  endif
> @@ -1602,14 +1608,14 @@ endif # CONFIG_MODULES
>  CLEAN_FILES += include/ksym vmlinux.symvers modules-only.symvers \
>  	       modules.builtin modules.builtin.modinfo modules.nsdeps \
>  	       compile_commands.json .thinlto-cache rust/test rust/doc \
> -	       .vmlinux.objs .vmlinux.export.c
> +	       modules.livepatch .vmlinux.objs .vmlinux.export.c
>  
>  # Directories & files removed with 'make mrproper'
>  MRPROPER_FILES += include/config include/generated          \
>  		  arch/$(SRCARCH)/include/generated .objdiff \
>  		  debian snap tar-install \
>  		  .config .config.old .version \
> -		  Module.symvers \
> +		  Module.symvers symbols.klp \
>  		  certs/signing_key.pem \
>  		  certs/x509.genkey \
>  		  vmlinux-gdb.py \
> diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
> index a30d5b08eee9..a8901e4e98c5 100644
> --- a/scripts/Makefile.modfinal
> +++ b/scripts/Makefile.modfinal
> @@ -14,6 +14,7 @@ include $(srctree)/scripts/Makefile.lib
>  
>  # find all modules listed in modules.order
>  modules := $(call read-file, $(MODORDER))
> +modules-klp := $(call read-file, $(MODULES_LIVEPATCH))
>  
>  __modfinal: $(modules:%.o=%.ko)
>  	@:
> @@ -65,6 +66,38 @@ endif
>  
>  targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o)
>  
> +# Livepatch
> +# ---------------------------------------------------------------------------
> +
> +%.tmp.ko: %.o %.mod.o symbols.klp FORCE
> +	+$(call if_changed,ld_ko_o)
> +
> +quiet_cmd_klp_convert = KLP     $@
> +      cmd_klp_convert = scripts/livepatch/klp-convert symbols.klp $< $@
> +
> +$(modules-klp:%.o=%.ko): %.ko: %.tmp.ko FORCE
> +	$(call if_changed,klp_convert)
> +
> +targets += $(modules-klp:.ko=.tmp.ko)
> +
> +ifeq ($(KBUILD_EXTMOD),)
> +filechk_klp_map = \
> +	echo "klp-convert-symbol-data.0.1";		\
> +	echo "*vmlinux";				\
> +	$(NM) -f posix vmlinux | cut -d\  -f1;		\
> +	sort $(MODORDER) $(MODULES_LIVEPATCH) |		\
> +	uniq -u |					\
> +	sed 's/\.o$$//' |    			  	\
> +	while read o;					\
> +	do						\
> +		echo "*$$(basename $$o)";		\
> +		$(NM) -f posix $$o.o | cut -d\  -f1;	\
> +	done
> +
> +symbols.klp: FORCE
> +	$(call filechk,klp_map)
> +endif
> +
>  # Add FORCE to the prequisites of a target to force it to be always rebuilt.
>  # ---------------------------------------------------------------------------
>  
> diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
> index 43343e13c542..02f1354d4cff 100644
> --- a/scripts/Makefile.modpost
> +++ b/scripts/Makefile.modpost
> @@ -47,6 +47,7 @@ modpost-args =										\
>  	$(if $(KBUILD_MODPOST_WARN),-w)							\
>  	$(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS))					\
>  	$(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N)	\
> +	$(if $(CONFIG_LIVEPATCH),-l $(MODULES_LIVEPATCH))				\
>  	-o $@
>  
>  modpost-deps := $(MODPOST)
> @@ -138,6 +139,10 @@ $(output-symdump): $(modpost-deps) FORCE
>  	$(call if_changed,modpost)
>  
>  __modpost: $(output-symdump)
> +ifndef CONFIG_LIVEPATCH
> +	$(Q)rm -f $(MODULES_LIVEPATCH)
> +	$(Q)touch $(MODULES_LIVEPATCH)
> +endif
>  PHONY += FORCE
>  FORCE:
>  
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index efff8078e395..0a8f0ce75761 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -1831,6 +1831,10 @@ static void read_symbols(const char *modname)
>  		handle_moddevtable(mod, &info, sym, symname);
>  	}
>  
> +	/* Livepatch modules have unresolved symbols resolved by klp-convert */
> +	if (get_modinfo(&info, "livepatch"))
> +		mod->is_livepatch = true;
> +
>  	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
>  		symname = remove_dot(info.strtab + sym->st_name);
>  
> @@ -1919,7 +1923,7 @@ static void check_exports(struct module *mod)
>  		const char *basename;
>  		exp = find_symbol(s->name);
>  		if (!exp) {
> -			if (!s->weak && nr_unresolved++ < MAX_UNRESOLVED_REPORTS)
> +			if (!s->weak && !mod->is_livepatch && nr_unresolved++ < MAX_UNRESOLVED_REPORTS)
>  				modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR,
>  					    "\"%s\" [%s.ko] undefined!\n",
>  					    s->name, mod->name);
> @@ -2320,6 +2324,20 @@ static void write_namespace_deps_files(const char *fname)
>  	free(ns_deps_buf.p);
>  }
>  
> +static void write_livepatch_modules(const char *fname)
> +{
> +	struct buffer buf = { };
> +	struct module *mod;
> +
> +	list_for_each_entry(mod, &modules, list) {
> +		if (mod->is_livepatch)
> +			buf_printf(&buf, "%s.o\n", mod->name);
> +	}
> +
> +	write_if_changed(&buf, fname);
> +	free(buf.p);
> +}
> +
>  struct dump_list {
>  	struct list_head list;
>  	const char *file;
> @@ -2330,11 +2348,12 @@ int main(int argc, char **argv)
>  	struct module *mod;
>  	char *missing_namespace_deps = NULL;
>  	char *dump_write = NULL, *files_source = NULL;
> +	char *livepatch_modules = NULL;
>  	int opt;
>  	LIST_HEAD(dump_lists);
>  	struct dump_list *dl, *dl2;
>  
> -	while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) {
> +	while ((opt = getopt(argc, argv, "ei:l:mnT:o:awENd:")) != -1) {
>  		switch (opt) {
>  		case 'e':
>  			external_module = true;
> @@ -2344,6 +2363,9 @@ int main(int argc, char **argv)
>  			dl->file = optarg;
>  			list_add_tail(&dl->list, &dump_lists);
>  			break;
> +		case 'l':
> +			livepatch_modules = optarg;
> +			break;
>  		case 'm':
>  			modversions = true;
>  			break;
> @@ -2403,6 +2425,8 @@ int main(int argc, char **argv)
>  
>  	if (dump_write)
>  		write_dump(dump_write);
> +	if (livepatch_modules)
> +		write_livepatch_modules(livepatch_modules);
>  	if (sec_mismatch_count && !sec_mismatch_warn_only)
>  		error("Section mismatches detected.\n"
>  		      "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n");
> diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
> index 1178f40a73f3..9be9bf6fb7da 100644
> --- a/scripts/mod/modpost.h
> +++ b/scripts/mod/modpost.h
> @@ -119,6 +119,7 @@ struct module {
>  	bool is_gpl_compatible;
>  	bool from_dump;		/* true if module was loaded from *.symvers */
>  	bool is_vmlinux;
> +	bool is_livepatch;
>  	bool seen;
>  	bool has_init;
>  	bool has_cleanup;
> -- 
> 2.39.2
> 



[Index of Archives]     [Linux&nblp;USB Development]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite Secrets]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux