[PATCH] kcov: Use WRITE_ONCE() for selftest mode stores

From: Karl Mehltretter

Date: Tue May 26 2026 - 07:50:08 EST


The KCOV selftest enables coverage by setting current->kcov_mode to
KCOV_MODE_TRACE_PC without installing a coverage area. If an interrupt
records coverage in that window, the access should fault and expose the
bug.

When building for QEMU raspi0 (Raspberry Pi Zero, ARMv6,
CONFIG_CPU_V6K=y, CONFIG_CURRENT_POINTER_IN_TPIDRURO=y) with GCC
13.3.0, the store that enables the mode is removed. The generated
kcov_init() code only stores zero after the wait loop:

mrc 15, 0, r3, cr13, cr0, {3}
str r4, [r3, #2028]

where r4 is zero. There is no store of KCOV_MODE_TRACE_PC before the
loop, so the selftest reports success without exercising coverage.

Use WRITE_ONCE() for the temporary mode stores. With the same compiler
and config, kcov_init() contains the intended mode store:

mov r3, #2
mrc 15, 0, r2, cr13, cr0, {3}
str r3, [r2, #2028]

Now that the KCOV selftest is actually executed, it may expose KCOV
instrumentation issues depending on the kernel config. That is expected
for a selftest that was intended to catch coverage from interrupt paths.

Fixes: 6cd0dd934b03 ("kcov: Add interrupt handling self test")
Assisted-by: Codex:gpt-5
Signed-off-by: Karl Mehltretter <kmehltretter@xxxxxxxxx>
---
Reviewer note:
This is related to my pending trace_irqsoff.o KCOV report. Once the KCOV
selftest actually enables coverage, that trace_irqsoff.o KCOV issue can
become visible depending on the kernel config. That issue is separate from
this patch; this patch only fixes the selftest false negative.

https://lore.kernel.org/r/20260525170428.67211-1-kmehltretter@xxxxxxxxx

kernel/kcov.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/kcov.c b/kernel/kcov.c
index 0b369e88c7c9..f3a5ae960ce5 100644
--- a/kernel/kcov.c
+++ b/kernel/kcov.c
@@ -1109,10 +1109,10 @@ static void __init selftest(void)
* potentially traced functions in this region.
*/
start = jiffies;
- current->kcov_mode = KCOV_MODE_TRACE_PC;
+ WRITE_ONCE(current->kcov_mode, KCOV_MODE_TRACE_PC);
while ((jiffies - start) * MSEC_PER_SEC / HZ < 300)
;
- current->kcov_mode = 0;
+ WRITE_ONCE(current->kcov_mode, 0);
pr_err("done running self test\n");
}
#endif

base-commit: e8c2f9fdadee7cbc75134dc463c1e0d856d6e5c7
--
2.39.5 (Apple Git-154)