Re: [RFC PATCH 0/4] Enable Clang's Source-based Code Coverage and MC/DC for x86-64

Chuck Wolber
2025-10-15T08:26:54Z

On Wed Oct 15, 2025 at 7:41 AM UTC, Peter Zijlstra wrote:
> On Tue, Oct 14, 2025 at 07:26:35PM -0400, Sasha Levin wrote:
>> This series adds support for Clang's Source-based Code Coverage to the
>> Linux kernel, enabling more accurate coverage measurement at the source
>> level compared to gcov. This is particularly valuable for safety-critical
>> use cases (automotive, medical, aerospace) where MC/DC coverage is required
>> for certification.
>>
>> Changes since previous patchset [1]:
>> - Rebased on v6.18-rc1
>> - Adapted to lib/crypto reorganization (curve25519 exclusion moved to
>> lib/crypto/Makefile)
>> - Minor correctness fixes throughout the codebase
>>
>> The implementation has been tested with a kernel build using Clang 18+ and
>> boots successfully in a KVM environment with instrumentation enabled.
>>
>> [1] https://lore.kernel.org/all/20240905043245.1389509-1-wentaoz5@illinois.edu/
>>
>> Wentao Zhang (4):
>> llvm-cov: add Clang's Source-based Code Coverage support
>> llvm-cov: add Clang's MC/DC support
>> x86: disable llvm-cov instrumentation
>> x86: enable llvm-cov support
>>
>> Makefile | 9 ++
>> arch/Kconfig | 1 +
>> arch/x86/Kconfig | 2 +
>> arch/x86/crypto/Makefile | 1 +
>> arch/x86/kernel/vmlinux.lds.S | 2 +
>> include/asm-generic/vmlinux.lds.h | 36 +++++
>> kernel/Makefile | 1 +
>> kernel/llvm-cov/Kconfig | 121 ++++++++++++++
>> kernel/llvm-cov/Makefile | 8 +
>> kernel/llvm-cov/fs.c | 253 ++++++++++++++++++++++++++++++
>> kernel/llvm-cov/llvm-cov.h | 157 ++++++++++++++++++
>> lib/crypto/Makefile | 3 +-
>> scripts/Makefile.lib | 23 +++
>> scripts/mod/modpost.c | 2 +
>
> I'm thinking I'm going to NAK this based on the fact that I'm not
> interested in playing file based games. As long as this thing doesn't
> honour noinstr I don't want this near x86.

I am working on a noinstr patchset that will precede this pachset. As it turns
out there are several areas of the kernel (128 that I have found so far) that
are missing the noinstr attribute macro.

Example:

kernel/locking/lockdep.c:
void noinstr lockdep_hardirqs_off(unsigned long ip)
include/linux/irqflags.h:
static inline void lockdep_hardirqs_off(unsigned long ip) { }

The latter version is intended to be optimized out if the kernel is not
configured to use this feature. However when the kernel is instrumented for
profiling, the stub is not optimized out and ends up in the .text section
rather than the .noinstr.text section.

> And we have kcov support, and gcov and now llvm-cov, surely 3 coverage
> solutions is like 2 too many?

Optimization makes it nearly impossible to correlate GCov results back to
actual lines of source. llvm-cov instruments at the AST level which enables
precise mapping back to source code regardless of optimization level.

A detailed rundown on this issue can be found here[1], with the most relevant
excerpt reproduced here:

> In the following gcov example from drivers/firmware/dmi_scan.c, an
> expression with four conditions is reported to have six branch outcomes,
> which is not ideally informative in many safety related use cases, such as
> automotive, medical, and aerospace.
>
> 5: 1068: if (s == e || *e != '/' || !month || month > 12) {
> branch 0 taken 5 (fallthrough)
> branch 1 taken 0
> branch 2 taken 5 (fallthrough)
> branch 3 taken 0
> branch 4 taken 0 (fallthrough)
> branch 5 taken 5
>
> On the other hand, Clang's Source-based Code Coverage instruments at the
> compiler frontend which maintains an accurate mapping from coverage
> measurement to source code location. Coverage reports reflect exactly how
> the code is written regardless of optimization and can present advanced
> metrics like branch coverage and MC/DC in a clearer way. Coverage report
> for the same snippet by llvm-cov would look as follows:
>
> 1068| 5| if (s == e || *e != '/' || !month || month > 12) {
> ------------------
> | Branch (1068:6): [True: 0, False: 5]
> | Branch (1068:16): [True: 0, False: 5]
> | Branch (1068:29): [True: 0, False: 5]
> | Branch (1068:39): [True: 0, False: 5]
> ------------------

..Ch:W..

[1] https://lore.kernel.org/llvm/20240905043245.1389509-1-wentaoz5@illinois.edu/