From: Sasha Levin <sashal@kernel.org>
To: nathan@kernel.org
Cc: Matt.Kelly2@boeing.com, akpm@linux-foundation.org,
andrew.j.oppelt@boeing.com, anton.ivanov@cambridgegreys.com,
ardb@kernel.org, arnd@arndb.de, bhelgaas@google.com,
bp@alien8.de, chuck.wolber@boeing.com,
dave.hansen@linux.intel.com, dvyukov@google.com, hpa@zytor.com,
jinghao7@illinois.edu, johannes@sipsolutions.net,
jpoimboe@kernel.org, justinstitt@google.com, kees@kernel.org,
kent.overstreet@linux.dev, linux-arch@vger.kernel.org,
linux-efi@vger.kernel.org, linux-kbuild@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
linux-um@lists.infradead.org, llvm@lists.linux.dev,
luto@kernel.org, marinov@illinois.edu, masahiroy@kernel.org,
maskray@google.com, mathieu.desnoyers@efficios.com,
matthew.l.weber3@boeing.com, mhiramat@kernel.org,
mingo@redhat.com, morbo@google.com, ndesaulniers@google.com,
oberpar@linux.ibm.com, paulmck@kernel.org, peterz@infradead.org,
richard@nod.at, rostedt@goodmis.org, samitolvanen@google.com,
samuel.sarkisian@boeing.com, sashal@kernel.org,
steven.h.vanderleest@boeing.com, tglx@linutronix.de,
tingxur@illinois.edu, tyxu@illinois.edu, wentaoz5@illinois.edu,
x86@kernel.org
Subject: [RFC PATCH 2/4] llvm-cov: add Clang's MC/DC support
Date: Tue, 14 Oct 2025 19:26:37 -0400 [thread overview]
Message-ID: <20251014232639.673260-3-sashal@kernel.org> (raw)
In-Reply-To: <20251014232639.673260-1-sashal@kernel.org>
From: Wentao Zhang <wentaoz5@illinois.edu>
Add infrastructure to enable Clang's Modified Condition/Decision Coverage
(MC/DC) [1].
Clang has added MC/DC support as of its 18.1.0 release. MC/DC is a fine-
grained coverage metric required by many automotive and aviation industrial
standards for certifying mission-critical software [2].
In the following example from arch/x86/events/probe.c, llvm-cov gives the
MC/DC measurement for the compound logic decision at line 43.
43| 12| if (msr[bit].test && !msr[bit].test(bit, data))
------------------
|---> MC/DC Decision Region (43:8) to (43:50)
|
| Number of Conditions: 2
| Condition C1 --> (43:8)
| Condition C2 --> (43:25)
|
| Executed MC/DC Test Vectors:
|
| C1, C2 Result
| 1 { T, F = F }
| 2 { T, T = T }
|
| C1-Pair: not covered
| C2-Pair: covered: (1,2)
| MC/DC Coverage for Decision: 50.00%
|
------------------
44| 5| continue;
As the results suggest, during the span of measurement, only condition C2
(!msr[bit].test(bit, data)) is covered. That means C2 was evaluated to both
true and false, and in those test vectors C2 affected the decision outcome
independently. Therefore MC/DC for this decision is 1 out of 2 (50.00%).
As of Clang 19, users can determine the max number of conditions in a
decision to measure via option LLVM_COV_KERNEL_MCDC_MAX_CONDITIONS, which
controls -fmcdc-max-conditions flag of Clang cc1 [3]. Since MC/DC
implementation utilizes bitmaps to track the execution of test vectors,
more memory is consumed if larger decisions are getting counted. The
maximum value supported by Clang is 32767. According to local experiments,
the working maximum for Linux kernel is 46, with the largest decisions in
kernel codebase (with 47 conditions, as of v6.11) excluded, otherwise the
kernel image size limit will be exceeded. The largest decisions in kernel
are contributed for example by macros checking CPUID.
Code exceeding LLVM_COV_KERNEL_MCDC_MAX_CONDITIONS will produce compiler
warnings.
As of LLVM 19, certain expressions are still not covered, and will produce
build warnings when they are encountered:
"[...] if a boolean expression is embedded in the nest of another boolean
expression but separated by a non-logical operator, this is also not
supported. For example, in x = (a && b && c && func(d && f)), the d && f
case starts a new boolean expression that is separated from the other
conditions by the operator func(). When this is encountered, a warning
will be generated and the boolean expression will not be
instrumented." [4]
Link: https://en.wikipedia.org/wiki/Modified_condition%2Fdecision_coverage [1]
Link: https://digital-library.theiet.org/content/journals/10.1049/sej.1994.0025 [2]
Link: https://discourse.llvm.org/t/rfc-coverage-new-algorithm-and-file-format-for-mc-dc/76798 [3]
Link: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#mc-dc-instrumentation [4]
Signed-off-by: Wentao Zhang <wentaoz5@illinois.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Makefile | 6 ++++++
kernel/llvm-cov/Kconfig | 36 ++++++++++++++++++++++++++++++++++++
scripts/Makefile.lib | 12 ++++++++++++
3 files changed, 54 insertions(+)
diff --git a/Makefile b/Makefile
index 621a27ed148bb..3cfa49280d504 100644
--- a/Makefile
+++ b/Makefile
@@ -802,6 +802,12 @@ all: vmlinux
CFLAGS_LLVM_COV := -fprofile-instr-generate -fcoverage-mapping
export CFLAGS_LLVM_COV
+CFLAGS_LLVM_COV_MCDC := -fcoverage-mcdc
+ifdef CONFIG_LLVM_COV_KERNEL_MCDC_MAX_CONDITIONS
+CFLAGS_LLVM_COV_MCDC += -Xclang -fmcdc-max-conditions=$(CONFIG_LLVM_COV_KERNEL_MCDC_MAX_CONDITIONS)
+endif
+export CFLAGS_LLVM_COV_MCDC
+
CFLAGS_GCOV := -fprofile-arcs -ftest-coverage
ifdef CONFIG_CC_IS_GCC
CFLAGS_GCOV += -fno-tree-loop-im
diff --git a/kernel/llvm-cov/Kconfig b/kernel/llvm-cov/Kconfig
index 45ae5a579743d..d7b7272a2e75c 100644
--- a/kernel/llvm-cov/Kconfig
+++ b/kernel/llvm-cov/Kconfig
@@ -82,4 +82,40 @@ config LLVM_COV_PROFILE_ALL
Note that a kernel compiled with profiling flags will be significantly
larger and run slower.
+config LLVM_COV_KERNEL_MCDC
+ bool "Enable measuring modified condition/decision coverage (MC/DC)"
+ depends on LLVM_COV_KERNEL
+ depends on CLANG_VERSION >= 180000
+ help
+ This option enables modified condition/decision coverage (MC/DC)
+ code coverage instrumentation.
+
+ If unsure, say N.
+
+ This will add Clang's Source-based Code Coverage MC/DC
+ instrumentation to your kernel. As of LLVM 19, certain expressions
+ are still not covered, and will produce build warnings when they are
+ encountered.
+
+ "[...] if a boolean expression is embedded in the nest of another
+ boolean expression but separated by a non-logical operator, this is
+ also not supported. For example, in
+ x = (a && b && c && func(d && f)), the d && f case starts a new
+ boolean expression that is separated from the other conditions by the
+ operator func(). When this is encountered, a warning will be
+ generated and the boolean expression will not be instrumented."
+
+ https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#mc-dc-instrumentation
+
+config LLVM_COV_KERNEL_MCDC_MAX_CONDITIONS
+ int "Maximum number of conditions in a decision to instrument"
+ range 6 32767
+ depends on LLVM_COV_KERNEL_MCDC
+ depends on CLANG_VERSION >= 190000
+ default "6"
+ help
+ This value is passed to "-fmcdc-max-conditions" flag of Clang cc1.
+ Expressions whose number of conditions is greater than this value will
+ produce warnings and will not be instrumented.
+
endmenu
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 66c10893077d4..61fad6dff79cc 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -59,6 +59,18 @@ _c_flags += $(if $(patsubst n%,, \
$(CFLAGS_LLVM_COV))
endif
+#
+# Flag that turns on modified condition/decision coverage (MC/DC) measurement
+# with Clang's Source-based Code Coverage. Enable the flag for a file or
+# directory depending on variables LLVM_COV_PROFILE_obj.o, LLVM_COV_PROFILE and
+# CONFIG_LLVM_COV_PROFILE_ALL.
+#
+ifeq ($(CONFIG_LLVM_COV_KERNEL_MCDC),y)
+_c_flags += $(if $(patsubst n%,, \
+ $(LLVM_COV_PROFILE_$(target-stem).o)$(LLVM_COV_PROFILE)$(if $(is-kernel-object),$(CONFIG_LLVM_COV_PROFILE_ALL))), \
+ $(CFLAGS_LLVM_COV_MCDC))
+endif
+
#
# Enable address sanitizer flags for kernel except some files or directories
# we don't want to check (depends on variables KASAN_SANITIZE_obj.o, KASAN_SANITIZE)
--
2.51.0
next prev parent reply other threads:[~2025-10-14 23:27 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-24 23:06 [RFC PATCH 0/3] Enable measuring the kernel's Source-based Code Coverage and MC/DC with Clang Wentao Zhang
2024-08-24 23:06 ` [RFC PATCH 1/3] llvm-cov: add Clang's Source-based Code Coverage support Wentao Zhang
2024-08-25 11:52 ` Thomas Gleixner
2024-08-24 23:06 ` [RFC PATCH 2/3] kbuild, llvm-cov: disable instrumentation in odd or sensitive code Wentao Zhang
2024-08-25 12:12 ` Thomas Gleixner
2024-08-24 23:06 ` [RFC PATCH 3/3] llvm-cov: add Clang's MC/DC support Wentao Zhang
2024-09-05 4:32 ` [PATCH v2 0/4] Enable measuring the kernel's Source-based Code Coverage and MC/DC with Clang Wentao Zhang
2024-09-05 4:32 ` [PATCH v2 1/4] llvm-cov: add Clang's Source-based Code Coverage support Wentao Zhang
2024-10-02 0:30 ` Nathan Chancellor
2024-09-05 4:32 ` [PATCH v2 2/4] llvm-cov: add Clang's MC/DC support Wentao Zhang
2024-10-02 1:10 ` Nathan Chancellor
2024-10-03 3:14 ` Wentao Zhang
2024-09-05 4:32 ` [PATCH v2 3/4] x86: disable llvm-cov instrumentation Wentao Zhang
2024-10-02 1:17 ` Nathan Chancellor
2024-09-05 4:32 ` [PATCH v2 4/4] x86: enable llvm-cov support Wentao Zhang
2024-10-02 1:18 ` Nathan Chancellor
2024-09-05 11:41 ` [PATCH v2 0/4] Enable measuring the kernel's Source-based Code Coverage and MC/DC with Clang Peter Zijlstra
[not found] ` <BN0P110MB1785427A8771BD53DADB2E4DAB9DA@BN0P110MB1785.NAMP110.PROD.OUTLOOK.COM>
[not found] ` <BN0P110MB1785CA856C1898EEC22ACD7EAB9DA@BN0P110MB1785.NAMP110.PROD.OUTLOOK.COM>
2024-09-05 12:24 ` FW: [EXTERNAL] " Steve VanderLeest
2024-09-05 18:07 ` Wentao Zhang
2024-10-02 4:53 ` Nathan Chancellor
2024-10-02 6:42 ` Wentao Zhang
2024-10-03 23:29 ` Nathan Chancellor
2024-10-09 3:17 ` Wentao Zhang
2024-11-22 5:05 ` Jinghao Jia
2024-11-23 4:39 ` Nathan Chancellor
2025-08-29 18:10 ` Nathan Chancellor
2025-10-14 23:26 ` [RFC PATCH 0/4] Enable Clang's Source-based Code Coverage and MC/DC for x86-64 Sasha Levin
2025-10-14 23:26 ` [RFC PATCH 1/4] llvm-cov: add Clang's Source-based Code Coverage support Sasha Levin
2025-10-14 23:26 ` Sasha Levin [this message]
2025-10-14 23:26 ` [RFC PATCH 3/4] x86: disable llvm-cov instrumentation Sasha Levin
2025-10-14 23:26 ` [RFC PATCH 4/4] x86: enable llvm-cov support Sasha Levin
2025-10-15 7:37 ` [RFC PATCH 0/4] Enable Clang's Source-based Code Coverage and MC/DC for x86-64 Peter Zijlstra
2025-10-15 8:26 ` Chuck Wolber
2025-10-15 9:21 ` Peter Zijlstra
2024-11-22 12:27 ` [PATCH v2 0/4] Enable measuring the kernel's Source-based Code Coverage and MC/DC with Clang Peter Zijlstra
2024-11-22 19:28 ` [EXTERNAL] " Wolber (US), Chuck
2024-11-23 3:09 ` Nathan Chancellor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251014232639.673260-3-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=Matt.Kelly2@boeing.com \
--cc=akpm@linux-foundation.org \
--cc=andrew.j.oppelt@boeing.com \
--cc=anton.ivanov@cambridgegreys.com \
--cc=ardb@kernel.org \
--cc=arnd@arndb.de \
--cc=bhelgaas@google.com \
--cc=bp@alien8.de \
--cc=chuck.wolber@boeing.com \
--cc=dave.hansen@linux.intel.com \
--cc=dvyukov@google.com \
--cc=hpa@zytor.com \
--cc=jinghao7@illinois.edu \
--cc=johannes@sipsolutions.net \
--cc=jpoimboe@kernel.org \
--cc=justinstitt@google.com \
--cc=kees@kernel.org \
--cc=kent.overstreet@linux.dev \
--cc=linux-arch@vger.kernel.org \
--cc=linux-efi@vger.kernel.org \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=linux-um@lists.infradead.org \
--cc=llvm@lists.linux.dev \
--cc=luto@kernel.org \
--cc=marinov@illinois.edu \
--cc=masahiroy@kernel.org \
--cc=maskray@google.com \
--cc=mathieu.desnoyers@efficios.com \
--cc=matthew.l.weber3@boeing.com \
--cc=mhiramat@kernel.org \
--cc=mingo@redhat.com \
--cc=morbo@google.com \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=oberpar@linux.ibm.com \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=richard@nod.at \
--cc=rostedt@goodmis.org \
--cc=samitolvanen@google.com \
--cc=samuel.sarkisian@boeing.com \
--cc=steven.h.vanderleest@boeing.com \
--cc=tglx@linutronix.de \
--cc=tingxur@illinois.edu \
--cc=tyxu@illinois.edu \
--cc=wentaoz5@illinois.edu \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).