This introduces pretty minimal GCOV support. The hypervisor does not need to understand much of that. It just needs to call the init functions to gather the addresses of the gcov related data structures. These are just linked together so something outside the hypervisor can look at them later.
Signed-off-by: Henning Schild <[email protected]> diff --git a/hypervisor/Makefile b/hypervisor/Makefile --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -25,6 +25,7 @@ KBUILD_CFLAGS := -g -Os -Wall -Wstrict-p -fno-stack-protector -fno-builtin-ffsl include $(src)/arch/$(SRCARCH)/Makefile +include $(obj)/include/generated/config.mk ifneq ($(wildcard $(obj)/include/jailhouse/config.h),) KBUILD_CFLAGS += -include $(obj)/include/jailhouse/config.h @@ -35,6 +36,12 @@ GCOV_PROFILE := n CORE_OBJECTS = setup.o printk.o paging.o control.o lib.o mmio.o pci.o ivshmem.o CORE_OBJECTS += uart.o uart-8250.o +ifdef CONFIG_JAILHOUSE_GCOV +CORE_OBJECTS += gcov.o +endif +ccflags-$(CONFIG_JAILHOUSE_GCOV) += --coverage +clean-files += *.gcno + clean-dirs := arch/$(SRCARCH)/include/generated define sed-y diff --git a/hypervisor/arch/arm-common/Kbuild b/hypervisor/arch/arm-common/Kbuild --- a/hypervisor/arch/arm-common/Kbuild +++ b/hypervisor/arch/arm-common/Kbuild @@ -13,6 +13,8 @@ include $(obj)/../../include/generated/config.mk GCOV_PROFILE := n +ccflags-$(CONFIG_JAILHOUSE_GCOV) += --coverage +clean-files += *.gcno OBJS-y += dbg-write.o lib.o psci.o control.o paging.o mmu_cell.o OBJS-y += irqchip.o pci.o ivshmem.o uart-pl011.o uart-xuartps.o diff --git a/hypervisor/arch/x86/Kbuild b/hypervisor/arch/x86/Kbuild --- a/hypervisor/arch/x86/Kbuild +++ b/hypervisor/arch/x86/Kbuild @@ -15,6 +15,8 @@ include $(obj)/../../include/generated/config.mk GCOV_PROFILE := n +ccflags-$(CONFIG_JAILHOUSE_GCOV) += --coverage +clean-files += *.gcno BUILT_IN_OBJECTS := built-in-amd.o built-in-intel.o COMMON_OBJECTS := apic.o dbg-write.o entry.o setup.o control.o mmio.o iommu.o \ diff --git a/hypervisor/gcov.c b/hypervisor/gcov.c new file mode 100644 --- /dev/null +++ b/hypervisor/gcov.c @@ -0,0 +1,36 @@ +/* + * Jailhouse, a Linux-based partitioning hypervisor + * + * Copyright (c) Siemens AG, 2017 + * + * Authors: + * Henning Schild <[email protected]> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ +#include <jailhouse/entry.h> + +/* the actual data structure is bigger but we just need to know the version + * independent beginning to link the elements to a list */ +struct gcov_min_info { + unsigned int version; + struct gcov_min_info *next; +}; + +void __gcov_init(struct gcov_min_info *info); +void __gcov_merge_add(void *counters, unsigned int n_counters); + + +/* just link them all together and leave the head in the header + * where a processing tool can find it */ +void __gcov_init(struct gcov_min_info *info) +{ + info->next = (struct gcov_min_info *)hypervisor_header.gcov_info_head; + hypervisor_header.gcov_info_head = info; +} + +/* Satisfy the linker, never called */ +void __gcov_merge_add(void *counters, unsigned int n_counters) +{ +} diff --git a/hypervisor/hypervisor.lds.S b/hypervisor/hypervisor.lds.S --- a/hypervisor/hypervisor.lds.S +++ b/hypervisor/hypervisor.lds.S @@ -30,6 +30,11 @@ SECTIONS . = ALIGN(16); .data : { *(.data) } + . = ALIGN(8); + __init_array_start = .; + .init_array : { *(SORT(.init_array.*)) *(.init_array) } + __init_array_end = .; + ARCH_SECTIONS . = ALIGN(16); diff --git a/hypervisor/include/jailhouse/header.h b/hypervisor/include/jailhouse/header.h --- a/hypervisor/include/jailhouse/header.h +++ b/hypervisor/include/jailhouse/header.h @@ -58,6 +58,9 @@ struct jailhouse_header { /** Offset of the console page inside the hypervisor memory * @note Filled at build time. */ unsigned long console_page; + /** Pointer to the first struct gcov_info + * @note Filled at build time */ + void *gcov_info_head; /** Configured maximum logical CPU ID + 1. * @note Filled by Linux loader driver before entry. */ diff --git a/hypervisor/setup.c b/hypervisor/setup.c --- a/hypervisor/setup.c +++ b/hypervisor/setup.c @@ -21,6 +21,7 @@ #include <asm/spinlock.h> extern u8 __text_start[], __page_pool[]; +extern unsigned long __init_array_start[], __init_array_end[]; static const __attribute__((aligned(PAGE_SIZE))) u8 empty_page[PAGE_SIZE]; @@ -35,6 +36,11 @@ static void init_early(unsigned int cpu_ sizeof(struct per_cpu) * hypervisor_header.max_cpus; u64 hyp_phys_start, hyp_phys_end; struct jailhouse_memory hv_page; +#ifdef CONFIG_JAILHOUSE_GCOV + unsigned long *iarray = __init_array_start; + unsigned long *iarray_end = __init_array_end; + void (*__init_func)(void); +#endif master_cpu_id = cpu_id; @@ -51,6 +57,13 @@ static void init_early(unsigned int cpu_ JAILHOUSE_VERSION, cpu_id); printk("Code location: %p\n", __text_start); +#ifdef CONFIG_JAILHOUSE_GCOV + while (iarray < iarray_end) { + __init_func = (void(*)(void))iarray[0]; + iarray++; + __init_func(); + } +#endif error = paging_init(); if (error) return; -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
