On 05/12/2025 7:34 pm, Grygorii Strashko wrote:
> 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

This is a lot nicer (i.e. more simple).

But, I still don't know why we need to avoid freeing init memory to make
this work.  What explodes if we dont?

> 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 :=

This could become a single line now.

> 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

For both of these, the preferred way would be to use if (
IS_ENABLED(CONFIG_DO_NOT_FREE_INIT_MEMORY) ), which removes the need for
the else clause in x86.

Also, you make free_init_memory() un-called on ARM with this change. 
Depending on how the freeing-init question lands, you either want some
extra ifdefary, or the --gc-sections option that we discussed before.

~Andrew

Reply via email to