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]>
Tested-by: Ralf Ramsauer <[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 $(FILE_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) += -fprofile-arcs -ftest-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 $(FILE_CONFIG_MK)
 
 GCOV_PROFILE := n
+ccflags-$(CONFIG_JAILHOUSE_GCOV) += -fprofile-arcs -ftest-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/arm/Kbuild b/hypervisor/arch/arm/Kbuild
--- a/hypervisor/arch/arm/Kbuild
+++ b/hypervisor/arch/arm/Kbuild
@@ -20,5 +20,11 @@ obj-y := $(COMMON_OBJECTS)
 obj-y += entry.o exception.o setup.o control.o traps.o mmio.o lib.o
 obj-y += mmu_hyp.o caches.o mach-stubs.o
 
+# in here we switch of the MMU and stuff, cant profile such code
+# NOTE
+#  gcc7 will bring a new function attribute "no_profile_instrument_function"
+#  should switch to that for higher granularity, but gcc7 is not even there
+CFLAGS_mmu_hyp.o += -fno-profile-arcs -fno-test-coverage
+
 obj-$(CONFIG_ARM_GIC_V3) += gic-v3.o
 obj-$(CONFIG_MACH_VEXPRESS) += mach-vexpress.o
diff --git a/hypervisor/arch/x86/Kbuild b/hypervisor/arch/x86/Kbuild
--- a/hypervisor/arch/x86/Kbuild
+++ b/hypervisor/arch/x86/Kbuild
@@ -1,7 +1,7 @@
 #
 # Jailhouse, a Linux-based partitioning hypervisor
 #
-# Copyright (c) Siemens AG, 2013
+# Copyright (c) Siemens AG, 2013-2017
 # Copyright (c) Valentine Sinitsyn, 2014
 #
 # Authors:
@@ -12,7 +12,11 @@
 # the COPYING file in the top-level directory.
 #
 
+include $(FILE_CONFIG_MK)
+
 GCOV_PROFILE := n
+ccflags-$(CONFIG_JAILHOUSE_GCOV) += -fprofile-arcs -ftest-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,50 @@
+/*
+ * 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>
+#include <jailhouse/gcov.h>
+
+extern unsigned long __init_array_start[], __init_array_end[];
+
+/* 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(void) {
+       unsigned long *iarray = __init_array_start;
+       unsigned long *iarray_end = __init_array_end;
+       void (*__init_func)(void);
+
+       while (iarray < iarray_end) {
+               __init_func = (void(*)(void))iarray[0];
+               iarray++;
+               __init_func();
+       }
+}
+
+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/gcov.h 
b/hypervisor/include/jailhouse/gcov.h
new file mode 100644
--- /dev/null
+++ b/hypervisor/include/jailhouse/gcov.h
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+#ifdef CONFIG_JAILHOUSE_GCOV
+void gcov_init(void);
+#else
+static inline void gcov_init(void) {}
+#endif
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
@@ -1,7 +1,7 @@
 /*
  * Jailhouse, a Linux-based partitioning hypervisor
  *
- * Copyright (c) Siemens AG, 2013-2016
+ * Copyright (c) Siemens AG, 2013-2017
  *
  * Authors:
  *  Jan Kiszka <[email protected]>
@@ -13,6 +13,7 @@
 #include <jailhouse/processor.h>
 #include <jailhouse/printk.h>
 #include <jailhouse/entry.h>
+#include <jailhouse/gcov.h>
 #include <jailhouse/mmio.h>
 #include <jailhouse/paging.h>
 #include <jailhouse/control.h>
@@ -51,6 +52,8 @@ static void init_early(unsigned int cpu_
               JAILHOUSE_VERSION, cpu_id);
        printk("Code location: %p\n", __text_start);
 
+       gcov_init();
+
        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.

Reply via email to