kcov.h 2.4 KB

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