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

Karl Mehltretter posted 1 patch 1 week, 6 days ago
kernel/kcov.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
[PATCH] kcov: Use WRITE_ONCE() for selftest mode stores
Posted by Karl Mehltretter 1 week, 6 days ago
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@gmail.com>
---
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@gmail.com

 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)
Re: [PATCH] kcov: Use WRITE_ONCE() for selftest mode stores
Posted by Alexander Potapenko 1 week, 4 days ago
On Tue, May 26, 2026 at 1:47 PM Karl Mehltretter <kmehltretter@gmail.com> wrote:
>
> 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@gmail.com>
Reviewed-by: Alexander Potapenko <glider@google.com>