From: Karl Mehltretter <kmehltretter@gmail.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Karl Mehltretter <kmehltretter@gmail.com>,
Andrey Konovalov <andreyknvl@gmail.com>,
Alexander Potapenko <glider@google.com>,
Dmitry Vyukov <dvyukov@google.com>,
Marco Elver <elver@google.com>,
Bradley Morgan <include@grrlz.net>,
Anna-Maria Behnsen <anna-maria@linutronix.de>,
Frederic Weisbecker <frederic@kernel.org>,
Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
Peter Zijlstra <peterz@infradead.org>,
Juri Lelli <juri.lelli@redhat.com>,
Vincent Guittot <vincent.guittot@linaro.org>,
Dietmar Eggemann <dietmar.eggemann@arm.com>,
Steven Rostedt <rostedt@goodmis.org>,
Ben Segall <bsegall@google.com>, Mel Gorman <mgorman@suse.de>,
Valentin Schneider <vschneid@redhat.com>,
K Prateek Nayak <kprateek.nayak@amd.com>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
Clark Williams <clrkwllms@kernel.org>,
linux-rt-devel@lists.linux.dev, kasan-dev@googlegroups.com,
linux-kernel@vger.kernel.org
Subject: [PATCH v2 2/6] kcov: Add a kcov_pause guard
Date: Tue, 11 Aug 2026 17:41:07 +0200 [thread overview]
Message-ID: <20260811154111.64669-3-kmehltretter@gmail.com> (raw)
In-Reply-To: <20260811154111.64669-1-kmehltretter@gmail.com>
Interrupt-return work can run after HARDIRQ_OFFSET is dropped, when
in_task() is true. KCOV then attributes instrumented callees to the
interrupted task.
Add a KCOV_PAUSED bit next to KCOV_IN_CTXSW and mask both in
kcov_mode_enabled(). The coverage callbacks need no new check because
check_kcov_mode()'s exact comparison rejects modes with KCOV_PAUSED set.
The context switch suppression keeps its own bit: kcov_prepare_switch()
runs on the previous task and kcov_finish_switch() on the one switched
in, so its lifetime is not a pause section.
Provide a kcov_pause guard backed by internal helpers that operate on
current. The guard saves the previous pause state and restores it at
scope exit, so sections nest. When KCOV is enabled for current, remote
softirq sections save and restore the complete mode, preserving the pause
state.
The helpers are __always_inline, and guard users must be uninstrumented:
inlining does not remove the caller's own coverage callbacks.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
Notes:
v2:
- add guard(kcov_pause)() backed by private current-only helpers
include/linux/kcov.h | 40 +++++++++++++++++++++++++++++++++++++++-
kernel/kcov.c | 2 +-
2 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/include/linux/kcov.h b/include/linux/kcov.h
index 895b761b2db15..1b4806dab62fb 100644
--- a/include/linux/kcov.h
+++ b/include/linux/kcov.h
@@ -2,6 +2,8 @@
#ifndef _LINUX_KCOV_H
#define _LINUX_KCOV_H
+#include <linux/bits.h>
+#include <linux/cleanup.h>
#include <linux/sched.h>
#include <uapi/linux/kcov.h>
@@ -23,7 +25,8 @@ enum kcov_mode {
KCOV_MODE_TRACE_CMP = 3,
};
-#define KCOV_IN_CTXSW (1 << 30)
+#define KCOV_IN_CTXSW BIT(30)
+#define KCOV_PAUSED BIT(29)
void kcov_task_init(struct task_struct *t);
void kcov_task_exit(struct task_struct *t);
@@ -38,6 +41,25 @@ do { \
(t)->kcov_mode &= ~KCOV_IN_CTXSW; \
} while (0)
+/*
+ * Pause coverage for current. Callers must be uninstrumented.
+ * Pass the returned state to __kcov_resume().
+ */
+static __always_inline unsigned int __kcov_pause(void)
+{
+ unsigned int paused;
+
+ paused = current->kcov_mode & KCOV_PAUSED;
+ current->kcov_mode |= KCOV_PAUSED;
+ return paused;
+}
+
+static __always_inline void __kcov_resume(unsigned int paused)
+{
+ if (!paused)
+ current->kcov_mode &= ~KCOV_PAUSED;
+}
+
/* See Documentation/dev-tools/kcov.rst for usage details. */
void kcov_remote_start(u64 handle);
void kcov_remote_stop(void);
@@ -93,6 +115,8 @@ void __sanitizer_cov_trace_switch(kcov_u64 val, void *cases);
static inline void kcov_task_init(struct task_struct *t) {}
static inline void kcov_task_exit(struct task_struct *t) {}
+static inline unsigned int __kcov_pause(void) { return 0; }
+static inline void __kcov_resume(unsigned int paused) {}
static inline void kcov_prepare_switch(struct task_struct *t) {}
static inline void kcov_finish_switch(struct task_struct *t) {}
static inline void kcov_remote_start(u64 handle) {}
@@ -107,4 +131,18 @@ static inline void kcov_remote_start_usb_softirq(u64 id) {}
static inline void kcov_remote_stop_softirq(void) {}
#endif /* CONFIG_KCOV */
+
+/*
+ * Scope-based KCOV pause:
+ *
+ * guard(kcov_pause)();
+ *
+ * pauses coverage for current until the end of the scope. Callers must be
+ * uninstrumented.
+ */
+DEFINE_LOCK_GUARD_0(kcov_pause,
+ _T->paused = __kcov_pause(),
+ __kcov_resume(_T->paused),
+ unsigned int paused)
+
#endif /* _LINUX_KCOV_H */
diff --git a/kernel/kcov.c b/kernel/kcov.c
index b5340369e6fe3..a5c43764f21ac 100644
--- a/kernel/kcov.c
+++ b/kernel/kcov.c
@@ -830,7 +830,7 @@ static const struct file_operations kcov_fops = {
static inline bool kcov_mode_enabled(unsigned int mode)
{
- return (mode & ~KCOV_IN_CTXSW) != KCOV_MODE_DISABLED;
+ return (mode & ~(KCOV_IN_CTXSW | KCOV_PAUSED)) != KCOV_MODE_DISABLED;
}
static void kcov_remote_softirq_start(struct task_struct *t)
--
2.53.0
next prev parent reply other threads:[~2026-08-11 15:41 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-11 15:41 [PATCH v2 0/6] kcov: Suppress timer and scheduler coverage leaks Karl Mehltretter
2026-08-11 15:41 ` [PATCH v2 1/6] kcov: Use unsigned int for kcov_start() mode parameter Karl Mehltretter
2026-08-11 15:41 ` Karl Mehltretter [this message]
2026-08-11 15:41 ` [PATCH v2 3/6] hrtimer: Pause KCOV during deferred rearm Karl Mehltretter
2026-08-12 10:21 ` Peter Zijlstra
2026-08-11 15:41 ` [PATCH v2 4/6] sched/core: Pause KCOV in __schedule() Karl Mehltretter
2026-08-12 10:35 ` Peter Zijlstra
2026-08-11 15:41 ` [PATCH v2 5/6] sched/core: Pause KCOV in try_to_wake_up() Karl Mehltretter
2026-08-12 10:35 ` Peter Zijlstra
2026-08-11 15:41 ` [PATCH v2 6/6] sched/core: Pause KCOV in wake_up_new_task() Karl Mehltretter
2026-08-12 10:36 ` Peter Zijlstra
2026-08-11 19:59 ` [PATCH v2 0/6] kcov: Suppress timer and scheduler coverage leaks Bradley Morgan
2026-08-12 10:36 ` Peter Zijlstra
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=20260811154111.64669-3-kmehltretter@gmail.com \
--to=kmehltretter@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=andreyknvl@gmail.com \
--cc=anna-maria@linutronix.de \
--cc=bigeasy@linutronix.de \
--cc=bsegall@google.com \
--cc=clrkwllms@kernel.org \
--cc=dietmar.eggemann@arm.com \
--cc=dvyukov@google.com \
--cc=elver@google.com \
--cc=frederic@kernel.org \
--cc=glider@google.com \
--cc=include@grrlz.net \
--cc=juri.lelli@redhat.com \
--cc=kasan-dev@googlegroups.com \
--cc=kprateek.nayak@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=tglx@kernel.org \
--cc=vincent.guittot@linaro.org \
--cc=vschneid@redhat.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.