~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/dev-tools/kcov.rst

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /Documentation/dev-tools/kcov.rst (Version linux-6.12-rc7) and /Documentation/dev-tools/kcov.rst (Version linux-2.6.0)


  1 KCOV: code coverage for fuzzing                   
  2 ===============================                   
  3                                                   
  4 KCOV collects and exposes kernel code coverage    
  5 for coverage-guided fuzzing. Coverage data of     
  6 the ``kcov`` debugfs file. Coverage collection    
  7 thus KCOV can capture precise coverage of a si    
  8                                                   
  9 Note that KCOV does not aim to collect as much    
 10 to collect more or less stable coverage that i    
 11 To achieve this goal, it does not collect cove    
 12 (unless remove coverage collection is enabled,    
 13 inherently non-deterministic parts of the kern    
 14                                                   
 15 Besides collecting code coverage, KCOV can als    
 16 See the "Comparison operands collection" secti    
 17                                                   
 18 Besides collecting coverage data from syscall     
 19 coverage for annotated parts of the kernel exe    
 20 tasks or soft interrupts. See the "Remote cove    
 21 details.                                          
 22                                                   
 23 Prerequisites                                     
 24 -------------                                     
 25                                                   
 26 KCOV relies on compiler instrumentation and re    
 27 or any Clang version supported by the kernel.     
 28                                                   
 29 Collecting comparison operands is supported wi    
 30                                                   
 31 To enable KCOV, configure the kernel with::       
 32                                                   
 33         CONFIG_KCOV=y                             
 34                                                   
 35 To enable comparison operands collection, set:    
 36                                                   
 37         CONFIG_KCOV_ENABLE_COMPARISONS=y          
 38                                                   
 39 Coverage data only becomes accessible once deb    
 40                                                   
 41         mount -t debugfs none /sys/kernel/debu    
 42                                                   
 43 Coverage collection                               
 44 -------------------                               
 45                                                   
 46 The following program demonstrates how to use     
 47 single syscall from within a test program:        
 48                                                   
 49 .. code-block:: c                                 
 50                                                   
 51     #include <stdio.h>                            
 52     #include <stddef.h>                           
 53     #include <stdint.h>                           
 54     #include <stdlib.h>                           
 55     #include <sys/types.h>                        
 56     #include <sys/stat.h>                         
 57     #include <sys/ioctl.h>                        
 58     #include <sys/mman.h>                         
 59     #include <unistd.h>                           
 60     #include <fcntl.h>                            
 61     #include <linux/types.h>                      
 62                                                   
 63     #define KCOV_INIT_TRACE                       
 64     #define KCOV_ENABLE                 _IO('c    
 65     #define KCOV_DISABLE                          
 66     #define COVER_SIZE                  (64<<1    
 67                                                   
 68     #define KCOV_TRACE_PC  0                      
 69     #define KCOV_TRACE_CMP 1                      
 70                                                   
 71     int main(int argc, char **argv)               
 72     {                                             
 73         int fd;                                   
 74         unsigned long *cover, n, i;               
 75                                                   
 76         /* A single fd descriptor allows cover    
 77          * thread.                                
 78          */                                       
 79         fd = open("/sys/kernel/debug/kcov", O_    
 80         if (fd == -1)                             
 81                 perror("open"), exit(1);          
 82         /* Setup trace mode and trace size. */    
 83         if (ioctl(fd, KCOV_INIT_TRACE, COVER_S    
 84                 perror("ioctl"), exit(1);         
 85         /* Mmap buffer shared between kernel-     
 86         cover = (unsigned long*)mmap(NULL, COV    
 87                                      PROT_READ    
 88         if ((void*)cover == MAP_FAILED)           
 89                 perror("mmap"), exit(1);          
 90         /* Enable coverage collection on the c    
 91         if (ioctl(fd, KCOV_ENABLE, KCOV_TRACE_    
 92                 perror("ioctl"), exit(1);         
 93         /* Reset coverage from the tail of the    
 94         __atomic_store_n(&cover[0], 0, __ATOMI    
 95         /* Call the target syscall call. */       
 96         read(-1, NULL, 0);                        
 97         /* Read number of PCs collected. */       
 98         n = __atomic_load_n(&cover[0], __ATOMI    
 99         for (i = 0; i < n; i++)                   
100                 printf("0x%lx\n", cover[i + 1]    
101         /* Disable coverage collection for the    
102          * coverage can be enabled for a diffe    
103          */                                       
104         if (ioctl(fd, KCOV_DISABLE, 0))           
105                 perror("ioctl"), exit(1);         
106         /* Free resources. */                     
107         if (munmap(cover, COVER_SIZE * sizeof(    
108                 perror("munmap"), exit(1);        
109         if (close(fd))                            
110                 perror("close"), exit(1);         
111         return 0;                                 
112     }                                             
113                                                   
114 After piping through ``addr2line`` the output     
115                                                   
116     SyS_read                                      
117     fs/read_write.c:562                           
118     __fdget_pos                                   
119     fs/file.c:774                                 
120     __fget_light                                  
121     fs/file.c:746                                 
122     __fget_light                                  
123     fs/file.c:750                                 
124     __fget_light                                  
125     fs/file.c:760                                 
126     __fdget_pos                                   
127     fs/file.c:784                                 
128     SyS_read                                      
129     fs/read_write.c:562                           
130                                                   
131 If a program needs to collect coverage from se    
132 it needs to open ``/sys/kernel/debug/kcov`` in    
133                                                   
134 The interface is fine-grained to allow efficie    
135 That is, a parent process opens ``/sys/kernel/    
136 mmaps coverage buffer, and then forks child pr    
137 processes only need to enable coverage (it get    
138 a thread exits).                                  
139                                                   
140 Comparison operands collection                    
141 ------------------------------                    
142                                                   
143 Comparison operands collection is similar to c    
144                                                   
145 .. code-block:: c                                 
146                                                   
147     /* Same includes and defines as above. */     
148                                                   
149     /* Number of 64-bit words per record. */      
150     #define KCOV_WORDS_PER_CMP 4                  
151                                                   
152     /*                                            
153      * The format for the types of collected c    
154      *                                            
155      * Bit 0 shows whether one of the argument    
156      * Bits 1 & 2 contain log2 of the argument    
157      */                                           
158                                                   
159     #define KCOV_CMP_CONST          (1 << 0)      
160     #define KCOV_CMP_SIZE(n)        ((n) << 1)    
161     #define KCOV_CMP_MASK           KCOV_CMP_S    
162                                                   
163     int main(int argc, char **argv)               
164     {                                             
165         int fd;                                   
166         uint64_t *cover, type, arg1, arg2, is_    
167         unsigned long n, i;                       
168                                                   
169         fd = open("/sys/kernel/debug/kcov", O_    
170         if (fd == -1)                             
171                 perror("open"), exit(1);          
172         if (ioctl(fd, KCOV_INIT_TRACE, COVER_S    
173                 perror("ioctl"), exit(1);         
174         /*                                        
175         * Note that the buffer pointer is of t    
176         * the comparison operands are promoted    
177         */                                        
178         cover = (uint64_t *)mmap(NULL, COVER_S    
179                                      PROT_READ    
180         if ((void*)cover == MAP_FAILED)           
181                 perror("mmap"), exit(1);          
182         /* Note KCOV_TRACE_CMP instead of KCOV    
183         if (ioctl(fd, KCOV_ENABLE, KCOV_TRACE_    
184                 perror("ioctl"), exit(1);         
185         __atomic_store_n(&cover[0], 0, __ATOMI    
186         read(-1, NULL, 0);                        
187         /* Read number of comparisons collecte    
188         n = __atomic_load_n(&cover[0], __ATOMI    
189         for (i = 0; i < n; i++) {                 
190                 uint64_t ip;                      
191                                                   
192                 type = cover[i * KCOV_WORDS_PE    
193                 /* arg1 and arg2 - operands of    
194                 arg1 = cover[i * KCOV_WORDS_PE    
195                 arg2 = cover[i * KCOV_WORDS_PE    
196                 /* ip - caller address. */        
197                 ip = cover[i * KCOV_WORDS_PER_    
198                 /* size of the operands. */       
199                 size = 1 << ((type & KCOV_CMP_    
200                 /* is_const - true if either o    
201                 is_const = type & KCOV_CMP_CON    
202                 printf("ip: 0x%lx type: 0x%lx,    
203                         "size: %lu, %s\n",        
204                         ip, type, arg1, arg2,     
205                 is_const ? "const" : "non-cons    
206         }                                         
207         if (ioctl(fd, KCOV_DISABLE, 0))           
208                 perror("ioctl"), exit(1);         
209         /* Free resources. */                     
210         if (munmap(cover, COVER_SIZE * sizeof(    
211                 perror("munmap"), exit(1);        
212         if (close(fd))                            
213                 perror("close"), exit(1);         
214         return 0;                                 
215     }                                             
216                                                   
217 Note that the KCOV modes (collection of code c    
218 are mutually exclusive.                           
219                                                   
220 Remote coverage collection                        
221 --------------------------                        
222                                                   
223 Besides collecting coverage data from handlers    
224 userspace process, KCOV can also collect cover    
225 executing in other contexts - so-called "remot    
226                                                   
227 Using KCOV to collect remote coverage requires    
228                                                   
229 1. Modifying kernel code to annotate the code     
230    should be collected with ``kcov_remote_star    
231                                                   
232 2. Using ``KCOV_REMOTE_ENABLE`` instead of ``K    
233    process that collects coverage.                
234                                                   
235 Both ``kcov_remote_start`` and ``kcov_remote_s    
236 ``KCOV_REMOTE_ENABLE`` ioctl accept handles th    
237 collection sections. The way a handle is used     
238 matching code section executes.                   
239                                                   
240 KCOV supports collecting remote coverage from     
241                                                   
242 1. Global kernel background tasks. These are t    
243    kernel boot in a limited number of instance    
244    worker is spawned per one USB HCD).            
245                                                   
246 2. Local kernel background tasks. These are sp    
247    interacts with some kernel interface and ar    
248    exits (e.g. vhost workers).                    
249                                                   
250 3. Soft interrupts.                               
251                                                   
252 For #1 and #3, a unique global handle must be     
253 corresponding ``kcov_remote_start`` call. Then    
254 this handle to ``KCOV_REMOTE_ENABLE`` in the `    
255 ``kcov_remote_arg`` struct. This will attach t    
256 section referenced by this handle. Multiple gl    
257 different code sections can be passed at once.    
258                                                   
259 For #2, the userspace process instead must pas    
260 ``common_handle`` field of the ``kcov_remote_a    
261 gets saved to the ``kcov_handle`` field in the    
262 needs to be passed to the newly spawned local     
263 modifications. Those tasks should in turn use     
264 ``kcov_remote_start`` and ``kcov_remote_stop``    
265                                                   
266 KCOV follows a predefined format for both glob    
267 handle is a ``u64`` integer. Currently, only t    
268 are used. Bytes 4-7 are reserved and must be z    
269                                                   
270 For global handles, the top byte of the handle    
271 this handle belongs to. For example, KCOV uses    
272 The lower 4 bytes of a global handle denote th    
273 that subsystem. For example, each ``hub_event`    
274 as the task instance id.                          
275                                                   
276 For common handles, a reserved value ``0`` is     
277 handles don't belong to a particular subsystem    
278 handle identify a collective instance of all l    
279 userspace process that passed a common handle     
280                                                   
281 In practice, any value can be used for common     
282 is only collected from a single userspace proc    
283 common handles are used by multiple processes,    
284 used for each process. One option is to use th    
285 handle instance id.                               
286                                                   
287 The following program demonstrates using KCOV     
288 local tasks spawned by the process and the glo    
289                                                   
290 .. code-block:: c                                 
291                                                   
292     /* Same includes and defines as above. */     
293                                                   
294     struct kcov_remote_arg {                      
295         __u32           trace_mode;               
296         __u32           area_size;                
297         __u32           num_handles;              
298         __aligned_u64   common_handle;            
299         __aligned_u64   handles[0];               
300     };                                            
301                                                   
302     #define KCOV_INIT_TRACE                       
303     #define KCOV_DISABLE                          
304     #define KCOV_REMOTE_ENABLE          _IOW('    
305                                                   
306     #define COVER_SIZE  (64 << 10)                
307                                                   
308     #define KCOV_TRACE_PC       0                 
309                                                   
310     #define KCOV_SUBSYSTEM_COMMON       (0x00u    
311     #define KCOV_SUBSYSTEM_USB  (0x01ull << 56    
312                                                   
313     #define KCOV_SUBSYSTEM_MASK (0xffull << 56    
314     #define KCOV_INSTANCE_MASK  (0xffffffffull    
315                                                   
316     static inline __u64 kcov_remote_handle(__u    
317     {                                             
318         if (subsys & ~KCOV_SUBSYSTEM_MASK || i    
319                 return 0;                         
320         return subsys | inst;                     
321     }                                             
322                                                   
323     #define KCOV_COMMON_ID      0x42              
324     #define KCOV_USB_BUS_NUM    1                 
325                                                   
326     int main(int argc, char **argv)               
327     {                                             
328         int fd;                                   
329         unsigned long *cover, n, i;               
330         struct kcov_remote_arg *arg;              
331                                                   
332         fd = open("/sys/kernel/debug/kcov", O_    
333         if (fd == -1)                             
334                 perror("open"), exit(1);          
335         if (ioctl(fd, KCOV_INIT_TRACE, COVER_S    
336                 perror("ioctl"), exit(1);         
337         cover = (unsigned long*)mmap(NULL, COV    
338                                      PROT_READ    
339         if ((void*)cover == MAP_FAILED)           
340                 perror("mmap"), exit(1);          
341                                                   
342         /* Enable coverage collection via comm    
343         arg = calloc(1, sizeof(*arg) + sizeof(    
344         if (!arg)                                 
345                 perror("calloc"), exit(1);        
346         arg->trace_mode = KCOV_TRACE_PC;          
347         arg->area_size = COVER_SIZE;              
348         arg->num_handles = 1;                     
349         arg->common_handle = kcov_remote_handl    
350                                                   
351         arg->handles[0] = kcov_remote_handle(K    
352                                                   
353         if (ioctl(fd, KCOV_REMOTE_ENABLE, arg)    
354                 perror("ioctl"), free(arg), ex    
355         free(arg);                                
356                                                   
357         /*                                        
358          * Here the user needs to trigger exec    
359          * that is either annotated with the c    
360          * activity on USB bus #1.                
361          */                                       
362         sleep(2);                                 
363                                                   
364         n = __atomic_load_n(&cover[0], __ATOMI    
365         for (i = 0; i < n; i++)                   
366                 printf("0x%lx\n", cover[i + 1]    
367         if (ioctl(fd, KCOV_DISABLE, 0))           
368                 perror("ioctl"), exit(1);         
369         if (munmap(cover, COVER_SIZE * sizeof(    
370                 perror("munmap"), exit(1);        
371         if (close(fd))                            
372                 perror("close"), exit(1);         
373         return 0;                                 
374     }                                             
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php