Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _LINUX_KCOV_H
0003 #define _LINUX_KCOV_H
0004 
0005 #include <linux/sched.h>
0006 #include <uapi/linux/kcov.h>
0007 
0008 struct task_struct;
0009 
0010 #ifdef CONFIG_KCOV
0011 
0012 enum kcov_mode {
0013     /* Coverage collection is not enabled yet. */
0014     KCOV_MODE_DISABLED = 0,
0015     /* KCOV was initialized, but tracing mode hasn't been chosen yet. */
0016     KCOV_MODE_INIT = 1,
0017     /*
0018      * Tracing coverage collection mode.
0019      * Covered PCs are collected in a per-task buffer.
0020      */
0021     KCOV_MODE_TRACE_PC = 2,
0022     /* Collecting comparison operands mode. */
0023     KCOV_MODE_TRACE_CMP = 3,
0024 };
0025 
0026 #define KCOV_IN_CTXSW   (1 << 30)
0027 
0028 void kcov_task_init(struct task_struct *t);
0029 void kcov_task_exit(struct task_struct *t);
0030 
0031 #define kcov_prepare_switch(t)          \
0032 do {                        \
0033     (t)->kcov_mode |= KCOV_IN_CTXSW;    \
0034 } while (0)
0035 
0036 #define kcov_finish_switch(t)           \
0037 do {                        \
0038     (t)->kcov_mode &= ~KCOV_IN_CTXSW;   \
0039 } while (0)
0040 
0041 /* See Documentation/dev-tools/kcov.rst for usage details. */
0042 void kcov_remote_start(u64 handle);
0043 void kcov_remote_stop(void);
0044 u64 kcov_common_handle(void);
0045 
0046 static inline void kcov_remote_start_common(u64 id)
0047 {
0048     kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_COMMON, id));
0049 }
0050 
0051 static inline void kcov_remote_start_usb(u64 id)
0052 {
0053     kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_USB, id));
0054 }
0055 
0056 /*
0057  * The softirq flavor of kcov_remote_*() functions is introduced as a temporary
0058  * work around for kcov's lack of nested remote coverage sections support in
0059  * task context. Adding suport for nested sections is tracked in:
0060  * https://bugzilla.kernel.org/show_bug.cgi?id=210337
0061  */
0062 
0063 static inline void kcov_remote_start_usb_softirq(u64 id)
0064 {
0065     if (in_serving_softirq())
0066         kcov_remote_start_usb(id);
0067 }
0068 
0069 static inline void kcov_remote_stop_softirq(void)
0070 {
0071     if (in_serving_softirq())
0072         kcov_remote_stop();
0073 }
0074 
0075 #else
0076 
0077 static inline void kcov_task_init(struct task_struct *t) {}
0078 static inline void kcov_task_exit(struct task_struct *t) {}
0079 static inline void kcov_prepare_switch(struct task_struct *t) {}
0080 static inline void kcov_finish_switch(struct task_struct *t) {}
0081 static inline void kcov_remote_start(u64 handle) {}
0082 static inline void kcov_remote_stop(void) {}
0083 static inline u64 kcov_common_handle(void)
0084 {
0085     return 0;
0086 }
0087 static inline void kcov_remote_start_common(u64 id) {}
0088 static inline void kcov_remote_start_usb(u64 id) {}
0089 static inline void kcov_remote_start_usb_softirq(u64 id) {}
0090 static inline void kcov_remote_stop_softirq(void) {}
0091 
0092 #endif /* CONFIG_KCOV */
0093 #endif /* _LINUX_KCOV_H */