:p
atchew
Login
From: Grygorii Strashko <grygorii_strashko@epam.com> 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 <grygorii_strashko@epam.com> --- 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/20251203222436.660044-1-grygorii_strashko@epam.com/ 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 XXXXXXX..XXXXXXX 100644 --- a/xen/Kconfig.debug +++ b/xen/Kconfig.debug @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ $(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 \ @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -XXX,XX +XXX,XX @@ 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(); @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/xen/common/libelf/Makefile +++ b/xen/common/libelf/Makefile @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/xen/common/libfdt/Makefile +++ b/xen/common/libfdt/Makefile @@ -XXX,XX +XXX,XX @@ 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
From: Grygorii Strashko <grygorii_strashko@epam.com> Extend coverage support on .init and lib code. To enable coverage support on .init code the gcc special section should stay in memory after Xen boot when COVERAGE=y. So, add hidden Kconfig option RELAX_INIT_CHECK "Relax strict check for .init sections only in %.init.o files", which is selected when COVERAGE=y and allows to bypass strict check for .init sections only in %.init.o files. Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com> --- changes in v3: - drop DO_NOT_FREE_INIT_MEMORY: only gcc special section should stay in memory after Xen boot - split make cmd quiet_cmd_obj_init_o on two: obj_init_check and obj_init_check - drop libfdt/libelf changes - they need additional work -- before v2 of this patch libfdt/libelf were out of code coverage scope -- v2 allowed to enable coverage for libfdt/libelf easily thanks to DO_NOT_FREE_INIT_MEMORY which kept all .init code in memory -- without DO_NOT_FREE_INIT_MEMORY it's not so easy any more, so drop libfdt/libelf changes 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 v2: https://patchwork.kernel.org/project/xen-devel/patch/20251205193411.1368659-1-grygorii_strashko@epam.com/ v1: https://patchwork.kernel.org/project/xen-devel/patch/20251203222436.660044-1-grygorii_strashko@epam.com/ xen/Kconfig.debug | 6 ++++++ xen/Rules.mk | 22 +++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/xen/Kconfig.debug b/xen/Kconfig.debug index XXXXXXX..XXXXXXX 100644 --- a/xen/Kconfig.debug +++ b/xen/Kconfig.debug @@ -XXX,XX +XXX,XX @@ config COVERAGE bool "Code coverage support" depends on SYSCTL && !LIVEPATCH select SUPPRESS_DUPLICATE_SYMBOL_WARNINGS if !ENFORCE_UNIQUE_SYMBOLS + select RELAX_INIT_CHECK 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 CONDITION_COVERAGE bool "Condition coverage support" depends on COVERAGE && CC_HAS_MCDC diff --git a/xen/Rules.mk b/xen/Rules.mk index XXXXXXX..XXXXXXX 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -XXX,XX +XXX,XX @@ cov-cflags-y := nocov-y := noubsan-y := +# when coverage is enabled the gcc special section should stay in memory +# after Xen boot +ifneq ($(CONFIG_COVERAGE),y) SPECIAL_DATA_SECTIONS := rodata $(foreach a,1 2 4 8 16, \ $(foreach w,1 2 4, \ rodata.str$(w).$(a)) \ rodata.cst$(a)) \ $(foreach r,rel rel.ro,data.$(r).local) +endif # The filename build.mk has precedence over Makefile include $(firstword $(wildcard $(srcdir)/build.mk) $(srcdir)/Makefile) @@ -XXX,XX +XXX,XX @@ 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)): \ - cov-cflags-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 @@ -XXX,XX +XXX,XX @@ $(obj)/%.o: $(src)/%.S FORCE $(call if_changed_dep,cc_o_S) -quiet_cmd_obj_init_o = INIT_O $@ -define cmd_obj_init_o +quiet_cmd_obj_init_check = INIT_C $@ +define cmd_obj_init_check $(OBJDUMP) -h $< | while read idx name sz rest; do \ case "$$name" in \ .*.local) ;; \ @@ -XXX,XX +XXX,XX @@ define cmd_obj_init_o echo "Error: size of $<:$$name is 0x$$sz" >&2; \ exit $$(expr $$idx + 1);; \ esac; \ - done || exit $$?; \ + done || exit $$? +endef + +quiet_cmd_obj_init_objcopy = INIT_O $@ +define cmd_obj_init_objcopy $(OBJCOPY) $(foreach s,$(SPECIAL_DATA_SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@ endef $(filter %.init.o,$(obj-y) $(obj-bin-y) $(extra-y)): $(obj)/%.init.o: $(obj)/%.o FORCE - $(call if_changed,obj_init_o) + $(if $(filter y,$(CONFIG_RELAX_INIT_CHECK)),,$(call if_changed,obj_init_check)) + $(call if_changed,obj_init_objcopy) quiet_cmd_cpp_i_c = CPP $@ cmd_cpp_i_c = $(CPP) $(call cpp_flags,$(c_flags)) -MQ $@ -o $@ $< -- 2.34.1