mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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,



  parent reply	other threads:[~2026-11-02 11:40 UTC|newest]

Thread overview: 8+ 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 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®