Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0 */ 2 : #ifndef _LINUX_KCOV_H 3 : #define _LINUX_KCOV_H 4 : 5 : #include <uapi/linux/kcov.h> 6 : 7 : struct task_struct; 8 : 9 : #ifdef CONFIG_KCOV 10 : 11 : enum kcov_mode { 12 : /* Coverage collection is not enabled yet. */ 13 : KCOV_MODE_DISABLED = 0, 14 : /* KCOV was initialized, but tracing mode hasn't been chosen yet. */ 15 : KCOV_MODE_INIT = 1, 16 : /* 17 : * Tracing coverage collection mode. 18 : * Covered PCs are collected in a per-task buffer. 19 : */ 20 : KCOV_MODE_TRACE_PC = 2, 21 : /* Collecting comparison operands mode. */ 22 : KCOV_MODE_TRACE_CMP = 3, 23 : }; 24 : 25 : #define KCOV_IN_CTXSW (1 << 30) 26 : 27 : void kcov_task_init(struct task_struct *t); 28 : void kcov_task_exit(struct task_struct *t); 29 : 30 : #define kcov_prepare_switch(t) \ 31 : do { \ 32 : (t)->kcov_mode |= KCOV_IN_CTXSW; \ 33 : } while (0) 34 : 35 : #define kcov_finish_switch(t) \ 36 : do { \ 37 : (t)->kcov_mode &= ~KCOV_IN_CTXSW; \ 38 : } while (0) 39 : 40 : /* See Documentation/dev-tools/kcov.rst for usage details. */ 41 : void kcov_remote_start(u64 handle); 42 : void kcov_remote_stop(void); 43 : u64 kcov_common_handle(void); 44 : 45 : static inline void kcov_remote_start_common(u64 id) 46 : { 47 : kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_COMMON, id)); 48 : } 49 : 50 : static inline void kcov_remote_start_usb(u64 id) 51 : { 52 : kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_USB, id)); 53 : } 54 : 55 : /* 56 : * The softirq flavor of kcov_remote_*() functions is introduced as a temporary 57 : * work around for kcov's lack of nested remote coverage sections support in 58 : * task context. Adding suport for nested sections is tracked in: 59 : * https://bugzilla.kernel.org/show_bug.cgi?id=210337 60 : */ 61 : 62 : static inline void kcov_remote_start_usb_softirq(u64 id) 63 : { 64 : if (in_serving_softirq()) 65 : kcov_remote_start_usb(id); 66 : } 67 : 68 : static inline void kcov_remote_stop_softirq(void) 69 : { 70 : if (in_serving_softirq()) 71 : kcov_remote_stop(); 72 : } 73 : 74 : #else 75 : 76 916 : static inline void kcov_task_init(struct task_struct *t) {} 77 0 : static inline void kcov_task_exit(struct task_struct *t) {} 78 26511 : static inline void kcov_prepare_switch(struct task_struct *t) {} 79 26515 : static inline void kcov_finish_switch(struct task_struct *t) {} 80 : static inline void kcov_remote_start(u64 handle) {} 81 : static inline void kcov_remote_stop(void) {} 82 4864 : static inline u64 kcov_common_handle(void) 83 : { 84 4864 : return 0; 85 : } 86 : static inline void kcov_remote_start_common(u64 id) {} 87 : static inline void kcov_remote_start_usb(u64 id) {} 88 : static inline void kcov_remote_start_usb_softirq(u64 id) {} 89 : static inline void kcov_remote_stop_softirq(void) {} 90 : 91 : #endif /* CONFIG_KCOV */ 92 : #endif /* _LINUX_KCOV_H */