Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] arm64: irq: exclude the softirq stack switch from KCOV
@ 2026-09-26 19:13 Karl Mehltretter
  2026-10-08 15:19 ` Will Deacon
  0 siblings, 1 reply; 2+ messages in thread
From: Karl Mehltretter @ 2026-09-26 19:13 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: Karl Mehltretter, Mark Rutland, Qi Zheng, Arnd Bergmann,
	Andrey Konovalov, Alexander Potapenko, Dmitry Vyukov, kasan-dev,
	linux-arm-kernel, linux-kernel

On IRQ exit, __irq_exit_rcu() drops HARDIRQ_OFFSET before calling
invoke_softirq(). The arm64 do_softirq_own_stack() wrapper and its
____do_softirq() trampoline run before __do_softirq() establishes
softirq context, so KCOV records their PCs in the interrupted task's
coverage buffer. They also run outside softirq accounting when
local_bh_enable() reaches do_softirq().

The IRQ-exit coverage makes the KCOV boot selftest fail even after
the scheduler and timer coverage leaks are suppressed. The generic
softirq.o is already excluded from KCOV, but that exclusion does not
cover the separately compiled arm64 wrappers.

Exclude irq.o from KCOV instrumentation, as is already done for the
arm64 entry code. This covers both wrappers even with compilers that
lack the no_sanitize_coverage attribute. The softirq action functions
remain instrumented for explicit remote coverage.

Fixes: 8eb858c44b98 ("arm64: run softirqs on the per-CPU IRQ stack")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
This patch applies without my other pending KCOV or softirq patches.
For testing, the pause series [1] suppresses the other known
timer/scheduler leaks, and the selftest diagnostic [2] reports the
remaining PCs.

Tested on mainline 40288c9206c17 with both prerequisites applied:
- GCC 15.2 arm64 builds, KCOV_INSTRUMENT_ALL and KCOV_SELFTEST enabled.
- QEMU virt/cortex-a76: baseline reports 15 PCs alternating between
  the two wrappers and panics. The fix passes three boots with KASLR
  and three with nokaslr. All KASLR boots have nonzero relocation.
- Raspberry Pi 500, BCM2712 D0: baseline records seven PCs from each
  wrapper. The fixed kernel completes the strict selftest with zero
  PCs. The baseline alone replaces the final panic with a diagnostic
  and return so SSH can retrieve its log. Recording is unchanged.
- Clang 21 W=1 object builds: irq.o has no KCOV callbacks after the
  change, while syscall.o retains its instrumentation.
- Fixed QEMU image: positive PC and comparison coverage remains live
  for getpid() and close(-1), with neither buffer saturated.

My softirq IRQ-exit v3 patch [3] makes the boot selftest pass in QEMU
and on the Pi without this patch. It does not cover the task-context
path through local_bh_enable(). A five-send loopback UDP test shows:

                                    v3    v3 + this patch
  Wrapper PC entries (five sends)  10    0
  Sends covering udp_sendmsg()     5/5   5/5

A bounded syzkaller replay compared my softirq v4 patch [4] alone
against v4 plus this patch. It used 18 reviewed programs with 40
executions per program and variant across four fresh boots in A-B-B-A
order. A is v4 alone; B adds this patch:

                                    v4          v4 + this patch
  Program executions               720         720
  Wrapper PC entries (40 sends)    80          0
  Stable non-wrapper locations     7,172       7,172
  Executions to reach 99%          17          17
  Greedy fixed corpus              16/4,068 B  16/4,068 B
  Executor time                    3.932 s     3.956 s

This fixed replay measures coverage cleanup, not syz-manager discovery
or corpus growth.

A longer replay used the same A-B-B-A order and ran the workload for
30 minutes per variant. Excluding a 30-second warmup from each 15-minute
session left 29 measured minutes per variant:

                                    v4          v4 + this patch
  Program executions               119,883     119,868
  Programs/s                       68.898      68.890
  Mean executor time/program       5.256 ms    5.285 ms
  90%-stable non-wrapper locations 6,959       6,953
  Wrapper PC entries (40 sends)    80          0
  KCOV overflows                   0           0

The 80 entries are 40 instances of each wrapper PC. The variants shared
6,952 stable non-wrapper locations; the six unmatched locations were
route-lookup PCs. The timing differences were not material.

Apply checks pass on v6.1, v6.6, v6.12 and v6.18; those older kernels
have not been built or boot-tested here.

[1] https://lore.kernel.org/all/20260914054632.12877-1-kmehltretter@gmail.com/
[2] https://lore.kernel.org/all/20260919080220.37633-1-kmehltretter@gmail.com/
[3] https://lore.kernel.org/all/20260924041538.52574-1-kmehltretter@gmail.com/
[4] https://lore.kernel.org/r/20260926143505.66024-1-kmehltretter@gmail.com/

 arch/arm64/kernel/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index d2690c3ec5288..ea66339435bf0 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -25,6 +25,9 @@ KASAN_SANITIZE_stacktrace.o := n
 KCOV_INSTRUMENT_entry-common.o := n
 KCOV_INSTRUMENT_idle.o := n
 
+# Softirq stack switching can run outside interrupt context.
+KCOV_INSTRUMENT_irq.o := n
+
 # Object file lists.
 obj-y			:= debug-monitors.o entry.o irq.o fpsimd.o		\
 			   entry-common.o process.o ptrace.o			\
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] arm64: irq: exclude the softirq stack switch from KCOV
  2026-09-26 19:13 [PATCH] arm64: irq: exclude the softirq stack switch from KCOV Karl Mehltretter
@ 2026-10-08 15:19 ` Will Deacon
  0 siblings, 0 replies; 2+ messages in thread
From: Will Deacon @ 2026-10-08 15:19 UTC (permalink / raw)
  To: Catalin Marinas, Karl Mehltretter
  Cc: mark.rutland, kernel-team, Will Deacon, Qi Zheng, Arnd Bergmann,
	Andrey Konovalov, Alexander Potapenko, Dmitry Vyukov, kasan-dev,
	linux-arm-kernel, linux-kernel

On Sat, 26 Sep 2026 21:13:25 +0200, Karl Mehltretter wrote:
> On IRQ exit, __irq_exit_rcu() drops HARDIRQ_OFFSET before calling
> invoke_softirq(). The arm64 do_softirq_own_stack() wrapper and its
> ____do_softirq() trampoline run before __do_softirq() establishes
> softirq context, so KCOV records their PCs in the interrupted task's
> coverage buffer. They also run outside softirq accounting when
> local_bh_enable() reaches do_softirq().
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: irq: exclude the softirq stack switch from KCOV
      https://git.kernel.org/arm64/c/a9cd14bfb0c1

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-08 15:19 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-26 19:13 [PATCH] arm64: irq: exclude the softirq stack switch from KCOV Karl Mehltretter
2026-10-08 15:19 ` Will Deacon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox