Kernel coverage gets one framework, Clang MC/DC support
Sasha Levin’s second-round series folds gcov and KCOV together and adds source-based coverage that safety standards require.
Sasha Levin has posted a revised 20-patch series that consolidates the Linux kernel’s scattered code-coverage implementations into one framework and adds Clang source-based coverage with Modified Condition/Decision Coverage (MC/DC).
Earlier postings of Clang coverage drew pushback for introducing a third stack beside gcov and KCOV, each with its own Kconfig menus, build flags, profiling annotations and debugfs layout. Reviewers also insisted that instrumentation honour noinstr. The new series answers both points: existing backends move under a shared core that owns configuration, COVERAGE_PROFILE annotations, reset and the /sys/kernel/debug/coverage/ tree. Each backend supplies only toolchain-specific flags, data format and architecture support. Dependencies that mean “the kernel is instrumented” (LTO, KCFI and similar) now key off a single COVERAGE_KERNEL symbol rather than gcov-specific names.
Clang’s source-based path instruments in the compiler front end, so results map back to source conditions even under the optimizations the kernel always uses. gcov works at object-code level and can lose that precision. Levin cites a four-condition test in the DMI scanner where gcov reported six branch outcomes while the Clang path reported each condition separately. The same backend exports a raw profile for the built-in kernel image; modules are left uninstrumented for now. x86_64 is the first architecture enabled.
MC/DC, required by several automotive and aviation certification regimes, is wired for both Clang (since version 18) and GCC 14’s condition-coverage mode. It checks that every condition in a boolean decision has independently affected the outcome. A related gcov fix stops IOR-style bitset counters (including MC/DC condition data) from being merged with addition instead of bitwise OR, a long-standing error.
Coverage instrumentation had also been leaking into noinstr paths through empty lockdep and perf stubs that failed to inline, GHCB accessors that still called instrumented bitops, and counter updates that objtool could not see. The series makes the stubs always-inline, switches the accessors to uninstrumented bitops, teaches objtool to flag coverage-counter references outside instrumentation sections, and then drops redundant Makefile exclusions on x86 entry and SEV code so noinstr alone is the barrier. Generic entry code stays excluded for a different reason: some interrupt-exit helpers run after hardirq context and would otherwise pollute the interrupted task’s KCOV trace.
Documentation is updated to describe the common interface, MC/DC options and noinstr rules. Portions of the Clang work build on earlier efforts by Wentao Zhang and Sami Tolvanen.