All of lore.kernel.org
 help / color / mirror / Atom feed
From: Karl Mehltretter <kmehltretter@gmail.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Karl Mehltretter <kmehltretter@gmail.com>,
	Andrey Konovalov <andreyknvl@gmail.com>,
	Dmitry Vyukov <dvyukov@google.com>,
	Alexander Potapenko <glider@google.com>,
	Marco Elver <elver@google.com>,
	Bradley Morgan <include@grrlz.net>,
	kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org
Subject: [PATCH 1/5] kcov: add kcov_pause()/kcov_resume() helpers
Date: Fri,  7 Aug 2026 22:50:23 +0200	[thread overview]
Message-ID: <20260807205027.31972-2-kmehltretter@gmail.com> (raw)
In-Reply-To: <20260807205027.31972-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 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.

Sections nest by passing the state returned by kcov_pause() to
kcov_resume(). Both operate on current. When task KCOV is active, remote
softirq sections save and restore the complete mode, preserving the
pause state.

The helpers are __always_inline, and the caller must be uninstrumented:
inlining does not remove the caller's own coverage callbacks.

Assisted-by: Claude:claude-opus-4-8
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
 include/linux/kcov.h | 25 ++++++++++++++++++++++++-
 kernel/kcov.c        |  2 +-
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/include/linux/kcov.h b/include/linux/kcov.h
index 895b761b2db1..5a0a1a9bb7ef 100644
--- a/include/linux/kcov.h
+++ b/include/linux/kcov.h
@@ -2,6 +2,7 @@
 #ifndef _LINUX_KCOV_H
 #define _LINUX_KCOV_H
 
+#include <linux/bits.h>
 #include <linux/sched.h>
 #include <uapi/linux/kcov.h>
 
@@ -23,7 +24,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 +40,25 @@ do {						\
 	(t)->kcov_mode &= ~KCOV_IN_CTXSW;	\
 } while (0)
 
+/*
+ * Pause coverage for current. Pass the returned state to kcov_resume().
+ * Callers must be uninstrumented.
+ */
+static __always_inline unsigned int kcov_pause(struct task_struct *t)
+{
+	unsigned int paused;
+
+	paused = t->kcov_mode & KCOV_PAUSED;
+	t->kcov_mode |= KCOV_PAUSED;
+	return paused;
+}
+
+static __always_inline void kcov_resume(struct task_struct *t, unsigned int paused)
+{
+	if (!paused)
+		t->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 +114,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(struct task_struct *t) { return 0; }
+static inline void kcov_resume(struct task_struct *t, 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) {}
diff --git a/kernel/kcov.c b/kernel/kcov.c
index 1df373fb562b..83d53e383822 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

  reply	other threads:[~2026-08-07 20:50 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-07 20:50 [PATCH 0/5] kcov: suppress timer and scheduler coverage leaks Karl Mehltretter
2026-08-07 20:50 ` Karl Mehltretter [this message]
2026-08-08  1:16   ` [PATCH 1/5] kcov: add kcov_pause()/kcov_resume() helpers Bradley Morgan
2026-08-07 20:50 ` [PATCH 2/5] hrtimer: pause KCOV during deferred rearm Karl Mehltretter
2026-08-08  1:19   ` Bradley Morgan
2026-08-07 20:50 ` [PATCH 3/5] sched: pause KCOV in __schedule() Karl Mehltretter
2026-08-08  1:21   ` Bradley Morgan
2026-08-07 20:50 ` [PATCH 4/5] sched: pause KCOV in try_to_wake_up() Karl Mehltretter
2026-08-07 21:00   ` sashiko-bot
2026-08-08  1:28   ` Bradley Morgan
2026-08-07 20:50 ` [PATCH 5/5] sched: pause KCOV in wake_up_new_task() Karl Mehltretter
2026-08-08  1:36   ` Bradley Morgan
2026-08-10 21:57     ` Karl Mehltretter
2026-08-08  8:44 ` [PATCH 0/5] kcov: suppress timer and scheduler coverage leaks 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=20260807205027.31972-2-kmehltretter@gmail.com \
    --to=kmehltretter@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=andreyknvl@gmail.com \
    --cc=dvyukov@google.com \
    --cc=elver@google.com \
    --cc=glider@google.com \
    --cc=include@grrlz.net \
    --cc=kasan-dev@googlegroups.com \
    --cc=linux-kernel@vger.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 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.