From: Grygorii Strashko <[email protected]> Extend coverage support on .init and lib code. Add two hidden Kconfig options: - RELAX_INIT_CHECK "Relax strict check for .init sections only in %.init.o files" - DO_NOT_FREE_INIT_MEMORY "Prevent freeing of .init sections at the end of Xen boot."
Both selected selected when COVERAGE=y, as getting coverage report for ".init" code is required: - to bypass strict check for .init sections only in %.init.o files; - the .init code stay in memory after Xen boot. RELAX_INIT_CHECK/DO_NOT_FREE_INIT_MEMORY could be used by other debug features in the future. Signed-off-by: Grygorii Strashko <[email protected]> --- changes in v2: - add RELAX_INIT_CHECK and DO_NOT_FREE_INIT_MEMORY, those are two different things, both potentially reusable - enable coverage for libfdt/libelf always - enable colverage for .init always v1: https://patchwork.kernel.org/project/xen-devel/patch/[email protected]/ xen/Kconfig.debug | 12 ++++++++++++ xen/Rules.mk | 10 ++++++++-- xen/arch/arm/setup.c | 2 ++ xen/arch/x86/setup.c | 4 ++++ xen/common/libelf/Makefile | 1 - xen/common/libfdt/Makefile | 1 - 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/xen/Kconfig.debug b/xen/Kconfig.debug index d900d926c555..8fc201d12c2c 100644 --- a/xen/Kconfig.debug +++ b/xen/Kconfig.debug @@ -39,11 +39,23 @@ config COVERAGE bool "Code coverage support" depends on SYSCTL && !LIVEPATCH select SUPPRESS_DUPLICATE_SYMBOL_WARNINGS if !ENFORCE_UNIQUE_SYMBOLS + select RELAX_INIT_CHECK + select DO_NOT_FREE_INIT_MEMORY help Enable code coverage support. If unsure, say N here. +config RELAX_INIT_CHECK + bool + help + Relax strict check for .init sections only in %.init.o files. + +config DO_NOT_FREE_INIT_MEMORY + bool + help + Prevent freeing of .init sections at the end of Xen boot. + config CONDITION_COVERAGE bool "Condition coverage support" depends on COVERAGE && CC_HAS_MCDC diff --git a/xen/Rules.mk b/xen/Rules.mk index 24f447b95734..c884a4199dc2 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -145,10 +145,10 @@ endif $(call cc-option-add,cov-cflags-$(CONFIG_COVERAGE),CC,-fprofile-update=atomic) # Reset cov-cflags-y in cases where an objects has another one as prerequisite -$(nocov-y) $(filter %.init.o, $(obj-y) $(obj-bin-y) $(extra-y)): \ +$(nocov-y) $(extra-y): \ cov-cflags-y := -$(non-init-objects): _c_flags += $(cov-cflags-y) +$(obj-y) $(obj-bin-y) $(extra-y) $(lib-y): _c_flags += $(cov-cflags-y) ifeq ($(CONFIG_UBSAN),y) # Any -fno-sanitize= options need to come after any -fsanitize= options @@ -259,6 +259,7 @@ $(obj)/%.o: $(src)/%.S FORCE quiet_cmd_obj_init_o = INIT_O $@ +ifneq ($(CONFIG_RELAX_INIT_CHECK),y) define cmd_obj_init_o $(OBJDUMP) -h $< | while read idx name sz rest; do \ case "$$name" in \ @@ -271,6 +272,11 @@ define cmd_obj_init_o done || exit $$?; \ $(OBJCOPY) $(foreach s,$(SPECIAL_DATA_SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@ endef +else +define cmd_obj_init_o + $(OBJCOPY) $(foreach s,$(SPECIAL_DATA_SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@ +endef +endif $(filter %.init.o,$(obj-y) $(obj-bin-y) $(extra-y)): $(obj)/%.init.o: $(obj)/%.o FORCE $(call if_changed,obj_init_o) diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 22e929aac778..2a0b322445cd 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -69,10 +69,12 @@ static __used void noreturn init_done(void) { int rc; +#ifndef CONFIG_DO_NOT_FREE_INIT_MEMORY /* Must be done past setting system_state. */ unregister_init_virtual_region(); free_init_memory(); +#endif /* * We have finished booting. Mark the section .data.ro_after_init diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 7bbba76a92f8..280085c206a7 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -815,6 +815,7 @@ static void noreturn init_done(void) for ( unsigned int i = 0; i < bi->nr_domains; i++ ) domain_unpause_by_systemcontroller(bi->domains[i].d); +#ifndef CONFIG_DO_NOT_FREE_INIT_MEMORY /* MUST be done prior to removing .init data. */ unregister_init_virtual_region(); @@ -837,6 +838,9 @@ static void noreturn init_done(void) destroy_xen_mappings(start, end); init_xenheap_pages(__pa(start), __pa(end)); printk("Freed %lukB init memory\n", (end - start) >> 10); +#else + (void) end, (void) start, (void)va; +#endif /* Mark .rodata/ro_after_init as RO. Maybe reform the superpage. */ modify_xen_mappings((unsigned long)&__2M_rodata_start, diff --git a/xen/common/libelf/Makefile b/xen/common/libelf/Makefile index 917d12b006f7..60b3ae40728f 100644 --- a/xen/common/libelf/Makefile +++ b/xen/common/libelf/Makefile @@ -1,5 +1,4 @@ obj-bin-y := libelf.o -nocov-y += libelf.o libelf-objs := libelf-tools.o libelf-loader.o libelf-dominfo.o SECTIONS := text data $(SPECIAL_DATA_SECTIONS) diff --git a/xen/common/libfdt/Makefile b/xen/common/libfdt/Makefile index 6ce679f98f47..ae0f69c01373 100644 --- a/xen/common/libfdt/Makefile +++ b/xen/common/libfdt/Makefile @@ -5,7 +5,6 @@ SECTIONS := text data $(SPECIAL_DATA_SECTIONS) # For CONFIG_OVERLAY_DTB, libfdt functionalities will be needed during runtime. ifneq ($(CONFIG_OVERLAY_DTB),y) OBJCOPYFLAGS := $(foreach s,$(SECTIONS),--rename-section .$(s)=.init.$(s)) -nocov-y += libfdt.o endif obj-y += libfdt.o -- 2.34.1
