> - Per-task buffer: task->kcov_df_area with atomic xadd reservation I don't understand this line...
> - Recursion-safe: notrace __no_sanitize_coverage noinline > - ERR_PTR aware: skips struct expansion for error pointers ... and this. > > The callbacks (__sanitizer_cov_trace_args/ret) are inserted by the > compiler when -fsanitize-coverage=dataflow-args,dataflow-ret is used. > The Kconfig options depend on cc-option to verify compiler support. > > Buffer format (TLV records, all u64): > area[0]: atomic word count > [pos+0]: type_and_seq (0xE=entry, 0xF=return in upper 4 bits) > [pos+1]: PC > [pos+2]: meta (arg_idx | arg_size | ptr) > [pos+3..N]: field values read via copy_from_kernel_nofault() > > This is completely independent from legacy /sys/kernel/debug/kcov. > Existing users (syzkaller, oss-fuzz) are unaffected. Does oss-fuzz even use kcov? > > Signed-off-by: Yunseong Kim <[email protected]> > --- > include/linux/sched.h | 8 ++ > kernel/kcov.c | 291 > ++++++++++++++++++++++++++++++++++++++++++++++++++ > lib/Kconfig.debug | 22 ++++ > 3 files changed, 321 insertions(+) > > diff --git a/include/linux/sched.h b/include/linux/sched.h > index c4433c185ad8..03be4b495f70 100644 > --- a/include/linux/sched.h > +++ b/include/linux/sched.h > @@ -1533,6 +1533,14 @@ struct task_struct { > /* KCOV sequence number: */ > int kcov_sequence; > > + /* KCOV dataflow per-task sequence counter for TLV records: */ > + u32 kcov_dataflow_seq; > + > + /* KCOV dataflow: separate buffer for trace-args/trace-ret */ > + unsigned int kcov_df_size; > + void *kcov_df_area; > + bool kcov_df_enabled; > + > /* Collect coverage from softirq context: */ > unsigned int kcov_softirq; > #endif > diff --git a/kernel/kcov.c b/kernel/kcov.c > index 1df373fb562b..d3c9c0efe961 100644 > --- a/kernel/kcov.c > +++ b/kernel/kcov.c > @@ -353,6 +353,288 @@ void notrace __sanitizer_cov_trace_switch(kcov_u64 val, > void *arg) > EXPORT_SYMBOL(__sanitizer_cov_trace_switch); > #endif /* ifdef CONFIG_KCOV_ENABLE_COMPARISONS */ > > +#if defined(CONFIG_KCOV_DATAFLOW_ARGS) || defined(CONFIG_KCOV_DATAFLOW_RET) > +/* > + * KCOV Dataflow: /sys/kernel/debug/kcov_dataflow > + * > + * Completely separate from legacy /sys/kernel/debug/kcov. Since this code is completely separate, could it be put into a separate file? I think kcov.c is too big already. > + * Own buffer, own ioctl, own mmap. No printk — buffer only. Can you please not use these long dashes in C code? > +/* > + * Core write function — no printk, no locks, just atomic buffer write. I think it's okay to omit what this function is not doing. > + > + /* Atomic reservation */ > + pos = 1 + xadd((unsigned long *)&area[0], record_len); > + if (unlikely(pos + record_len > max_pos)) { > + xadd((unsigned long *)&area[0], -(long)record_len); > + return; > + } Have you tried compiling this code on ARM64? I am pretty sure they don't have xadd(), so it won't work. But why do we need an atomic increment here at all? write_comp_data() performs the same job, and does not need it. Or am I missing something?

