From: Peter Zijlstra <peterz@infradead.org>
To: x86@kernel.org
Cc: linux-kernel@vger.kernel.org, peterz@infradead.org,
jpoimboe@kernel.org, leitao@debian.org, keescook@chromium.org,
hpa@zytor.com, kernel test robot <lkp@intel.com>
Subject: [PATCH 2/6] objtool: Add instrumentation_weak()
Date: Mon, 02 Nov 2026 12:25:51 +0100 [thread overview]
Message-ID: <20261102114000.552033727@infradead.org> (raw)
In-Reply-To: 20261102112549.714541309@infradead.org
The strict pairing of instrumentation_begin()/instrumentation_end() gets in the
way of tail-call optimizations, since it requires writing code like:
int bar(void);
noinstr int foo(void)
{
int ret;
instrumentation_begin();
ret = bar();
instrumentation_end();
return ret;
}
Introduce instrumentation_weak(), which is like instrumentation_begin() but
does not nest and does not pair. This way one can write:
noinstr int foo(void)
{
instrumentation_weak();
return bar();
}
And get tail-calls without objtool getting upset.
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
include/linux/annotate.h | 1 +
include/linux/instrumentation.h | 17 +++++++++++++++++
include/linux/objtool_types.h | 1 +
tools/include/linux/objtool_types.h | 1 +
tools/objtool/check.c | 17 ++++++++++++-----
5 files changed, 32 insertions(+), 5 deletions(-)
--- a/include/linux/annotate.h
+++ b/include/linux/annotate.h
@@ -71,6 +71,7 @@
*/
#define ANNOTATE_INSTR_BEGIN(label) ASM_ANNOTATE_LABEL(label, ANNOTYPE_INSTR_BEGIN)
#define ANNOTATE_INSTR_END(label) ASM_ANNOTATE_LABEL(label, ANNOTYPE_INSTR_END)
+#define ANNOTATE_INSTR_WEAK(label) ASM_ANNOTATE_LABEL(label, ANNOTYPE_INSTR_WEAK)
/*
* objtool annotation to ignore the alternatives and only consider the original
* instruction(s).
--- a/include/linux/instrumentation.h
+++ b/include/linux/instrumentation.h
@@ -52,9 +52,26 @@
: : "i" (c)); \
})
#define instrumentation_end() __instrumentation_end(__COUNTER__)
+
+/*
+ * A very much weaker variant of instrumentation_begin(). It does not nest and
+ * it does not pair with instrumentation_end().
+ *
+ * Its purpose is to allow calling instrumented code while preserving
+ * tail-call optimization, something which is otherwise impossible with the
+ * need to call instrumentation_end().
+ */
+#define __instrumentation_weak(c) ({ \
+ asm volatile(__stringify(c) ": nop\n\t" \
+ ANNOTATE_INSTR_WEAK(__ASM_BREF(c)) \
+ : : "i" (c)); \
+})
+#define instrumentation_weak() __instrumentation_weak(__COUNTER__)
+
#else /* !CONFIG_NOINSTR_VALIDATION */
# define instrumentation_begin() do { } while(0)
# define instrumentation_end() do { } while(0)
+# define instrumentation_weak() do { } while(0)
#endif /* CONFIG_NOINSTR_VALIDATION */
#endif /* __LINUX_INSTRUMENTATION_H */
--- a/include/linux/objtool_types.h
+++ b/include/linux/objtool_types.h
@@ -66,6 +66,7 @@ struct unwind_hint {
#define ANNOTYPE_INTRA_FUNCTION_CALL 7
#define ANNOTYPE_REACHABLE 8
#define ANNOTYPE_NOCFI 9
+#define ANNOTYPE_INSTR_WEAK 10
#define ANNOTYPE_DATA_SPECIAL 1
--- a/tools/include/linux/objtool_types.h
+++ b/tools/include/linux/objtool_types.h
@@ -66,6 +66,7 @@ struct unwind_hint {
#define ANNOTYPE_INTRA_FUNCTION_CALL 7
#define ANNOTYPE_REACHABLE 8
#define ANNOTYPE_NOCFI 9
+#define ANNOTYPE_INSTR_WEAK 10
#define ANNOTYPE_DATA_SPECIAL 1
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2435,11 +2435,15 @@ static int __annotate_late(struct objtoo
break;
case ANNOTYPE_INSTR_BEGIN:
- insn->instr++;
+ insn->instr += 2;
break;
case ANNOTYPE_INSTR_END:
- insn->instr--;
+ insn->instr -= 2;
+ break;
+
+ case ANNOTYPE_INSTR_WEAK:
+ insn->instr += 1;
break;
case ANNOTYPE_UNRET_BEGIN:
@@ -3535,6 +3539,11 @@ static int validate_sibling_call(struct
struct instruction *insn,
struct insn_state *state)
{
+ if (state->noinstr && state->instr > 1) {
+ WARN_INSN(insn, "sibling call with instrumentation enabled");
+ return 1;
+ }
+
if (insn_func(insn) && has_modified_stack_frame(insn, state)) {
WARN_INSN(insn, "sibling call from callable instruction with modified stack frame");
return 1;
@@ -3545,7 +3554,7 @@ static int validate_sibling_call(struct
static int validate_return(struct symbol *func, struct instruction *insn, struct insn_state *state)
{
- if (state->noinstr && state->instr > 0) {
+ if (state->noinstr && state->instr > 1) {
WARN_INSN(insn, "return with instrumentation enabled");
return 1;
}
@@ -3646,8 +3655,6 @@ static bool skip_alt_group(struct instru
static int validate_branch(struct objtool_file *file, struct symbol *func,
struct instruction *insn, struct insn_state state);
-static int do_validate_branch(struct objtool_file *file, struct symbol *func,
- struct instruction *insn, struct insn_state *state);
static int validate_insn(struct objtool_file *file, struct symbol *func,
struct instruction *insn, struct insn_state *statep,
next prev parent reply other threads:[~2026-11-02 11:40 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-02 11:25 [PATCH 0/6] x86: Harden syscall dispatch Peter Zijlstra
2026-11-02 11:25 ` [PATCH 1/6] x86_64/entry: Unconditionally use -fno-jump-table Peter Zijlstra
2026-11-02 14:28 ` Breno Leitao
2026-11-02 11:25 ` Peter Zijlstra [this message]
2026-11-02 11:25 ` [PATCH 3/6] x86_64/entry: Make syscall dispatch noinstr Peter Zijlstra
2026-11-02 11:25 ` [PATCH 4/6] x86_64/entry: Mark all syscalls __noendbr Peter Zijlstra
2026-11-02 17:06 ` David Laight
2026-11-03 8:51 ` Peter Zijlstra
2026-11-03 21:54 ` David Laight
2026-11-02 11:25 ` [PATCH 5/6] objtool: Allow EXPORT_SYMBOL() of __noendbr functions Peter Zijlstra
2026-11-02 11:25 ` [PATCH 6/6] x86_64/entry: Mark C noinstr __noendbr 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=20261102114000.552033727@infradead.org \
--to=peterz@infradead.org \
--cc=hpa@zytor.com \
--cc=jpoimboe@kernel.org \
--cc=keescook@chromium.org \
--cc=leitao@debian.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lkp@intel.com \
--cc=x86@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.