Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kcov: improve documentation

Improve KCOV documentation:

- Use KCOV instead of kcov, as the former is more widely-used.

- Mention Clang in compiler requirements.

- Use ``annotations`` for inline code.

- Rework remote coverage collection documentation for better clarity.

- Various smaller changes.

[andreyknvl@google.com: v2]
Link: https://lkml.kernel.org/r/583f41c49eef15210fa813e8229730d11427efa7.1677614637.git.andreyknvl@google.com
[andreyknvl@google.com: fix ``annotation`` for KCOV_REMOTE_ENABLE]
Link: https://lkml.kernel.org/r/72be5c215c275f35891229b90622ed859f196a46.1677684837.git.andreyknvl@google.com
Link: https://lkml.kernel.org/r/0b5efd70e31bba7912cf9a6c951f0e76a8df27df.1677517724.git.andreyknvl@google.com
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Reviewed-by: Bagas Sanjaya <bagasdotme@gmail.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Marco Elver <elver@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Andrey Konovalov and committed by
Andrew Morton
7b32137b f9641a36

+97 -62
+97 -62
Documentation/dev-tools/kcov.rst
··· 1 - kcov: code coverage for fuzzing 1 + KCOV: code coverage for fuzzing 2 2 =============================== 3 3 4 - kcov exposes kernel code coverage information in a form suitable for coverage- 5 - guided fuzzing (randomized testing). Coverage data of a running kernel is 6 - exported via the "kcov" debugfs file. Coverage collection is enabled on a task 7 - basis, and thus it can capture precise coverage of a single system call. 4 + KCOV collects and exposes kernel code coverage information in a form suitable 5 + for coverage-guided fuzzing. Coverage data of a running kernel is exported via 6 + the ``kcov`` debugfs file. Coverage collection is enabled on a task basis, and 7 + thus KCOV can capture precise coverage of a single system call. 8 8 9 - Note that kcov does not aim to collect as much coverage as possible. It aims 10 - to collect more or less stable coverage that is function of syscall inputs. 11 - To achieve this goal it does not collect coverage in soft/hard interrupts 12 - and instrumentation of some inherently non-deterministic parts of kernel is 13 - disabled (e.g. scheduler, locking). 9 + Note that KCOV does not aim to collect as much coverage as possible. It aims 10 + to collect more or less stable coverage that is a function of syscall inputs. 11 + To achieve this goal, it does not collect coverage in soft/hard interrupts 12 + (unless remove coverage collection is enabled, see below) and from some 13 + inherently non-deterministic parts of the kernel (e.g. scheduler, locking). 14 14 15 - kcov is also able to collect comparison operands from the instrumented code 16 - (this feature currently requires that the kernel is compiled with clang). 15 + Besides collecting code coverage, KCOV can also collect comparison operands. 16 + See the "Comparison operands collection" section for details. 17 + 18 + Besides collecting coverage data from syscall handlers, KCOV can also collect 19 + coverage for annotated parts of the kernel executing in background kernel 20 + tasks or soft interrupts. See the "Remote coverage collection" section for 21 + details. 17 22 18 23 Prerequisites 19 24 ------------- 20 25 21 - Configure the kernel with:: 26 + KCOV relies on compiler instrumentation and requires GCC 6.1.0 or later 27 + or any Clang version supported by the kernel. 28 + 29 + Collecting comparison operands is supported with GCC 8+ or with Clang. 30 + 31 + To enable KCOV, configure the kernel with:: 22 32 23 33 CONFIG_KCOV=y 24 34 25 - CONFIG_KCOV requires gcc 6.1.0 or later. 26 - 27 - If the comparison operands need to be collected, set:: 35 + To enable comparison operands collection, set:: 28 36 29 37 CONFIG_KCOV_ENABLE_COMPARISONS=y 30 38 31 - Profiling data will only become accessible once debugfs has been mounted:: 39 + Coverage data only becomes accessible once debugfs has been mounted:: 32 40 33 41 mount -t debugfs none /sys/kernel/debug 34 42 35 43 Coverage collection 36 44 ------------------- 37 45 38 - The following program demonstrates coverage collection from within a test 39 - program using kcov: 46 + The following program demonstrates how to use KCOV to collect coverage for a 47 + single syscall from within a test program: 40 48 41 49 .. code-block:: c 42 50 ··· 92 84 perror("ioctl"), exit(1); 93 85 /* Reset coverage from the tail of the ioctl() call. */ 94 86 __atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED); 95 - /* That's the target syscal call. */ 87 + /* Call the target syscall call. */ 96 88 read(-1, NULL, 0); 97 89 /* Read number of PCs collected. */ 98 90 n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED); ··· 111 103 return 0; 112 104 } 113 105 114 - After piping through addr2line output of the program looks as follows:: 106 + After piping through ``addr2line`` the output of the program looks as follows:: 115 107 116 108 SyS_read 117 109 fs/read_write.c:562 ··· 129 121 fs/read_write.c:562 130 122 131 123 If a program needs to collect coverage from several threads (independently), 132 - it needs to open /sys/kernel/debug/kcov in each thread separately. 124 + it needs to open ``/sys/kernel/debug/kcov`` in each thread separately. 133 125 134 126 The interface is fine-grained to allow efficient forking of test processes. 135 - That is, a parent process opens /sys/kernel/debug/kcov, enables trace mode, 136 - mmaps coverage buffer and then forks child processes in a loop. Child processes 137 - only need to enable coverage (disable happens automatically on thread end). 127 + That is, a parent process opens ``/sys/kernel/debug/kcov``, enables trace mode, 128 + mmaps coverage buffer, and then forks child processes in a loop. The child 129 + processes only need to enable coverage (it gets disabled automatically when 130 + a thread exits). 138 131 139 132 Comparison operands collection 140 133 ------------------------------ ··· 214 205 return 0; 215 206 } 216 207 217 - Note that the kcov modes (coverage collection or comparison operands) are 218 - mutually exclusive. 208 + Note that the KCOV modes (collection of code coverage or comparison operands) 209 + are mutually exclusive. 219 210 220 211 Remote coverage collection 221 212 -------------------------- 222 213 223 - With KCOV_ENABLE coverage is collected only for syscalls that are issued 224 - from the current process. With KCOV_REMOTE_ENABLE it's possible to collect 225 - coverage for arbitrary parts of the kernel code, provided that those parts 226 - are annotated with kcov_remote_start()/kcov_remote_stop(). 214 + Besides collecting coverage data from handlers of syscalls issued from a 215 + userspace process, KCOV can also collect coverage for parts of the kernel 216 + executing in other contexts - so-called "remote" coverage. 227 217 228 - This allows to collect coverage from two types of kernel background 229 - threads: the global ones, that are spawned during kernel boot in a limited 230 - number of instances (e.g. one USB hub_event() worker thread is spawned per 231 - USB HCD); and the local ones, that are spawned when a user interacts with 232 - some kernel interface (e.g. vhost workers); as well as from soft 233 - interrupts. 218 + Using KCOV to collect remote coverage requires: 234 219 235 - To enable collecting coverage from a global background thread or from a 236 - softirq, a unique global handle must be assigned and passed to the 237 - corresponding kcov_remote_start() call. Then a userspace process can pass 238 - a list of such handles to the KCOV_REMOTE_ENABLE ioctl in the handles 239 - array field of the kcov_remote_arg struct. This will attach the used kcov 240 - device to the code sections, that are referenced by those handles. 220 + 1. Modifying kernel code to annotate the code section from where coverage 221 + should be collected with ``kcov_remote_start`` and ``kcov_remote_stop``. 241 222 242 - Since there might be many local background threads spawned from different 243 - userspace processes, we can't use a single global handle per annotation. 244 - Instead, the userspace process passes a non-zero handle through the 245 - common_handle field of the kcov_remote_arg struct. This common handle gets 246 - saved to the kcov_handle field in the current task_struct and needs to be 247 - passed to the newly spawned threads via custom annotations. Those threads 248 - should in turn be annotated with kcov_remote_start()/kcov_remote_stop(). 223 + 2. Using ``KCOV_REMOTE_ENABLE`` instead of ``KCOV_ENABLE`` in the userspace 224 + process that collects coverage. 249 225 250 - Internally kcov stores handles as u64 integers. The top byte of a handle 251 - is used to denote the id of a subsystem that this handle belongs to, and 252 - the lower 4 bytes are used to denote the id of a thread instance within 253 - that subsystem. A reserved value 0 is used as a subsystem id for common 254 - handles as they don't belong to a particular subsystem. The bytes 4-7 are 255 - currently reserved and must be zero. In the future the number of bytes 256 - used for the subsystem or handle ids might be increased. 226 + Both ``kcov_remote_start`` and ``kcov_remote_stop`` annotations and the 227 + ``KCOV_REMOTE_ENABLE`` ioctl accept handles that identify particular coverage 228 + collection sections. The way a handle is used depends on the context where the 229 + matching code section executes. 257 230 258 - When a particular userspace process collects coverage via a common 259 - handle, kcov will collect coverage for each code section that is annotated 260 - to use the common handle obtained as kcov_handle from the current 261 - task_struct. However non common handles allow to collect coverage 262 - selectively from different subsystems. 231 + KCOV supports collecting remote coverage from the following contexts: 232 + 233 + 1. Global kernel background tasks. These are the tasks that are spawned during 234 + kernel boot in a limited number of instances (e.g. one USB ``hub_event`` 235 + worker is spawned per one USB HCD). 236 + 237 + 2. Local kernel background tasks. These are spawned when a userspace process 238 + interacts with some kernel interface and are usually killed when the process 239 + exits (e.g. vhost workers). 240 + 241 + 3. Soft interrupts. 242 + 243 + For #1 and #3, a unique global handle must be chosen and passed to the 244 + corresponding ``kcov_remote_start`` call. Then a userspace process must pass 245 + this handle to ``KCOV_REMOTE_ENABLE`` in the ``handles`` array field of the 246 + ``kcov_remote_arg`` struct. This will attach the used KCOV device to the code 247 + section referenced by this handle. Multiple global handles identifying 248 + different code sections can be passed at once. 249 + 250 + For #2, the userspace process instead must pass a non-zero handle through the 251 + ``common_handle`` field of the ``kcov_remote_arg`` struct. This common handle 252 + gets saved to the ``kcov_handle`` field in the current ``task_struct`` and 253 + needs to be passed to the newly spawned local tasks via custom kernel code 254 + modifications. Those tasks should in turn use the passed handle in their 255 + ``kcov_remote_start`` and ``kcov_remote_stop`` annotations. 256 + 257 + KCOV follows a predefined format for both global and common handles. Each 258 + handle is a ``u64`` integer. Currently, only the one top and the lower 4 bytes 259 + are used. Bytes 4-7 are reserved and must be zero. 260 + 261 + For global handles, the top byte of the handle denotes the id of a subsystem 262 + this handle belongs to. For example, KCOV uses ``1`` as the USB subsystem id. 263 + The lower 4 bytes of a global handle denote the id of a task instance within 264 + that subsystem. For example, each ``hub_event`` worker uses the USB bus number 265 + as the task instance id. 266 + 267 + For common handles, a reserved value ``0`` is used as a subsystem id, as such 268 + handles don't belong to a particular subsystem. The lower 4 bytes of a common 269 + handle identify a collective instance of all local tasks spawned by the 270 + userspace process that passed a common handle to ``KCOV_REMOTE_ENABLE``. 271 + 272 + In practice, any value can be used for common handle instance id if coverage 273 + is only collected from a single userspace process on the system. However, if 274 + common handles are used by multiple processes, unique instance ids must be 275 + used for each process. One option is to use the process id as the common 276 + handle instance id. 277 + 278 + The following program demonstrates using KCOV to collect coverage from both 279 + local tasks spawned by the process and the global task that handles USB bus #1: 263 280 264 281 .. code-block:: c 265 282