Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e8572bd9 authored by Alistair Strachan's avatar Alistair Strachan
Browse files

Revert "BACKPORT: kernel: add kcov code coverage"



This reverts commit f945a3c1.

Revert this unused feature. It is starting to complicate 3.18 LTS merges
and it is not a base or recommended option. It is not being used any
more.

Bug: 116647072
Change-Id: I46253472a1b4429b1a87c27deea529f4c3eb4a36
Signed-off-by: default avatarAlistair Strachan <astrachan@google.com>
parent 8f521c73
Loading
Loading
Loading
Loading

Documentation/kcov.txt

deleted100644 → 0
+0 −111
Original line number Diff line number Diff line
kcov: code coverage for fuzzing
===============================

kcov exposes kernel code coverage information in a form suitable for coverage-
guided fuzzing (randomized testing). Coverage data of a running kernel is
exported via the "kcov" debugfs file. Coverage collection is enabled on a task
basis, and thus it can capture precise coverage of a single system call.

Note that kcov does not aim to collect as much coverage as possible. It aims
to collect more or less stable coverage that is function of syscall inputs.
To achieve this goal it does not collect coverage in soft/hard interrupts
and instrumentation of some inherently non-deterministic parts of kernel is
disbled (e.g. scheduler, locking).

Usage:
======

Configure kernel with:

        CONFIG_KCOV=y

CONFIG_KCOV requires gcc built on revision 231296 or later.
Profiling data will only become accessible once debugfs has been mounted:

        mount -t debugfs none /sys/kernel/debug

The following program demonstrates kcov usage from within a test program:

#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>

#define KCOV_INIT_TRACE			_IOR('c', 1, unsigned long)
#define KCOV_ENABLE			_IO('c', 100)
#define KCOV_DISABLE			_IO('c', 101)
#define COVER_SIZE			(64<<10)

int main(int argc, char **argv)
{
	int fd;
	unsigned long *cover, n, i;

	/* A single fd descriptor allows coverage collection on a single
	 * thread.
	 */
	fd = open("/sys/kernel/debug/kcov", O_RDWR);
	if (fd == -1)
		perror("open"), exit(1);
	/* Setup trace mode and trace size. */
	if (ioctl(fd, KCOV_INIT_TRACE, COVER_SIZE))
		perror("ioctl"), exit(1);
	/* Mmap buffer shared between kernel- and user-space. */
	cover = (unsigned long*)mmap(NULL, COVER_SIZE * sizeof(unsigned long),
				     PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	if ((void*)cover == MAP_FAILED)
		perror("mmap"), exit(1);
	/* Enable coverage collection on the current thread. */
	if (ioctl(fd, KCOV_ENABLE, 0))
		perror("ioctl"), exit(1);
	/* Reset coverage from the tail of the ioctl() call. */
	__atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED);
	/* That's the target syscal call. */
	read(-1, NULL, 0);
	/* Read number of PCs collected. */
	n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED);
	for (i = 0; i < n; i++)
		printf("0x%lx\n", cover[i + 1]);
	/* Disable coverage collection for the current thread. After this call
	 * coverage can be enabled for a different thread.
	 */
	if (ioctl(fd, KCOV_DISABLE, 0))
		perror("ioctl"), exit(1);
	/* Free resources. */
	if (munmap(cover, COVER_SIZE * sizeof(unsigned long)))
		perror("munmap"), exit(1);
	if (close(fd))
		perror("close"), exit(1);
	return 0;
}

After piping through addr2line output of the program looks as follows:

SyS_read
fs/read_write.c:562
__fdget_pos
fs/file.c:774
__fget_light
fs/file.c:746
__fget_light
fs/file.c:750
__fget_light
fs/file.c:760
__fdget_pos
fs/file.c:784
SyS_read
fs/read_write.c:562

If a program needs to collect coverage from several threads (independently),
it needs to open /sys/kernel/debug/kcov in each thread separately.

The interface is fine-grained to allow efficient forking of test processes.
That is, a parent process opens /sys/kernel/debug/kcov, enables trace mode,
mmaps coverage buffer and then forks child processes in a loop. Child processes
only need to enable coverage (disable happens automatically on thread end).
+1 −11
Original line number Diff line number Diff line
@@ -376,8 +376,6 @@ LDFLAGS_MODULE =
CFLAGS_KERNEL	=
AFLAGS_KERNEL	=
CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage -fno-tree-loop-im
CFLAGS_KCOV	= -fsanitize-coverage=trace-pc


# Use USERINCLUDE when you must reference the UAPI directories only.
USERINCLUDE    := \
@@ -422,7 +420,7 @@ export MAKE AWK GENKSYMS INSTALLKERNEL PERL PYTHON UTS_MACHINE
export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS

export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV CFLAGS_KCOV CFLAGS_KASAN CFLAGS_UBSAN
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV
export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
@@ -678,14 +676,6 @@ endif
endif
KBUILD_CFLAGS += $(stackp-flag)

ifdef CONFIG_KCOV
  ifeq ($(call cc-option, $(CFLAGS_KCOV)),)
    $(warning Cannot use CONFIG_KCOV: \
             -fsanitize-coverage=trace-pc is not supported by compiler)
    CFLAGS_KCOV =
  endif
endif

ifeq ($(COMPILER),clang)
KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
KBUILD_CPPFLAGS += $(call cc-option,-Wno-unknown-warning-option,)
+0 −6
Original line number Diff line number Diff line
@@ -24,12 +24,6 @@ config X86
	select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI
	select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS
	select ARCH_HAS_FAST_MULTIPLIER
	select ARCH_HAS_GCOV_PROFILE_ALL
	select ARCH_HAS_KCOV			if X86_64
	select ARCH_HAS_PMEM_API		if X86_64
	select ARCH_HAS_MMIO_FLUSH
	select ARCH_HAS_SG_CHAIN
	select ARCH_HAS_UBSAN_SANITIZE_ALL
	select ARCH_MIGHT_HAVE_PC_PARPORT
	select ARCH_MIGHT_HAVE_PC_SERIO
	select HAVE_AOUT if X86_32
+0 −10
Original line number Diff line number Diff line
@@ -9,16 +9,6 @@
# Changed by many, many contributors over the years.
#

KASAN_SANITIZE			:= n
OBJECT_FILES_NON_STANDARD	:= y

# Kernel does not boot with kcov instrumentation here.
# One of the problems observed was insertion of __sanitizer_cov_trace_pc()
# callback into middle of per-cpu data enabling code. Thus the callback observed
# inconsistent state and crashed. We are interested mostly in syscall coverage,
# so boot code is not interesting anyway.
KCOV_INSTRUMENT		:= n

# If you want to preset the SVGA mode, uncomment the next line and
# set SVGA_MODE to whatever number you want.
# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
+0 −5
Original line number Diff line number Diff line
@@ -4,11 +4,6 @@
# create a compressed vmlinux image from the original vmlinux
#

KASAN_SANITIZE := n

# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
KCOV_INSTRUMENT		:= n

targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
	vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4

Loading