public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] objtool: Rewrite annotations
@ 2024-11-22 12:10 Peter Zijlstra
  2024-11-22 12:10 ` [PATCH 1/9] objtool: Generic annotation infrastructure Peter Zijlstra
                   ` (9 more replies)
  0 siblings, 10 replies; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-22 12:10 UTC (permalink / raw)
  To: jpoimboe; +Cc: linux-kernel, peterz

Just the objtool annotation rewrite bits.

Changes since last time:

 - split from the x86 and kvm patches
 - s/ANNOTYPE_INTRA_FUNCTION_CALLS/ANNOTYPE_INTRA_FUNCTION_CALL/g
 - made __ASM_ANNOTATE() take a full label name (no longer appends 'b')
 - added a patch that moves all the annotations to objtool.h
 - some changes to the first patch


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

* [PATCH 1/9] objtool: Generic annotation infrastructure
  2024-11-22 12:10 [PATCH 0/9] objtool: Rewrite annotations Peter Zijlstra
@ 2024-11-22 12:10 ` Peter Zijlstra
  2024-11-24  3:16   ` Nathan Chancellor
  2024-11-22 12:10 ` [PATCH 2/9] objtool: Convert ANNOTATE_NOENDBR to ANNOTATE Peter Zijlstra
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-22 12:10 UTC (permalink / raw)
  To: jpoimboe; +Cc: linux-kernel, peterz

Avoid endless .discard.foo sections for each annotation, create a
single .discard.annotate section that takes an annotation type along
with the instruction.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 include/linux/objtool.h |   18 ++++++++++++++++++
 tools/objtool/check.c   |   45 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

--- a/include/linux/objtool.h
+++ b/include/linux/objtool.h
@@ -57,6 +57,13 @@
 	".long 998b\n\t"						\
 	".popsection\n\t"
 
+#define ASM_ANNOTATE(x)						\
+	"911:\n\t"						\
+	".pushsection .discard.annotate,\"M\",@progbits,8\n\t"	\
+	".long 911b - .\n\t"					\
+	".long " __stringify(x) "\n\t"				\
+	".popsection\n\t"
+
 #else /* __ASSEMBLY__ */
 
 /*
@@ -146,6 +153,14 @@
 	.popsection
 .endm
 
+.macro ANNOTATE type:req
+.Lhere_\@:
+	.pushsection .discard.annotate,"M",@progbits,8
+	.long	.Lhere_\@ - .
+	.long	\type
+	.popsection
+.endm
+
 #endif /* __ASSEMBLY__ */
 
 #else /* !CONFIG_OBJTOOL */
@@ -155,6 +170,7 @@
 #define UNWIND_HINT(type, sp_reg, sp_offset, signal) "\n\t"
 #define STACK_FRAME_NON_STANDARD(func)
 #define STACK_FRAME_NON_STANDARD_FP(func)
+#define ASM_ANNOTATE(x)
 #define ANNOTATE_NOENDBR
 #define ASM_REACHABLE
 #else
@@ -167,6 +183,8 @@
 .endm
 .macro REACHABLE
 .endm
+.macro ANNOTATE type:req
+.endm
 #endif
 
 #endif /* CONFIG_OBJTOOL */
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2373,6 +2373,49 @@ static int read_unwind_hints(struct objt
 	return 0;
 }
 
+static int read_annotate(struct objtool_file *file, void (*func)(int type, struct instruction *insn))
+{
+	struct section *sec;
+	struct instruction *insn;
+	struct reloc *reloc;
+	int type;
+
+	sec = find_section_by_name(file->elf, ".discard.annotate");
+	if (!sec)
+		return 0;
+
+	if (!sec->rsec)
+		return 0;
+
+	if (sec->sh.sh_entsize != 8) {
+		static bool warned = false;
+		if (!warned) {
+			WARN("%s: dodgy linker, sh_entsize != 8", sec->name);
+			warned = true;
+		}
+		sec->sh.sh_entsize = 8;
+	}
+
+	for_each_reloc(sec->rsec, reloc) {
+		type = *(u32 *)(sec->data->d_buf + (reloc_idx(reloc) * sec->sh.sh_entsize) + 4);
+
+		insn = find_insn(file, reloc->sym->sec,
+				 reloc->sym->offset + reloc_addend(reloc));
+		if (!insn) {
+			WARN("bad .discard.annotate entry: %d of type %d", reloc_idx(reloc), type);
+			return -1;
+		}
+
+		func(type, insn);
+	}
+
+	return 0;
+}
+
+static void __annotate_nop(int type, struct instruction *insn)
+{
+}
+
 static int read_noendbr_hints(struct objtool_file *file)
 {
 	struct instruction *insn;
@@ -2670,6 +2713,8 @@ static int decode_sections(struct objtoo
 	if (ret)
 		return ret;
 
+	read_annotate(file, __annotate_nop);
+
 	/*
 	 * Must be before read_unwind_hints() since that needs insn->noendbr.
 	 */



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

* [PATCH 2/9] objtool: Convert ANNOTATE_NOENDBR to ANNOTATE
  2024-11-22 12:10 [PATCH 0/9] objtool: Rewrite annotations Peter Zijlstra
  2024-11-22 12:10 ` [PATCH 1/9] objtool: Generic annotation infrastructure Peter Zijlstra
@ 2024-11-22 12:10 ` Peter Zijlstra
  2024-11-22 12:10 ` [PATCH 3/9] objtool: Convert ANNOTATE_RETPOLINE_SAFE " Peter Zijlstra
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-22 12:10 UTC (permalink / raw)
  To: jpoimboe; +Cc: linux-kernel, peterz


Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 include/linux/objtool.h             |   17 ++++-------------
 include/linux/objtool_types.h       |    5 +++++
 tools/include/linux/objtool_types.h |    5 +++++
 tools/objtool/check.c               |   32 +++++---------------------------
 4 files changed, 19 insertions(+), 40 deletions(-)

--- a/include/linux/objtool.h
+++ b/include/linux/objtool.h
@@ -45,12 +45,6 @@
 #define STACK_FRAME_NON_STANDARD_FP(func)
 #endif
 
-#define ANNOTATE_NOENDBR					\
-	"986: \n\t"						\
-	".pushsection .discard.noendbr\n\t"			\
-	".long 986b\n\t"					\
-	".popsection\n\t"
-
 #define ASM_REACHABLE							\
 	"998:\n\t"							\
 	".pushsection .discard.reachable\n\t"				\
@@ -64,6 +58,8 @@
 	".long " __stringify(x) "\n\t"				\
 	".popsection\n\t"
 
+#define ANNOTATE_NOENDBR	ASM_ANNOTATE(ANNOTYPE_NOENDBR)
+
 #else /* __ASSEMBLY__ */
 
 /*
@@ -122,13 +118,6 @@
 #endif
 .endm
 
-.macro ANNOTATE_NOENDBR
-.Lhere_\@:
-	.pushsection .discard.noendbr
-	.long	.Lhere_\@
-	.popsection
-.endm
-
 /*
  * Use objtool to validate the entry requirement that all code paths do
  * VALIDATE_UNRET_END before RET.
@@ -161,6 +150,8 @@
 	.popsection
 .endm
 
+#define ANNOTATE_NOENDBR	ANNOTATE type=ANNOTYPE_NOENDBR
+
 #endif /* __ASSEMBLY__ */
 
 #else /* !CONFIG_OBJTOOL */
--- a/include/linux/objtool_types.h
+++ b/include/linux/objtool_types.h
@@ -54,4 +54,9 @@ struct unwind_hint {
 #define UNWIND_HINT_TYPE_SAVE		6
 #define UNWIND_HINT_TYPE_RESTORE	7
 
+/*
+ * Annotate types
+ */
+#define ANNOTYPE_NOENDBR		1
+
 #endif /* _LINUX_OBJTOOL_TYPES_H */
--- a/tools/include/linux/objtool_types.h
+++ b/tools/include/linux/objtool_types.h
@@ -54,4 +54,9 @@ struct unwind_hint {
 #define UNWIND_HINT_TYPE_SAVE		6
 #define UNWIND_HINT_TYPE_RESTORE	7
 
+/*
+ * Annotate types
+ */
+#define ANNOTYPE_NOENDBR		1
+
 #endif /* _LINUX_OBJTOOL_TYPES_H */
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2412,32 +2412,12 @@ static int read_annotate(struct objtool_
 	return 0;
 }
 
-static void __annotate_nop(int type, struct instruction *insn)
+static void __annotate_noendbr(int type, struct instruction *insn)
 {
-}
-
-static int read_noendbr_hints(struct objtool_file *file)
-{
-	struct instruction *insn;
-	struct section *rsec;
-	struct reloc *reloc;
-
-	rsec = find_section_by_name(file->elf, ".rela.discard.noendbr");
-	if (!rsec)
-		return 0;
+	if (type != ANNOTYPE_NOENDBR)
+		return;
 
-	for_each_reloc(rsec, reloc) {
-		insn = find_insn(file, reloc->sym->sec,
-				 reloc->sym->offset + reloc_addend(reloc));
-		if (!insn) {
-			WARN("bad .discard.noendbr entry");
-			return -1;
-		}
-
-		insn->noendbr = 1;
-	}
-
-	return 0;
+	insn->noendbr = 1;
 }
 
 static int read_retpoline_hints(struct objtool_file *file)
@@ -2713,12 +2693,10 @@ static int decode_sections(struct objtoo
 	if (ret)
 		return ret;
 
-	read_annotate(file, __annotate_nop);
-
 	/*
 	 * Must be before read_unwind_hints() since that needs insn->noendbr.
 	 */
-	ret = read_noendbr_hints(file);
+	ret = read_annotate(file, __annotate_noendbr);
 	if (ret)
 		return ret;
 



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

* [PATCH 3/9] objtool: Convert ANNOTATE_RETPOLINE_SAFE to ANNOTATE
  2024-11-22 12:10 [PATCH 0/9] objtool: Rewrite annotations Peter Zijlstra
  2024-11-22 12:10 ` [PATCH 1/9] objtool: Generic annotation infrastructure Peter Zijlstra
  2024-11-22 12:10 ` [PATCH 2/9] objtool: Convert ANNOTATE_NOENDBR to ANNOTATE Peter Zijlstra
@ 2024-11-22 12:10 ` Peter Zijlstra
  2024-11-22 12:10 ` [PATCH 4/9] objtool: Convert instrumentation_{begin,end}() " Peter Zijlstra
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-22 12:10 UTC (permalink / raw)
  To: jpoimboe; +Cc: linux-kernel, peterz


Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/nospec-branch.h |   13 +-------
 include/linux/objtool_types.h        |    1 
 tools/include/linux/objtool_types.h  |    1 
 tools/objtool/check.c                |   52 ++++++++++++-----------------------
 4 files changed, 22 insertions(+), 45 deletions(-)

--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -184,12 +184,7 @@
  * objtool the subsequent indirect jump/call is vouched safe for retpoline
  * builds.
  */
-.macro ANNOTATE_RETPOLINE_SAFE
-.Lhere_\@:
-	.pushsection .discard.retpoline_safe
-	.long .Lhere_\@
-	.popsection
-.endm
+#define ANNOTATE_RETPOLINE_SAFE	ANNOTATE type=ANNOTYPE_RETPOLINE_SAFE
 
 /*
  * (ab)use RETPOLINE_SAFE on RET to annotate away 'bare' RET instructions
@@ -350,11 +345,7 @@
 
 #else /* __ASSEMBLY__ */
 
-#define ANNOTATE_RETPOLINE_SAFE					\
-	"999:\n\t"						\
-	".pushsection .discard.retpoline_safe\n\t"		\
-	".long 999b\n\t"					\
-	".popsection\n\t"
+#define ANNOTATE_RETPOLINE_SAFE ASM_ANNOTATE(ANNOTYPE_RETPOLINE_SAFE)
 
 typedef u8 retpoline_thunk_t[RETPOLINE_THUNK_SIZE];
 extern retpoline_thunk_t __x86_indirect_thunk_array[];
--- a/include/linux/objtool_types.h
+++ b/include/linux/objtool_types.h
@@ -58,5 +58,6 @@ struct unwind_hint {
  * Annotate types
  */
 #define ANNOTYPE_NOENDBR		1
+#define ANNOTYPE_RETPOLINE_SAFE		2
 
 #endif /* _LINUX_OBJTOOL_TYPES_H */
--- a/tools/include/linux/objtool_types.h
+++ b/tools/include/linux/objtool_types.h
@@ -58,5 +58,6 @@ struct unwind_hint {
  * Annotate types
  */
 #define ANNOTYPE_NOENDBR		1
+#define ANNOTYPE_RETPOLINE_SAFE		2
 
 #endif /* _LINUX_OBJTOOL_TYPES_H */
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2373,12 +2373,12 @@ static int read_unwind_hints(struct objt
 	return 0;
 }
 
-static int read_annotate(struct objtool_file *file, void (*func)(int type, struct instruction *insn))
+static int read_annotate(struct objtool_file *file, int (*func)(int type, struct instruction *insn))
 {
 	struct section *sec;
 	struct instruction *insn;
 	struct reloc *reloc;
-	int type;
+	int type, ret;
 
 	sec = find_section_by_name(file->elf, ".discard.annotate");
 	if (!sec)
@@ -2406,53 +2406,37 @@ static int read_annotate(struct objtool_
 			return -1;
 		}
 
-		func(type, insn);
+		ret = func(type, insn);
+		if (ret < 0)
+			return ret;
 	}
 
 	return 0;
 }
 
-static void __annotate_noendbr(int type, struct instruction *insn)
+static int __annotate_noendbr(int type, struct instruction *insn)
 {
 	if (type != ANNOTYPE_NOENDBR)
-		return;
+		return 0;
 
 	insn->noendbr = 1;
+	return 0;
 }
 
-static int read_retpoline_hints(struct objtool_file *file)
+static int __annotate_retpoline_safe(int type, struct instruction *insn)
 {
-	struct section *rsec;
-	struct instruction *insn;
-	struct reloc *reloc;
-
-	rsec = find_section_by_name(file->elf, ".rela.discard.retpoline_safe");
-	if (!rsec)
+	if (type != ANNOTYPE_RETPOLINE_SAFE)
 		return 0;
 
-	for_each_reloc(rsec, reloc) {
-		if (reloc->sym->type != STT_SECTION) {
-			WARN("unexpected relocation symbol type in %s", rsec->name);
-			return -1;
-		}
-
-		insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc));
-		if (!insn) {
-			WARN("bad .discard.retpoline_safe entry");
-			return -1;
-		}
-
-		if (insn->type != INSN_JUMP_DYNAMIC &&
-		    insn->type != INSN_CALL_DYNAMIC &&
-		    insn->type != INSN_RETURN &&
-		    insn->type != INSN_NOP) {
-			WARN_INSN(insn, "retpoline_safe hint not an indirect jump/call/ret/nop");
-			return -1;
-		}
-
-		insn->retpoline_safe = true;
+	if (insn->type != INSN_JUMP_DYNAMIC &&
+	    insn->type != INSN_CALL_DYNAMIC &&
+	    insn->type != INSN_RETURN &&
+	    insn->type != INSN_NOP) {
+		WARN_INSN(insn, "retpoline_safe hint not an indirect jump/call/ret/nop");
+		return -1;
 	}
 
+	insn->retpoline_safe = true;
 	return 0;
 }
 
@@ -2742,7 +2726,7 @@ static int decode_sections(struct objtoo
 	if (ret)
 		return ret;
 
-	ret = read_retpoline_hints(file);
+	ret = read_annotate(file, __annotate_retpoline_safe);
 	if (ret)
 		return ret;
 



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

* [PATCH 4/9] objtool: Convert instrumentation_{begin,end}() to ANNOTATE
  2024-11-22 12:10 [PATCH 0/9] objtool: Rewrite annotations Peter Zijlstra
                   ` (2 preceding siblings ...)
  2024-11-22 12:10 ` [PATCH 3/9] objtool: Convert ANNOTATE_RETPOLINE_SAFE " Peter Zijlstra
@ 2024-11-22 12:10 ` Peter Zijlstra
  2024-11-22 12:10 ` [PATCH 5/9] objtool: Convert VALIDATE_UNRET_BEGIN " Peter Zijlstra
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-22 12:10 UTC (permalink / raw)
  To: jpoimboe; +Cc: linux-kernel, peterz


Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 include/linux/instrumentation.h     |   12 ++++----
 include/linux/objtool.h             |    9 ++++--
 include/linux/objtool_types.h       |    2 +
 tools/include/linux/objtool_types.h |    2 +
 tools/objtool/check.c               |   49 +++++++-----------------------------
 5 files changed, 26 insertions(+), 48 deletions(-)

--- a/include/linux/instrumentation.h
+++ b/include/linux/instrumentation.h
@@ -4,14 +4,15 @@
 
 #ifdef CONFIG_NOINSTR_VALIDATION
 
+#include <linux/objtool.h>
 #include <linux/stringify.h>
+#include <linux/args.h>
 
 /* Begin/end of an instrumentation safe region */
 #define __instrumentation_begin(c) ({					\
 	asm volatile(__stringify(c) ": nop\n\t"				\
-		     ".pushsection .discard.instr_begin\n\t"		\
-		     ".long " __stringify(c) "b - .\n\t"		\
-		     ".popsection\n\t" : : "i" (c));			\
+		     __ASM_ANNOTATE(CONCATENATE(c, b), ANNOTYPE_INSTR_BEGIN)	\
+		     : : "i" (c));					\
 })
 #define instrumentation_begin() __instrumentation_begin(__COUNTER__)
 
@@ -48,9 +49,8 @@
  */
 #define __instrumentation_end(c) ({					\
 	asm volatile(__stringify(c) ": nop\n\t"				\
-		     ".pushsection .discard.instr_end\n\t"		\
-		     ".long " __stringify(c) "b - .\n\t"		\
-		     ".popsection\n\t" : : "i" (c));			\
+		     __ASM_ANNOTATE(CONCATENATE(c, b), ANNOTYPE_INSTR_END)		\
+		     : : "i" (c));					\
 })
 #define instrumentation_end() __instrumentation_end(__COUNTER__)
 #else /* !CONFIG_NOINSTR_VALIDATION */
--- a/include/linux/objtool.h
+++ b/include/linux/objtool.h
@@ -51,13 +51,16 @@
 	".long 998b\n\t"						\
 	".popsection\n\t"
 
-#define ASM_ANNOTATE(x)						\
-	"911:\n\t"						\
+#define __ASM_ANNOTATE(s, x)					\
 	".pushsection .discard.annotate,\"M\",@progbits,8\n\t"	\
-	".long 911b - .\n\t"					\
+	".long " __stringify(s) " - .\n\t"			\
 	".long " __stringify(x) "\n\t"				\
 	".popsection\n\t"
 
+#define ASM_ANNOTATE(x)						\
+	"911:\n\t"						\
+	__ASM_ANNOTATE(911b, x)
+
 #define ANNOTATE_NOENDBR	ASM_ANNOTATE(ANNOTYPE_NOENDBR)
 
 #else /* __ASSEMBLY__ */
--- a/include/linux/objtool_types.h
+++ b/include/linux/objtool_types.h
@@ -59,5 +59,7 @@ struct unwind_hint {
  */
 #define ANNOTYPE_NOENDBR		1
 #define ANNOTYPE_RETPOLINE_SAFE		2
+#define ANNOTYPE_INSTR_BEGIN		3
+#define ANNOTYPE_INSTR_END		4
 
 #endif /* _LINUX_OBJTOOL_TYPES_H */
--- a/tools/include/linux/objtool_types.h
+++ b/tools/include/linux/objtool_types.h
@@ -59,5 +59,7 @@ struct unwind_hint {
  */
 #define ANNOTYPE_NOENDBR		1
 #define ANNOTYPE_RETPOLINE_SAFE		2
+#define ANNOTYPE_INSTR_BEGIN		3
+#define ANNOTYPE_INSTR_END		4
 
 #endif /* _LINUX_OBJTOOL_TYPES_H */
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2440,48 +2440,19 @@ static int __annotate_retpoline_safe(int
 	return 0;
 }
 
-static int read_instr_hints(struct objtool_file *file)
+static int __annotate_instr(int type, struct instruction *insn)
 {
-	struct section *rsec;
-	struct instruction *insn;
-	struct reloc *reloc;
-
-	rsec = find_section_by_name(file->elf, ".rela.discard.instr_end");
-	if (!rsec)
-		return 0;
-
-	for_each_reloc(rsec, reloc) {
-		if (reloc->sym->type != STT_SECTION) {
-			WARN("unexpected relocation symbol type in %s", rsec->name);
-			return -1;
-		}
-
-		insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc));
-		if (!insn) {
-			WARN("bad .discard.instr_end entry");
-			return -1;
-		}
+	switch (type) {
+	case ANNOTYPE_INSTR_BEGIN:
+		insn->instr++;
+		break;
 
+	case ANNOTYPE_INSTR_END:
 		insn->instr--;
-	}
-
-	rsec = find_section_by_name(file->elf, ".rela.discard.instr_begin");
-	if (!rsec)
-		return 0;
+		break;
 
-	for_each_reloc(rsec, reloc) {
-		if (reloc->sym->type != STT_SECTION) {
-			WARN("unexpected relocation symbol type in %s", rsec->name);
-			return -1;
-		}
-
-		insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc));
-		if (!insn) {
-			WARN("bad .discard.instr_begin entry");
-			return -1;
-		}
-
-		insn->instr++;
+	default:
+		break;
 	}
 
 	return 0;
@@ -2730,7 +2701,7 @@ static int decode_sections(struct objtoo
 	if (ret)
 		return ret;
 
-	ret = read_instr_hints(file);
+	ret = read_annotate(file, __annotate_instr);
 	if (ret)
 		return ret;
 



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

* [PATCH 5/9] objtool: Convert VALIDATE_UNRET_BEGIN to ANNOTATE
  2024-11-22 12:10 [PATCH 0/9] objtool: Rewrite annotations Peter Zijlstra
                   ` (3 preceding siblings ...)
  2024-11-22 12:10 ` [PATCH 4/9] objtool: Convert instrumentation_{begin,end}() " Peter Zijlstra
@ 2024-11-22 12:10 ` Peter Zijlstra
  2024-11-22 12:10 ` [PATCH 6/9] objtool: Convert ANNOTATE_IGNORE_ALTERNATIVE " Peter Zijlstra
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-22 12:10 UTC (permalink / raw)
  To: jpoimboe; +Cc: linux-kernel, peterz


Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 include/linux/objtool.h             |    9 +++------
 include/linux/objtool_types.h       |    1 +
 tools/include/linux/objtool_types.h |    1 +
 tools/objtool/check.c               |   28 +++++-----------------------
 4 files changed, 10 insertions(+), 29 deletions(-)

--- a/include/linux/objtool.h
+++ b/include/linux/objtool.h
@@ -128,15 +128,12 @@
  * NOTE: The macro must be used at the beginning of a global symbol, otherwise
  * it will be ignored.
  */
-.macro VALIDATE_UNRET_BEGIN
 #if defined(CONFIG_NOINSTR_VALIDATION) && \
 	(defined(CONFIG_MITIGATION_UNRET_ENTRY) || defined(CONFIG_MITIGATION_SRSO))
-.Lhere_\@:
-	.pushsection .discard.validate_unret
-	.long	.Lhere_\@ - .
-	.popsection
+#define VALIDATE_UNRET_BEGIN	ANNOTATE type=ANNOTYPE_UNRET_BEGIN
+#else
+#define VALIDATE_UNRET_BEGIN
 #endif
-.endm
 
 .macro REACHABLE
 .Lhere_\@:
--- a/include/linux/objtool_types.h
+++ b/include/linux/objtool_types.h
@@ -61,5 +61,6 @@ struct unwind_hint {
 #define ANNOTYPE_RETPOLINE_SAFE		2
 #define ANNOTYPE_INSTR_BEGIN		3
 #define ANNOTYPE_INSTR_END		4
+#define ANNOTYPE_UNRET_BEGIN		5
 
 #endif /* _LINUX_OBJTOOL_TYPES_H */
--- a/tools/include/linux/objtool_types.h
+++ b/tools/include/linux/objtool_types.h
@@ -61,5 +61,6 @@ struct unwind_hint {
 #define ANNOTYPE_RETPOLINE_SAFE		2
 #define ANNOTYPE_INSTR_BEGIN		3
 #define ANNOTYPE_INSTR_END		4
+#define ANNOTYPE_UNRET_BEGIN		5
 
 #endif /* _LINUX_OBJTOOL_TYPES_H */
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2450,33 +2450,15 @@ static int __annotate_instr(int type, st
 	return 0;
 }
 
-static int read_validate_unret_hints(struct objtool_file *file)
+static int __annotate_unret(int type, struct instruction *insn)
 {
-	struct section *rsec;
-	struct instruction *insn;
-	struct reloc *reloc;
-
-	rsec = find_section_by_name(file->elf, ".rela.discard.validate_unret");
-	if (!rsec)
+	if (type != ANNOTYPE_UNRET_BEGIN)
 		return 0;
 
-	for_each_reloc(rsec, reloc) {
-		if (reloc->sym->type != STT_SECTION) {
-			WARN("unexpected relocation symbol type in %s", rsec->name);
-			return -1;
-		}
-
-		insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc));
-		if (!insn) {
-			WARN("bad .discard.instr_end entry");
-			return -1;
-		}
-		insn->unret = 1;
-	}
-
+	insn->unret = 1;
 	return 0;
-}
 
+}
 
 static int read_intra_function_calls(struct objtool_file *file)
 {
@@ -2697,7 +2679,7 @@ static int decode_sections(struct objtoo
 	if (ret)
 		return ret;
 
-	ret = read_validate_unret_hints(file);
+	ret = read_annotate(file, __annotate_unret);
 	if (ret)
 		return ret;
 



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

* [PATCH 6/9] objtool: Convert ANNOTATE_IGNORE_ALTERNATIVE to ANNOTATE
  2024-11-22 12:10 [PATCH 0/9] objtool: Rewrite annotations Peter Zijlstra
                   ` (4 preceding siblings ...)
  2024-11-22 12:10 ` [PATCH 5/9] objtool: Convert VALIDATE_UNRET_BEGIN " Peter Zijlstra
@ 2024-11-22 12:10 ` Peter Zijlstra
  2024-11-22 12:10 ` [PATCH 7/9] objtool: Convert ANNOTATE_INTRA_FUNCTION_CALLS " Peter Zijlstra
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-22 12:10 UTC (permalink / raw)
  To: jpoimboe; +Cc: linux-kernel, peterz


Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/alternative.h  |   14 ++---------
 include/linux/objtool_types.h       |    1 
 tools/include/linux/objtool_types.h |    1 
 tools/objtool/check.c               |   45 ++++++++----------------------------
 4 files changed, 15 insertions(+), 46 deletions(-)

--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -4,6 +4,7 @@
 
 #include <linux/types.h>
 #include <linux/stringify.h>
+#include <linux/objtool.h>
 #include <asm/asm.h>
 
 #define ALT_FLAGS_SHIFT		16
@@ -55,11 +56,7 @@
  * objtool annotation to ignore the alternatives and only consider the original
  * instruction(s).
  */
-#define ANNOTATE_IGNORE_ALTERNATIVE				\
-	"999:\n\t"						\
-	".pushsection .discard.ignore_alts\n\t"			\
-	".long 999b\n\t"					\
-	".popsection\n\t"
+#define ANNOTATE_IGNORE_ALTERNATIVE	ASM_ANNOTATE(ANNOTYPE_IGNORE_ALTS)
 
 /*
  * The patching flags are part of the upper bits of the @ft_flags parameter when
@@ -349,12 +346,7 @@ static inline int alternatives_text_rese
  * objtool annotation to ignore the alternatives and only consider the original
  * instruction(s).
  */
-.macro ANNOTATE_IGNORE_ALTERNATIVE
-	.Lannotate_\@:
-	.pushsection .discard.ignore_alts
-	.long .Lannotate_\@
-	.popsection
-.endm
+#define ANNOTATE_IGNORE_ALTERNATIVE ANNOTATE type=ANNOTYPE_IGNORE_ALTS
 
 /*
  * Issue one struct alt_instr descriptor entry (need to put it into
--- a/include/linux/objtool_types.h
+++ b/include/linux/objtool_types.h
@@ -62,5 +62,6 @@ struct unwind_hint {
 #define ANNOTYPE_INSTR_BEGIN		3
 #define ANNOTYPE_INSTR_END		4
 #define ANNOTYPE_UNRET_BEGIN		5
+#define ANNOTYPE_IGNORE_ALTS		6
 
 #endif /* _LINUX_OBJTOOL_TYPES_H */
--- a/tools/include/linux/objtool_types.h
+++ b/tools/include/linux/objtool_types.h
@@ -62,5 +62,6 @@ struct unwind_hint {
 #define ANNOTYPE_INSTR_BEGIN		3
 #define ANNOTYPE_INSTR_END		4
 #define ANNOTYPE_UNRET_BEGIN		5
+#define ANNOTYPE_IGNORE_ALTS		6
 
 #endif /* _LINUX_OBJTOOL_TYPES_H */
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1255,40 +1255,6 @@ static void add_uaccess_safe(struct objt
 }
 
 /*
- * FIXME: For now, just ignore any alternatives which add retpolines.  This is
- * a temporary hack, as it doesn't allow ORC to unwind from inside a retpoline.
- * But it at least allows objtool to understand the control flow *around* the
- * retpoline.
- */
-static int add_ignore_alternatives(struct objtool_file *file)
-{
-	struct section *rsec;
-	struct reloc *reloc;
-	struct instruction *insn;
-
-	rsec = find_section_by_name(file->elf, ".rela.discard.ignore_alts");
-	if (!rsec)
-		return 0;
-
-	for_each_reloc(rsec, reloc) {
-		if (reloc->sym->type != STT_SECTION) {
-			WARN("unexpected relocation symbol type in %s", rsec->name);
-			return -1;
-		}
-
-		insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc));
-		if (!insn) {
-			WARN("bad .discard.ignore_alts entry");
-			return -1;
-		}
-
-		insn->ignore_alts = true;
-	}
-
-	return 0;
-}
-
-/*
  * Symbols that replace INSN_CALL_DYNAMIC, every (tail) call to such a symbol
  * will be added to the .retpoline_sites section.
  */
@@ -2341,6 +2307,15 @@ static int read_annotate(struct objtool_
 	return 0;
 }
 
+static int __annotate_ignore_alts(int type, struct instruction *insn)
+{
+	if (type != ANNOTYPE_IGNORE_ALTS)
+		return 0;
+
+	insn->ignore_alts = true;
+	return 0;
+}
+
 static int __annotate_noendbr(int type, struct instruction *insn)
 {
 	if (type != ANNOTYPE_NOENDBR)
@@ -2550,7 +2525,7 @@ static int decode_sections(struct objtoo
 	add_ignores(file);
 	add_uaccess_safe(file);
 
-	ret = add_ignore_alternatives(file);
+	ret = read_annotate(file, __annotate_ignore_alts);
 	if (ret)
 		return ret;
 



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

* [PATCH 7/9] objtool: Convert ANNOTATE_INTRA_FUNCTION_CALLS to ANNOTATE
  2024-11-22 12:10 [PATCH 0/9] objtool: Rewrite annotations Peter Zijlstra
                   ` (5 preceding siblings ...)
  2024-11-22 12:10 ` [PATCH 6/9] objtool: Convert ANNOTATE_IGNORE_ALTERNATIVE " Peter Zijlstra
@ 2024-11-22 12:10 ` Peter Zijlstra
  2024-11-22 17:22   ` Josh Poimboeuf
  2024-11-22 12:10 ` [PATCH 8/9] objtool: Collapse annotate sequences Peter Zijlstra
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-22 12:10 UTC (permalink / raw)
  To: jpoimboe; +Cc: linux-kernel, peterz


Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 include/linux/objtool.h             |   16 ++----
 include/linux/objtool_types.h       |    1 
 tools/include/linux/objtool_types.h |    1 
 tools/objtool/check.c               |   96 ++++++++++++++----------------------
 4 files changed, 47 insertions(+), 67 deletions(-)

--- a/include/linux/objtool.h
+++ b/include/linux/objtool.h
@@ -66,16 +66,6 @@
 #else /* __ASSEMBLY__ */
 
 /*
- * This macro indicates that the following intra-function call is valid.
- * Any non-annotated intra-function call will cause objtool to issue a warning.
- */
-#define ANNOTATE_INTRA_FUNCTION_CALL				\
-	999:							\
-	.pushsection .discard.intra_function_calls;		\
-	.long 999b;						\
-	.popsection;
-
-/*
  * In asm, there are two kinds of code: normal C-type callable functions and
  * the rest.  The normal callable functions can be called by other code, and
  * don't do anything unusual with the stack.  Such normal callable functions
@@ -152,6 +142,12 @@
 
 #define ANNOTATE_NOENDBR	ANNOTATE type=ANNOTYPE_NOENDBR
 
+/*
+ * This macro indicates that the following intra-function call is valid.
+ * Any non-annotated intra-function call will cause objtool to issue a warning.
+ */
+#define ANNOTATE_INTRA_FUNCTION_CALL ANNOTATE type=ANNOTYPE_INTRA_FUNCTION_CALL
+
 #endif /* __ASSEMBLY__ */
 
 #else /* !CONFIG_OBJTOOL */
--- a/include/linux/objtool_types.h
+++ b/include/linux/objtool_types.h
@@ -63,5 +63,6 @@ struct unwind_hint {
 #define ANNOTYPE_INSTR_END		4
 #define ANNOTYPE_UNRET_BEGIN		5
 #define ANNOTYPE_IGNORE_ALTS		6
+#define ANNOTYPE_INTRA_FUNCTION_CALL	7
 
 #endif /* _LINUX_OBJTOOL_TYPES_H */
--- a/tools/include/linux/objtool_types.h
+++ b/tools/include/linux/objtool_types.h
@@ -63,5 +63,6 @@ struct unwind_hint {
 #define ANNOTYPE_INSTR_END		4
 #define ANNOTYPE_UNRET_BEGIN		5
 #define ANNOTYPE_IGNORE_ALTS		6
+#define ANNOTYPE_INTRA_FUNCTION_CALL	7
 
 #endif /* _LINUX_OBJTOOL_TYPES_H */
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2339,7 +2339,8 @@ static int read_unwind_hints(struct objt
 	return 0;
 }
 
-static int read_annotate(struct objtool_file *file, int (*func)(int type, struct instruction *insn))
+static int read_annotate(struct objtool_file *file,
+			 int (*func)(struct objtool_file *file, int type, struct instruction *insn))
 {
 	struct section *sec;
 	struct instruction *insn;
@@ -2372,7 +2373,7 @@ static int read_annotate(struct objtool_
 			return -1;
 		}
 
-		ret = func(type, insn);
+		ret = func(file, type, insn);
 		if (ret < 0)
 			return ret;
 	}
@@ -2380,7 +2381,7 @@ static int read_annotate(struct objtool_
 	return 0;
 }
 
-static int __annotate_ignore_alts(int type, struct instruction *insn)
+static int __annotate_ignore_alts(struct objtool_file *file, int type, struct instruction *insn)
 {
 	if (type != ANNOTYPE_IGNORE_ALTS)
 		return 0;
@@ -2389,7 +2390,7 @@ static int __annotate_ignore_alts(int ty
 	return 0;
 }
 
-static int __annotate_noendbr(int type, struct instruction *insn)
+static int __annotate_noendbr(struct objtool_file *file, int type, struct instruction *insn)
 {
 	if (type != ANNOTYPE_NOENDBR)
 		return 0;
@@ -2398,7 +2399,37 @@ static int __annotate_noendbr(int type,
 	return 0;
 }
 
-static int __annotate_retpoline_safe(int type, struct instruction *insn)
+static int __annotate_ifc(struct objtool_file *file, int type, struct instruction *insn)
+{
+	unsigned long dest_off;
+
+	if (type != ANNOTYPE_INTRA_FUNCTION_CALL)
+		return 0;
+
+	if (insn->type != INSN_CALL) {
+		WARN_INSN(insn, "intra_function_call not a direct call");
+		return -1;
+	}
+
+	/*
+	 * Treat intra-function CALLs as JMPs, but with a stack_op.
+	 * See add_call_destinations(), which strips stack_ops from
+	 * normal CALLs.
+	 */
+	insn->type = INSN_JUMP_UNCONDITIONAL;
+
+	dest_off = arch_jump_destination(insn);
+	insn->jump_dest = find_insn(file, insn->sec, dest_off);
+	if (!insn->jump_dest) {
+		WARN_INSN(insn, "can't find call dest at %s+0x%lx",
+			  insn->sec->name, dest_off);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int __annotate_retpoline_safe(struct objtool_file *file, int type, struct instruction *insn)
 {
 	if (type != ANNOTYPE_RETPOLINE_SAFE)
 		return 0;
@@ -2415,7 +2446,7 @@ static int __annotate_retpoline_safe(int
 	return 0;
 }
 
-static int __annotate_instr(int type, struct instruction *insn)
+static int __annotate_instr(struct objtool_file *file, int type, struct instruction *insn)
 {
 	switch (type) {
 	case ANNOTYPE_INSTR_BEGIN:
@@ -2433,7 +2464,7 @@ static int __annotate_instr(int type, st
 	return 0;
 }
 
-static int __annotate_unret(int type, struct instruction *insn)
+static int __annotate_unret(struct objtool_file *file, int type, struct instruction *insn)
 {
 	if (type != ANNOTYPE_UNRET_BEGIN)
 		return 0;
@@ -2443,55 +2474,6 @@ static int __annotate_unret(int type, st
 
 }
 
-static int read_intra_function_calls(struct objtool_file *file)
-{
-	struct instruction *insn;
-	struct section *rsec;
-	struct reloc *reloc;
-
-	rsec = find_section_by_name(file->elf, ".rela.discard.intra_function_calls");
-	if (!rsec)
-		return 0;
-
-	for_each_reloc(rsec, reloc) {
-		unsigned long dest_off;
-
-		if (reloc->sym->type != STT_SECTION) {
-			WARN("unexpected relocation symbol type in %s",
-			     rsec->name);
-			return -1;
-		}
-
-		insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc));
-		if (!insn) {
-			WARN("bad .discard.intra_function_call entry");
-			return -1;
-		}
-
-		if (insn->type != INSN_CALL) {
-			WARN_INSN(insn, "intra_function_call not a direct call");
-			return -1;
-		}
-
-		/*
-		 * Treat intra-function CALLs as JMPs, but with a stack_op.
-		 * See add_call_destinations(), which strips stack_ops from
-		 * normal CALLs.
-		 */
-		insn->type = INSN_JUMP_UNCONDITIONAL;
-
-		dest_off = arch_jump_destination(insn);
-		insn->jump_dest = find_insn(file, insn->sec, dest_off);
-		if (!insn->jump_dest) {
-			WARN_INSN(insn, "can't find call dest at %s+0x%lx",
-				  insn->sec->name, dest_off);
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
 /*
  * Return true if name matches an instrumentation function, where calls to that
  * function from noinstr code can safely be removed, but compilers won't do so.
@@ -2630,7 +2612,7 @@ static int decode_sections(struct objtoo
 	 * Must be before add_call_destination(); it changes INSN_CALL to
 	 * INSN_JUMP.
 	 */
-	ret = read_intra_function_calls(file);
+	ret = read_annotate(file, __annotate_ifc);
 	if (ret)
 		return ret;
 



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

* [PATCH 8/9] objtool: Collapse annotate sequences
  2024-11-22 12:10 [PATCH 0/9] objtool: Rewrite annotations Peter Zijlstra
                   ` (6 preceding siblings ...)
  2024-11-22 12:10 ` [PATCH 7/9] objtool: Convert ANNOTATE_INTRA_FUNCTION_CALLS " Peter Zijlstra
@ 2024-11-22 12:10 ` Peter Zijlstra
  2024-11-22 17:57   ` Josh Poimboeuf
  2024-11-22 12:10 ` [PATCH 9/9] objtool: Collect all annotations in objtool.h Peter Zijlstra
  2024-11-22 17:40 ` [PATCH 0/9] objtool: Rewrite annotations Josh Poimboeuf
  9 siblings, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-22 12:10 UTC (permalink / raw)
  To: jpoimboe; +Cc: linux-kernel, peterz

Reduce read_annotate() runs by collapsing subsequent runs into a
single call.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20241111125218.921110073@infradead.org
---
 tools/objtool/check.c |   87 ++++++++++++++++++--------------------------------
 1 file changed, 32 insertions(+), 55 deletions(-)

--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2308,21 +2308,24 @@ static int read_annotate(struct objtool_
 	return 0;
 }
 
-static int __annotate_ignore_alts(struct objtool_file *file, int type, struct instruction *insn)
+static int __annotate_early(struct objtool_file *file, int type, struct instruction *insn)
 {
-	if (type != ANNOTYPE_IGNORE_ALTS)
-		return 0;
+	switch (type) {
+	case ANNOTYPE_IGNORE_ALTS:
+		insn->ignore_alts = true;
+		break;
 
-	insn->ignore_alts = true;
-	return 0;
-}
+	/*
+	 * Must be before read_unwind_hints() since that needs insn->noendbr.
+	 */
+	case ANNOTYPE_NOENDBR:
+		insn->noendbr = 1;
+		break;
 
-static int __annotate_noendbr(struct objtool_file *file, int type, struct instruction *insn)
-{
-	if (type != ANNOTYPE_NOENDBR)
-		return 0;
+	default:
+		break;
+	}
 
-	insn->noendbr = 1;
 	return 0;
 }
 
@@ -2356,26 +2359,21 @@ static int __annotate_ifc(struct objtool
 	return 0;
 }
 
-static int __annotate_retpoline_safe(struct objtool_file *file, int type, struct instruction *insn)
+static int __annotate_late(struct objtool_file *file, int type, struct instruction *insn)
 {
-	if (type != ANNOTYPE_RETPOLINE_SAFE)
-		return 0;
-
-	if (insn->type != INSN_JUMP_DYNAMIC &&
-	    insn->type != INSN_CALL_DYNAMIC &&
-	    insn->type != INSN_RETURN &&
-	    insn->type != INSN_NOP) {
-		WARN_INSN(insn, "retpoline_safe hint not an indirect jump/call/ret/nop");
-		return -1;
-	}
+	switch (type) {
+	case ANNOTYPE_RETPOLINE_SAFE:
+		if (insn->type != INSN_JUMP_DYNAMIC &&
+		    insn->type != INSN_CALL_DYNAMIC &&
+		    insn->type != INSN_RETURN &&
+		    insn->type != INSN_NOP) {
+			WARN_INSN(insn, "retpoline_safe hint not an indirect jump/call/ret/nop");
+			return -1;
+		}
 
-	insn->retpoline_safe = true;
-	return 0;
-}
+		insn->retpoline_safe = true;
+		break;
 
-static int __annotate_instr(struct objtool_file *file, int type, struct instruction *insn)
-{
-	switch (type) {
 	case ANNOTYPE_INSTR_BEGIN:
 		insn->instr++;
 		break;
@@ -2384,6 +2382,10 @@ static int __annotate_instr(struct objto
 		insn->instr--;
 		break;
 
+	case ANNOTYPE_UNRET_BEGIN:
+		insn->unret = 1;
+		break;
+
 	default:
 		break;
 	}
@@ -2391,16 +2393,6 @@ static int __annotate_instr(struct objto
 	return 0;
 }
 
-static int __annotate_unret(struct objtool_file *file, int type, struct instruction *insn)
-{
-	if (type != ANNOTYPE_UNRET_BEGIN)
-		return 0;
-
-	insn->unret = 1;
-	return 0;
-
-}
-
 /*
  * Return true if name matches an instrumentation function, where calls to that
  * function from noinstr code can safely be removed, but compilers won't do so.
@@ -2507,14 +2499,7 @@ static int decode_sections(struct objtoo
 	add_ignores(file);
 	add_uaccess_safe(file);
 
-	ret = read_annotate(file, __annotate_ignore_alts);
-	if (ret)
-		return ret;
-
-	/*
-	 * Must be before read_unwind_hints() since that needs insn->noendbr.
-	 */
-	ret = read_annotate(file, __annotate_noendbr);
+	ret = read_annotate(file, __annotate_early);
 	if (ret)
 		return ret;
 
@@ -2560,15 +2545,7 @@ static int decode_sections(struct objtoo
 	if (ret)
 		return ret;
 
-	ret = read_annotate(file, __annotate_retpoline_safe);
-	if (ret)
-		return ret;
-
-	ret = read_annotate(file, __annotate_instr);
-	if (ret)
-		return ret;
-
-	ret = read_annotate(file, __annotate_unret);
+	ret = read_annotate(file, __annotate_late);
 	if (ret)
 		return ret;
 



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

* [PATCH 9/9] objtool: Collect all annotations in objtool.h
  2024-11-22 12:10 [PATCH 0/9] objtool: Rewrite annotations Peter Zijlstra
                   ` (7 preceding siblings ...)
  2024-11-22 12:10 ` [PATCH 8/9] objtool: Collapse annotate sequences Peter Zijlstra
@ 2024-11-22 12:10 ` Peter Zijlstra
  2024-11-22 17:54   ` Josh Poimboeuf
  2024-11-22 17:40 ` [PATCH 0/9] objtool: Rewrite annotations Josh Poimboeuf
  9 siblings, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-22 12:10 UTC (permalink / raw)
  To: jpoimboe; +Cc: linux-kernel, peterz


Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/alternative.h   |   12 ------------
 arch/x86/include/asm/nospec-branch.h |    9 ---------
 include/linux/objtool.h              |   30 +++++++++++++++++++++++-------
 3 files changed, 23 insertions(+), 28 deletions(-)

--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -56,12 +56,6 @@
 #endif
 
 /*
- * objtool annotation to ignore the alternatives and only consider the original
- * instruction(s).
- */
-#define ANNOTATE_IGNORE_ALTERNATIVE	ASM_ANNOTATE(ANNOTYPE_IGNORE_ALTS)
-
-/*
  * The patching flags are part of the upper bits of the @ft_flags parameter when
  * specifying them. The split is currently like this:
  *
@@ -308,12 +302,6 @@ void nop_func(void);
 #endif
 
 /*
- * objtool annotation to ignore the alternatives and only consider the original
- * instruction(s).
- */
-#define ANNOTATE_IGNORE_ALTERNATIVE ANNOTATE type=ANNOTYPE_IGNORE_ALTS
-
-/*
  * Issue one struct alt_instr descriptor entry (need to put it into
  * the section .altinstructions, see below). This entry contains
  * enough information for the alternatives patching code to patch an
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -180,13 +180,6 @@
 #ifdef __ASSEMBLY__
 
 /*
- * This should be used immediately before an indirect jump/call. It tells
- * objtool the subsequent indirect jump/call is vouched safe for retpoline
- * builds.
- */
-#define ANNOTATE_RETPOLINE_SAFE	ANNOTATE type=ANNOTYPE_RETPOLINE_SAFE
-
-/*
  * (ab)use RETPOLINE_SAFE on RET to annotate away 'bare' RET instructions
  * vs RETBleed validation.
  */
@@ -345,8 +338,6 @@
 
 #else /* __ASSEMBLY__ */
 
-#define ANNOTATE_RETPOLINE_SAFE ASM_ANNOTATE(ANNOTYPE_RETPOLINE_SAFE)
-
 typedef u8 retpoline_thunk_t[RETPOLINE_THUNK_SIZE];
 extern retpoline_thunk_t __x86_indirect_thunk_array[];
 extern retpoline_thunk_t __x86_indirect_call_thunk_array[];
--- a/include/linux/objtool.h
+++ b/include/linux/objtool.h
@@ -61,8 +61,6 @@
 	"911:\n\t"						\
 	__ASM_ANNOTATE(911b, x)
 
-#define ANNOTATE_NOENDBR	ASM_ANNOTATE(ANNOTYPE_NOENDBR)
-
 #else /* __ASSEMBLY__ */
 
 /*
@@ -140,8 +138,6 @@
 	.popsection
 .endm
 
-#define ANNOTATE_NOENDBR	ANNOTATE type=ANNOTYPE_NOENDBR
-
 /*
  * This macro indicates that the following intra-function call is valid.
  * Any non-annotated intra-function call will cause objtool to issue a warning.
@@ -158,7 +154,6 @@
 #define STACK_FRAME_NON_STANDARD(func)
 #define STACK_FRAME_NON_STANDARD_FP(func)
 #define ASM_ANNOTATE(x)
-#define ANNOTATE_NOENDBR
 #define ASM_REACHABLE
 #else
 #define ANNOTATE_INTRA_FUNCTION_CALL
@@ -166,8 +161,6 @@
 .endm
 .macro STACK_FRAME_NON_STANDARD func:req
 .endm
-.macro ANNOTATE_NOENDBR
-.endm
 .macro REACHABLE
 .endm
 .macro ANNOTATE type:req
@@ -176,4 +169,27 @@
 
 #endif /* CONFIG_OBJTOOL */
 
+#ifndef __ASSEMBLY__
+/*
+ * Annotate away the various 'relocation to !ENDBR` complaints; knowing that
+ * these relocations will never be used for indirect calls.
+ */
+#define ANNOTATE_NOENDBR		ASM_ANNOTATE(ANNOTYPE_NOENDBR)
+/*
+ * This should be used immediately before an indirect jump/call. It tells
+ * objtool the subsequent indirect jump/call is vouched safe for retpoline
+ * builds.
+ */
+#define ANNOTATE_RETPOLINE_SAFE		ASM_ANNOTATE(ANNOTYPE_RETPOLINE_SAFE)
+/*
+ * objtool annotation to ignore the alternatives and only consider the original
+ * instruction(s).
+ */
+#define ANNOTATE_IGNORE_ALTERNATIVE	ASM_ANNOTATE(ANNOTYPE_IGNORE_ALTS)
+#else
+#define ANNOTATE_NOENDBR		ANNOTATE type=ANNOTYPE_NOENDBR
+#define ANNOTATE_RETPOLINE_SAFE		ANNOTATE type=ANNOTYPE_RETPOLINE_SAFE
+#define ANNOTATE_IGNORE_ALTERNATIVE	ANNOTATE type=ANNOTYPE_IGNORE_ALTS
+#endif
+
 #endif /* _LINUX_OBJTOOL_H */



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

* Re: [PATCH 7/9] objtool: Convert ANNOTATE_INTRA_FUNCTION_CALLS to ANNOTATE
  2024-11-22 12:10 ` [PATCH 7/9] objtool: Convert ANNOTATE_INTRA_FUNCTION_CALLS " Peter Zijlstra
@ 2024-11-22 17:22   ` Josh Poimboeuf
  0 siblings, 0 replies; 22+ messages in thread
From: Josh Poimboeuf @ 2024-11-22 17:22 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: linux-kernel

On Fri, Nov 22, 2024 at 01:10:23PM +0100, Peter Zijlstra wrote:
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

s/CALLS/CALL/ in $SUBJECT

-- 
Josh

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

* Re: [PATCH 0/9] objtool: Rewrite annotations
  2024-11-22 12:10 [PATCH 0/9] objtool: Rewrite annotations Peter Zijlstra
                   ` (8 preceding siblings ...)
  2024-11-22 12:10 ` [PATCH 9/9] objtool: Collect all annotations in objtool.h Peter Zijlstra
@ 2024-11-22 17:40 ` Josh Poimboeuf
  2024-11-23 13:21   ` Peter Zijlstra
  9 siblings, 1 reply; 22+ messages in thread
From: Josh Poimboeuf @ 2024-11-22 17:40 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: linux-kernel

On Fri, Nov 22, 2024 at 01:10:16PM +0100, Peter Zijlstra wrote:
> Just the objtool annotation rewrite bits.
> 
> Changes since last time:
> 
>  - split from the x86 and kvm patches
>  - s/ANNOTYPE_INTRA_FUNCTION_CALLS/ANNOTYPE_INTRA_FUNCTION_CALL/g
>  - made __ASM_ANNOTATE() take a full label name (no longer appends 'b')
>  - added a patch that moves all the annotations to objtool.h
>  - some changes to the first patch

For Valentin's thing we'll be adding annotations for static keys.  Those
will be symbol specific, like STACK_FRAME_NON_STANDARD().  In which case
we could have a generic .discard.annotate_sym.  And then rename
.discard.annotate to .discard.annotate_insn?

-- 
Josh

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

* Re: [PATCH 9/9] objtool: Collect all annotations in objtool.h
  2024-11-22 12:10 ` [PATCH 9/9] objtool: Collect all annotations in objtool.h Peter Zijlstra
@ 2024-11-22 17:54   ` Josh Poimboeuf
  2024-11-23 13:19     ` Peter Zijlstra
  0 siblings, 1 reply; 22+ messages in thread
From: Josh Poimboeuf @ 2024-11-22 17:54 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: linux-kernel

On Fri, Nov 22, 2024 at 01:10:25PM +0100, Peter Zijlstra wrote:
> +#ifndef __ASSEMBLY__
> +/*
> + * Annotate away the various 'relocation to !ENDBR` complaints; knowing that
> + * these relocations will never be used for indirect calls.
> + */
> +#define ANNOTATE_NOENDBR		ASM_ANNOTATE(ANNOTYPE_NOENDBR)
> +/*
> + * This should be used immediately before an indirect jump/call. It tells
> + * objtool the subsequent indirect jump/call is vouched safe for retpoline
> + * builds.
> + */
> +#define ANNOTATE_RETPOLINE_SAFE		ASM_ANNOTATE(ANNOTYPE_RETPOLINE_SAFE)
> +/*
> + * objtool annotation to ignore the alternatives and only consider the original
> + * instruction(s).
> + */
> +#define ANNOTATE_IGNORE_ALTERNATIVE	ASM_ANNOTATE(ANNOTYPE_IGNORE_ALTS)

This is a good start, though it would be really nice to have them *all*
together:

  - move ANNOTATE_INTRA_FUNCTION_CALL down next to those ^

  - create ANNOTATE_INSTR_BEGIN and ANNOTATE_INSTR_END, and then do
    
      #define instrumentation_begin() ANNOTATE_INSTR_BEGIN

    to keep the existing syntax.  Then instrumentation.h is no longer
    needed.  The nice comment there can go above ANNOTATE_INSTR_BEGIN.

  - similarly, create ANNOTATE_UNRET_BEGIN and just do

      #define VALIDATE_UNRET_BEGIN ANNOTATE_UNRET_BEGIN
    
    since the VALIDATE_* syntax is more descriptive.

So basically even the macros with non-ANNOTATE naming still resolve to
ANNOTATE_FOO, with all the ANNOTATE_FOOs in one place, each with its own
nice comment.

BTW, is there a reason .discard.[un]reachable weren't converted over?

-- 
Josh

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

* Re: [PATCH 8/9] objtool: Collapse annotate sequences
  2024-11-22 12:10 ` [PATCH 8/9] objtool: Collapse annotate sequences Peter Zijlstra
@ 2024-11-22 17:57   ` Josh Poimboeuf
  2024-11-23 13:09     ` Peter Zijlstra
  0 siblings, 1 reply; 22+ messages in thread
From: Josh Poimboeuf @ 2024-11-22 17:57 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: linux-kernel

On Fri, Nov 22, 2024 at 01:10:24PM +0100, Peter Zijlstra wrote:
> Reduce read_annotate() runs by collapsing subsequent runs into a
> single call.
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> Link: https://lkml.kernel.org/r/20241111125218.921110073@infradead.org

Stray link?

-- 
Josh

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

* Re: [PATCH 8/9] objtool: Collapse annotate sequences
  2024-11-22 17:57   ` Josh Poimboeuf
@ 2024-11-23 13:09     ` Peter Zijlstra
  0 siblings, 0 replies; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-23 13:09 UTC (permalink / raw)
  To: Josh Poimboeuf; +Cc: linux-kernel

On Fri, Nov 22, 2024 at 09:57:13AM -0800, Josh Poimboeuf wrote:
> On Fri, Nov 22, 2024 at 01:10:24PM +0100, Peter Zijlstra wrote:
> > Reduce read_annotate() runs by collapsing subsequent runs into a
> > single call.
> > 
> > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> > Link: https://lkml.kernel.org/r/20241111125218.921110073@infradead.org
> 
> Stray link?

Gah, yes, Was from the previous posting, I though I'd removed them all.
Gone now.

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

* Re: [PATCH 9/9] objtool: Collect all annotations in objtool.h
  2024-11-22 17:54   ` Josh Poimboeuf
@ 2024-11-23 13:19     ` Peter Zijlstra
  2024-11-25 13:06       ` Peter Zijlstra
  0 siblings, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-23 13:19 UTC (permalink / raw)
  To: Josh Poimboeuf; +Cc: linux-kernel

On Fri, Nov 22, 2024 at 09:54:45AM -0800, Josh Poimboeuf wrote:
> On Fri, Nov 22, 2024 at 01:10:25PM +0100, Peter Zijlstra wrote:
> > +#ifndef __ASSEMBLY__
> > +/*
> > + * Annotate away the various 'relocation to !ENDBR` complaints; knowing that
> > + * these relocations will never be used for indirect calls.
> > + */
> > +#define ANNOTATE_NOENDBR		ASM_ANNOTATE(ANNOTYPE_NOENDBR)
> > +/*
> > + * This should be used immediately before an indirect jump/call. It tells
> > + * objtool the subsequent indirect jump/call is vouched safe for retpoline
> > + * builds.
> > + */
> > +#define ANNOTATE_RETPOLINE_SAFE		ASM_ANNOTATE(ANNOTYPE_RETPOLINE_SAFE)
> > +/*
> > + * objtool annotation to ignore the alternatives and only consider the original
> > + * instruction(s).
> > + */
> > +#define ANNOTATE_IGNORE_ALTERNATIVE	ASM_ANNOTATE(ANNOTYPE_IGNORE_ALTS)
> 
> This is a good start, though it would be really nice to have them *all*
> together:
> 
>   - move ANNOTATE_INTRA_FUNCTION_CALL down next to those ^
> 
>   - similarly, create ANNOTATE_UNRET_BEGIN and just do
> 
>       #define VALIDATE_UNRET_BEGIN ANNOTATE_UNRET_BEGIN
>     
>     since the VALIDATE_* syntax is more descriptive.

Done these two.

>   - create ANNOTATE_INSTR_BEGIN and ANNOTATE_INSTR_END, and then do
>     
>       #define instrumentation_begin() ANNOTATE_INSTR_BEGIN
> 
>     to keep the existing syntax.  Then instrumentation.h is no longer
>     needed.  The nice comment there can go above ANNOTATE_INSTR_BEGIN.

Let me noodle a bit with this one, its a bit different from the rest.

> BTW, is there a reason .discard.[un]reachable weren't converted over?

Completely forgot/missed them. Let me add a patch.

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

* Re: [PATCH 0/9] objtool: Rewrite annotations
  2024-11-22 17:40 ` [PATCH 0/9] objtool: Rewrite annotations Josh Poimboeuf
@ 2024-11-23 13:21   ` Peter Zijlstra
  0 siblings, 0 replies; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-23 13:21 UTC (permalink / raw)
  To: Josh Poimboeuf; +Cc: linux-kernel

On Fri, Nov 22, 2024 at 09:40:56AM -0800, Josh Poimboeuf wrote:
> On Fri, Nov 22, 2024 at 01:10:16PM +0100, Peter Zijlstra wrote:
> > Just the objtool annotation rewrite bits.
> > 
> > Changes since last time:
> > 
> >  - split from the x86 and kvm patches
> >  - s/ANNOTYPE_INTRA_FUNCTION_CALLS/ANNOTYPE_INTRA_FUNCTION_CALL/g
> >  - made __ASM_ANNOTATE() take a full label name (no longer appends 'b')
> >  - added a patch that moves all the annotations to objtool.h
> >  - some changes to the first patch
> 
> For Valentin's thing we'll be adding annotations for static keys.  Those
> will be symbol specific, like STACK_FRAME_NON_STANDARD().  In which case
> we could have a generic .discard.annotate_sym.  And then rename
> .discard.annotate to .discard.annotate_insn?

Done.

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

* Re: [PATCH 1/9] objtool: Generic annotation infrastructure
  2024-11-22 12:10 ` [PATCH 1/9] objtool: Generic annotation infrastructure Peter Zijlstra
@ 2024-11-24  3:16   ` Nathan Chancellor
  2024-11-25  9:28     ` Peter Zijlstra
  0 siblings, 1 reply; 22+ messages in thread
From: Nathan Chancellor @ 2024-11-24  3:16 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: jpoimboe, linux-kernel, Fangrui Song, llvm

On Fri, Nov 22, 2024 at 01:10:17PM +0100, Peter Zijlstra wrote:
> Avoid endless .discard.foo sections for each annotation, create a
> single .discard.annotate section that takes an annotation type along
> with the instruction.
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
...
> --- a/tools/objtool/check.c
> +++ b/tools/objtool/check.c
> @@ -2373,6 +2373,49 @@ static int read_unwind_hints(struct objt
>  	return 0;
>  }
>  
> +static int read_annotate(struct objtool_file *file, void (*func)(int type, struct instruction *insn))
> +{
> +	struct section *sec;
> +	struct instruction *insn;
> +	struct reloc *reloc;
> +	int type;
> +
> +	sec = find_section_by_name(file->elf, ".discard.annotate");
> +	if (!sec)
> +		return 0;
> +
> +	if (!sec->rsec)
> +		return 0;
> +
> +	if (sec->sh.sh_entsize != 8) {
> +		static bool warned = false;
> +		if (!warned) {
> +			WARN("%s: dodgy linker, sh_entsize != 8", sec->name);

Thanks to Fangrui, this has been resolved in LLVM main:

https://github.com/llvm/llvm-project/commit/d4bed617f4378873d7ddf4b53c041e7b39d1a9ca
https://github.com/ClangBuiltLinux/linux/issues/2057#issuecomment-2495675374

I have built a version of LLVM from main and verified that this warning
does not trigger with that version, while it does with LLVM 19.1.4.

> +			warned = true;
> +		}
> +		sec->sh.sh_entsize = 8;
> +	}
> +
> +	for_each_reloc(sec->rsec, reloc) {
> +		type = *(u32 *)(sec->data->d_buf + (reloc_idx(reloc) * sec->sh.sh_entsize) + 4);
> +
> +		insn = find_insn(file, reloc->sym->sec,
> +				 reloc->sym->offset + reloc_addend(reloc));
> +		if (!insn) {
> +			WARN("bad .discard.annotate entry: %d of type %d", reloc_idx(reloc), type);
> +			return -1;
> +		}
> +
> +		func(type, insn);
> +	}
> +
> +	return 0;
> +}

Cheers,
Nathan

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

* Re: [PATCH 1/9] objtool: Generic annotation infrastructure
  2024-11-24  3:16   ` Nathan Chancellor
@ 2024-11-25  9:28     ` Peter Zijlstra
  0 siblings, 0 replies; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-25  9:28 UTC (permalink / raw)
  To: Nathan Chancellor; +Cc: jpoimboe, linux-kernel, Fangrui Song, llvm

On Sat, Nov 23, 2024 at 08:16:40PM -0700, Nathan Chancellor wrote:
> On Fri, Nov 22, 2024 at 01:10:17PM +0100, Peter Zijlstra wrote:
> > Avoid endless .discard.foo sections for each annotation, create a
> > single .discard.annotate section that takes an annotation type along
> > with the instruction.
> > 
> > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> ...
> > --- a/tools/objtool/check.c
> > +++ b/tools/objtool/check.c
> > @@ -2373,6 +2373,49 @@ static int read_unwind_hints(struct objt
> >  	return 0;
> >  }
> >  
> > +static int read_annotate(struct objtool_file *file, void (*func)(int type, struct instruction *insn))
> > +{
> > +	struct section *sec;
> > +	struct instruction *insn;
> > +	struct reloc *reloc;
> > +	int type;
> > +
> > +	sec = find_section_by_name(file->elf, ".discard.annotate");
> > +	if (!sec)
> > +		return 0;
> > +
> > +	if (!sec->rsec)
> > +		return 0;
> > +
> > +	if (sec->sh.sh_entsize != 8) {
> > +		static bool warned = false;
> > +		if (!warned) {
> > +			WARN("%s: dodgy linker, sh_entsize != 8", sec->name);
> 
> Thanks to Fangrui, this has been resolved in LLVM main:
> 
> https://github.com/llvm/llvm-project/commit/d4bed617f4378873d7ddf4b53c041e7b39d1a9ca
> https://github.com/ClangBuiltLinux/linux/issues/2057#issuecomment-2495675374
> 
> I have built a version of LLVM from main and verified that this warning
> does not trigger with that version, while it does with LLVM 19.1.4.

Excellent, thanks for getting this sorted.

Since there's a fair number of llvm releases between the minimally
supported version to build a kernel with and this fix, I'll leave the
warning as non fatal.

One question; is there any other means of setting entsize aside from
(ab)using SHF_MERGE ? The (GNU) as documetation for .section only
mentions entsize in combination with SHF_MERGE.


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

* Re: [PATCH 9/9] objtool: Collect all annotations in objtool.h
  2024-11-23 13:19     ` Peter Zijlstra
@ 2024-11-25 13:06       ` Peter Zijlstra
  2024-11-25 13:40         ` Peter Zijlstra
  0 siblings, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-25 13:06 UTC (permalink / raw)
  To: Josh Poimboeuf; +Cc: linux-kernel

On Sat, Nov 23, 2024 at 02:19:43PM +0100, Peter Zijlstra wrote:

> > BTW, is there a reason .discard.[un]reachable weren't converted over?
> 
> Completely forgot/missed them. Let me add a patch.

So this is turning into a bit of a trainwreck :/

That is, the below works, but I ended up having to include objtool.h
from compiler.h, which is really unfortunate.

--- a/arch/loongarch/include/asm/bug.h
+++ b/arch/loongarch/include/asm/bug.h
@@ -4,6 +4,7 @@
 
 #include <asm/break.h>
 #include <linux/stringify.h>
+#include <linux/objtool.h>
 
 #ifndef CONFIG_DEBUG_BUGVERBOSE
 #define _BUGVERBOSE_LOCATION(file, line)
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -311,7 +311,7 @@ SYM_CODE_END(xen_error_entry)
 	call	\cfunc
 
 	/* For some configurations \cfunc ends up being a noreturn. */
-	REACHABLE
+	ANNOTATE_REACHABLE
 
 	jmp	error_return
 .endm
@@ -532,7 +532,7 @@ SYM_CODE_START(\asmsym)
 	call	\cfunc
 
 	/* For some configurations \cfunc ends up being a noreturn. */
-	REACHABLE
+	ANNOTATE_REACHABLE
 
 	jmp	paranoid_exit
 
--- a/arch/x86/include/asm/bug.h
+++ b/arch/x86/include/asm/bug.h
@@ -92,7 +92,7 @@ do {								\
 do {								\
 	__auto_type __flags = BUGFLAG_WARNING|(flags);		\
 	instrumentation_begin();				\
-	_BUG_FLAGS(ASM_UD2, __flags, ASM_REACHABLE);		\
+	_BUG_FLAGS(ASM_UD2, __flags, ANNOTATE_REACHABLE);	\
 	instrumentation_end();					\
 } while (0)
 
--- a/arch/x86/include/asm/irq_stack.h
+++ b/arch/x86/include/asm/irq_stack.h
@@ -101,7 +101,7 @@
 
 #define ASM_CALL_ARG0							\
 	"call %c[__func]				\n"		\
-	ASM_REACHABLE
+	ANNOTATE_REACHABLE
 
 #define ASM_CALL_ARG1							\
 	"movq	%[arg1], %%rdi				\n"		\
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -3,6 +3,7 @@
 #define __LINUX_COMPILER_H
 
 #include <linux/compiler_types.h>
+#include <linux/objtool.h>
 
 #ifndef __ASSEMBLY__
 
@@ -107,37 +108,10 @@ void ftrace_likely_update(struct ftrace_
 # define barrier_before_unreachable() do { } while (0)
 #endif
 
-/* Unreachable code */
 #ifdef CONFIG_OBJTOOL
-/*
- * These macros help objtool understand GCC code flow for unreachable code.
- * The __COUNTER__ based labels are a hack to make each instance of the macros
- * unique, to convince GCC not to merge duplicate inline asm statements.
- */
-#define __stringify_label(n) #n
-
-#define __annotate_reachable(c) ({					\
-	asm volatile(__stringify_label(c) ":\n\t"			\
-			".pushsection .discard.reachable\n\t"		\
-			".long " __stringify_label(c) "b - .\n\t"	\
-			".popsection\n\t");				\
-})
-#define annotate_reachable() __annotate_reachable(__COUNTER__)
-
-#define __annotate_unreachable(c) ({					\
-	asm volatile(__stringify_label(c) ":\n\t"			\
-		     ".pushsection .discard.unreachable\n\t"		\
-		     ".long " __stringify_label(c) "b - .\n\t"		\
-		     ".popsection\n\t" : : "i" (c));			\
-})
-#define annotate_unreachable() __annotate_unreachable(__COUNTER__)
-
 /* Annotate a C jump table to allow objtool to follow the code flow */
 #define __annotate_jump_table __section(".rodata..c_jump_table,\"a\",@progbits #")
-
 #else /* !CONFIG_OBJTOOL */
-#define annotate_reachable()
-#define annotate_unreachable()
 #define __annotate_jump_table
 #endif /* CONFIG_OBJTOOL */
 
--- a/include/linux/instrumentation.h
+++ b/include/linux/instrumentation.h
@@ -6,12 +6,11 @@
 
 #include <linux/objtool.h>
 #include <linux/stringify.h>
-#include <linux/args.h>
 
 /* Begin/end of an instrumentation safe region */
 #define __instrumentation_begin(c) ({					\
 	asm volatile(__stringify(c) ": nop\n\t"				\
-		     __ASM_ANNOTATE(CONCATENATE(c, b), ANNOTYPE_INSTR_BEGIN)	\
+		     __ASM_ANNOTATE(__ASM_BREF(c), ANNOTYPE_INSTR_BEGIN)\
 		     : : "i" (c));					\
 })
 #define instrumentation_begin() __instrumentation_begin(__COUNTER__)
@@ -49,7 +48,7 @@
  */
 #define __instrumentation_end(c) ({					\
 	asm volatile(__stringify(c) ": nop\n\t"				\
-		     __ASM_ANNOTATE(CONCATENATE(c, b), ANNOTYPE_INSTR_END)		\
+		     __ASM_ANNOTATE(__ASM_BREF(c), ANNOTYPE_INSTR_END)	\
 		     : : "i" (c));					\
 })
 #define instrumentation_end() __instrumentation_end(__COUNTER__)
--- a/include/linux/objtool.h
+++ b/include/linux/objtool.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef _LINUX_OBJTOOL_H
 #define _LINUX_OBJTOOL_H
+#ifndef LINKER_SCRIPT
 
 #include <linux/objtool_types.h>
 
@@ -45,21 +46,19 @@
 #define STACK_FRAME_NON_STANDARD_FP(func)
 #endif
 
-#define ASM_REACHABLE							\
-	"998:\n\t"							\
-	".pushsection .discard.reachable\n\t"				\
-	".long 998b\n\t"						\
-	".popsection\n\t"
-
 #define __ASM_ANNOTATE(s, x)					\
 	".pushsection .discard.annotate_insn,\"M\",@progbits,8\n\t"	\
 	".long " __stringify(s) " - .\n\t"			\
 	".long " __stringify(x) "\n\t"				\
 	".popsection\n\t"
 
-#define ASM_ANNOTATE(x)						\
-	"911:\n\t"						\
-	__ASM_ANNOTATE(911b, x)
+#define __ASM_BREF(s)	s ## b
+
+#define _ASM_ANNOTATE(s, x)					\
+	__stringify(s) ":\n\t"					\
+	__ASM_ANNOTATE(__ASM_BREF(s), x)
+
+#define ASM_ANNOTATE(x)		_ASM_ANNOTATE(__COUNTER__, x)
 
 #else /* __ASSEMBLY__ */
 
@@ -109,14 +108,6 @@
 #endif
 .endm
 
-
-.macro REACHABLE
-.Lhere_\@:
-	.pushsection .discard.reachable
-	.long	.Lhere_\@
-	.popsection
-.endm
-
 .macro ANNOTATE type:req
 .Lhere_\@:
 	.pushsection .discard.annotate_insn,"M",@progbits,8
@@ -135,14 +126,11 @@
 #define STACK_FRAME_NON_STANDARD(func)
 #define STACK_FRAME_NON_STANDARD_FP(func)
 #define ASM_ANNOTATE(x)
-#define ASM_REACHABLE
 #else
 .macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0
 .endm
 .macro STACK_FRAME_NON_STANDARD func:req
 .endm
-.macro REACHABLE
-.endm
 .macro ANNOTATE type:req
 .endm
 #endif
@@ -180,12 +168,17 @@
  */
 #define ANNOTATE_UNRET_BEGIN		ASM_ANNOTATE(ANNOTYPE_UNRET_BEGIN)
 
+#define ANNOTATE_REACHABLE		ASM_ANNOTATE(ANNOTYPE_REACHABLE)
+#define ANNOTATE_UNREACHABLE		ASM_ANNOTATE(ANNOTYPE_UNREACHABLE)
+
 #else
 #define ANNOTATE_NOENDBR		ANNOTATE type=ANNOTYPE_NOENDBR
 #define ANNOTATE_RETPOLINE_SAFE		ANNOTATE type=ANNOTYPE_RETPOLINE_SAFE
 #define ANNOTATE_IGNORE_ALTERNATIVE	ANNOTATE type=ANNOTYPE_IGNORE_ALTS
 #define ANNOTATE_INTRA_FUNCTION_CALL	ANNOTATE type=ANNOTYPE_INTRA_FUNCTION_CALL
 #define ANNOTATE_UNRET_BEGIN		ANNOTATE type=ANNOTYPE_UNRET_BEGIN
+#define ANNOTATE_REACHABLE		ANNOTATE type=ANNOTYPE_REACHABLE
+#define ANNOTATE_UNREACHABLE		ANNOTATE type=ANNOTYPE_UNREACHABLE
 #endif
 
 #if defined(CONFIG_NOINSTR_VALIDATION) && \
@@ -195,4 +188,13 @@
 #define VALIDATE_UNRET_BEGIN
 #endif
 
+#define annotate_reachable() ({			\
+	asm volatile (ANNOTATE_REACHABLE);	\
+})
+
+#define annotate_unreachable() ({		\
+	asm volatile (ANNOTATE_UNREACHABLE);	\
+})
+
+#endif /* LINKER_SCRIPT */
 #endif /* _LINUX_OBJTOOL_H */
--- a/include/linux/objtool_types.h
+++ b/include/linux/objtool_types.h
@@ -64,5 +64,7 @@ struct unwind_hint {
 #define ANNOTYPE_UNRET_BEGIN		5
 #define ANNOTYPE_IGNORE_ALTS		6
 #define ANNOTYPE_INTRA_FUNCTION_CALL	7
+#define ANNOTYPE_REACHABLE		8
+#define ANNOTYPE_UNREACHABLE		9
 
 #endif /* _LINUX_OBJTOOL_TYPES_H */
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -627,95 +627,6 @@ static struct instruction *find_last_ins
 	return insn;
 }
 
-/*
- * Mark "ud2" instructions and manually annotated dead ends.
- */
-static int add_dead_ends(struct objtool_file *file)
-{
-	struct section *rsec;
-	struct reloc *reloc;
-	struct instruction *insn;
-	uint64_t offset;
-
-	/*
-	 * Check for manually annotated dead ends.
-	 */
-	rsec = find_section_by_name(file->elf, ".rela.discard.unreachable");
-	if (!rsec)
-		goto reachable;
-
-	for_each_reloc(rsec, reloc) {
-		if (reloc->sym->type == STT_SECTION) {
-			offset = reloc_addend(reloc);
-		} else if (reloc->sym->local_label) {
-			offset = reloc->sym->offset;
-		} else {
-			WARN("unexpected relocation symbol type in %s", rsec->name);
-			return -1;
-		}
-
-		insn = find_insn(file, reloc->sym->sec, offset);
-		if (insn)
-			insn = prev_insn_same_sec(file, insn);
-		else if (offset == reloc->sym->sec->sh.sh_size) {
-			insn = find_last_insn(file, reloc->sym->sec);
-			if (!insn) {
-				WARN("can't find unreachable insn at %s+0x%" PRIx64,
-				     reloc->sym->sec->name, offset);
-				return -1;
-			}
-		} else {
-			WARN("can't find unreachable insn at %s+0x%" PRIx64,
-			     reloc->sym->sec->name, offset);
-			return -1;
-		}
-
-		insn->dead_end = true;
-	}
-
-reachable:
-	/*
-	 * These manually annotated reachable checks are needed for GCC 4.4,
-	 * where the Linux unreachable() macro isn't supported.  In that case
-	 * GCC doesn't know the "ud2" is fatal, so it generates code as if it's
-	 * not a dead end.
-	 */
-	rsec = find_section_by_name(file->elf, ".rela.discard.reachable");
-	if (!rsec)
-		return 0;
-
-	for_each_reloc(rsec, reloc) {
-		if (reloc->sym->type == STT_SECTION) {
-			offset = reloc_addend(reloc);
-		} else if (reloc->sym->local_label) {
-			offset = reloc->sym->offset;
-		} else {
-			WARN("unexpected relocation symbol type in %s", rsec->name);
-			return -1;
-		}
-
-		insn = find_insn(file, reloc->sym->sec, offset);
-		if (insn)
-			insn = prev_insn_same_sec(file, insn);
-		else if (offset == reloc->sym->sec->sh.sh_size) {
-			insn = find_last_insn(file, reloc->sym->sec);
-			if (!insn) {
-				WARN("can't find reachable insn at %s+0x%" PRIx64,
-				     reloc->sym->sec->name, offset);
-				return -1;
-			}
-		} else {
-			WARN("can't find reachable insn at %s+0x%" PRIx64,
-			     reloc->sym->sec->name, offset);
-			return -1;
-		}
-
-		insn->dead_end = false;
-	}
-
-	return 0;
-}
-
 static int create_static_call_sections(struct objtool_file *file)
 {
 	struct static_call_site *site;
@@ -2345,6 +2256,7 @@ static int read_annotate(struct objtool_
 	struct section *sec;
 	struct instruction *insn;
 	struct reloc *reloc;
+	uint64_t offset;
 	int type, ret;
 
 	sec = find_section_by_name(file->elf, ".discard.annotate_insn");
@@ -2366,8 +2278,19 @@ static int read_annotate(struct objtool_
 	for_each_reloc(sec->rsec, reloc) {
 		type = *(u32 *)(sec->data->d_buf + (reloc_idx(reloc) * sec->sh.sh_entsize) + 4);
 
-		insn = find_insn(file, reloc->sym->sec,
-				 reloc->sym->offset + reloc_addend(reloc));
+		offset = reloc->sym->offset + reloc_addend(reloc);
+		insn = find_insn(file, reloc->sym->sec, offset);
+
+		/*
+		 * Reachable annotations are 'funneh' and act on the previous instruction :/
+		 */
+		if (type == ANNOTYPE_REACHABLE || type == ANNOTYPE_UNREACHABLE) {
+			if (insn)
+				insn = prev_insn_same_sec(file, insn);
+			else if (offset == reloc->sym->sec->sh.sh_size)
+				insn = find_last_insn(file, reloc->sym->sec);
+		}
+
 		if (!insn) {
 			WARN("bad .discard.annotate_insn entry: %d of type %d", reloc_idx(reloc), type);
 			return -1;
@@ -2459,6 +2382,14 @@ static int __annotate_late(struct objtoo
 		insn->unret = 1;
 		break;
 
+	case ANNOTYPE_REACHABLE:
+		insn->dead_end = false;
+		break;
+
+	case ANNOTYPE_UNREACHABLE:
+		insn->dead_end = true;
+		break;
+
 	default:
 		break;
 	}
@@ -2605,14 +2536,6 @@ static int decode_sections(struct objtoo
 	if (ret)
 		return ret;
 
-	/*
-	 * Must be after add_call_destinations() such that it can override
-	 * dead_end_function() marks.
-	 */
-	ret = add_dead_ends(file);
-	if (ret)
-		return ret;
-
 	ret = add_jump_table_alts(file);
 	if (ret)
 		return ret;
@@ -2621,6 +2544,10 @@ static int decode_sections(struct objtoo
 	if (ret)
 		return ret;
 
+	/*
+	 * Must be after add_call_destinations() such that it can override
+	 * dead_end_function() marks.
+	 */
 	ret = read_annotate(file, __annotate_late);
 	if (ret)
 		return ret;

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

* Re: [PATCH 9/9] objtool: Collect all annotations in objtool.h
  2024-11-25 13:06       ` Peter Zijlstra
@ 2024-11-25 13:40         ` Peter Zijlstra
  2024-11-25 14:36           ` Peter Zijlstra
  0 siblings, 1 reply; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-25 13:40 UTC (permalink / raw)
  To: Josh Poimboeuf; +Cc: linux-kernel

On Mon, Nov 25, 2024 at 02:06:13PM +0100, Peter Zijlstra wrote:
> On Sat, Nov 23, 2024 at 02:19:43PM +0100, Peter Zijlstra wrote:
> 
> > > BTW, is there a reason .discard.[un]reachable weren't converted over?
> > 
> > Completely forgot/missed them. Let me add a patch.
> 
> So this is turning into a bit of a trainwreck :/
> 
> That is, the below works, but I ended up having to include objtool.h
> from compiler.h, which is really unfortunate.

Or rather, I suppose I can move unreachable() into objtool.h (or another
header entirely) and go include it from all the various files that call
it.

Only ~70 files.

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

* Re: [PATCH 9/9] objtool: Collect all annotations in objtool.h
  2024-11-25 13:40         ` Peter Zijlstra
@ 2024-11-25 14:36           ` Peter Zijlstra
  0 siblings, 0 replies; 22+ messages in thread
From: Peter Zijlstra @ 2024-11-25 14:36 UTC (permalink / raw)
  To: Josh Poimboeuf; +Cc: linux-kernel

On Mon, Nov 25, 2024 at 02:40:05PM +0100, Peter Zijlstra wrote:
> On Mon, Nov 25, 2024 at 02:06:13PM +0100, Peter Zijlstra wrote:
> > On Sat, Nov 23, 2024 at 02:19:43PM +0100, Peter Zijlstra wrote:
> > 
> > > > BTW, is there a reason .discard.[un]reachable weren't converted over?
> > > 
> > > Completely forgot/missed them. Let me add a patch.
> > 
> > So this is turning into a bit of a trainwreck :/
> > 
> > That is, the below works, but I ended up having to include objtool.h
> > from compiler.h, which is really unfortunate.
> 
> Or rather, I suppose I can move unreachable() into objtool.h (or another
> header entirely) and go include it from all the various files that call
> it.
> 
> Only ~70 files.

OK, done that. Fed it to the robot, lets see what comes apart.

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

end of thread, other threads:[~2024-11-25 14:36 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-22 12:10 [PATCH 0/9] objtool: Rewrite annotations Peter Zijlstra
2024-11-22 12:10 ` [PATCH 1/9] objtool: Generic annotation infrastructure Peter Zijlstra
2024-11-24  3:16   ` Nathan Chancellor
2024-11-25  9:28     ` Peter Zijlstra
2024-11-22 12:10 ` [PATCH 2/9] objtool: Convert ANNOTATE_NOENDBR to ANNOTATE Peter Zijlstra
2024-11-22 12:10 ` [PATCH 3/9] objtool: Convert ANNOTATE_RETPOLINE_SAFE " Peter Zijlstra
2024-11-22 12:10 ` [PATCH 4/9] objtool: Convert instrumentation_{begin,end}() " Peter Zijlstra
2024-11-22 12:10 ` [PATCH 5/9] objtool: Convert VALIDATE_UNRET_BEGIN " Peter Zijlstra
2024-11-22 12:10 ` [PATCH 6/9] objtool: Convert ANNOTATE_IGNORE_ALTERNATIVE " Peter Zijlstra
2024-11-22 12:10 ` [PATCH 7/9] objtool: Convert ANNOTATE_INTRA_FUNCTION_CALLS " Peter Zijlstra
2024-11-22 17:22   ` Josh Poimboeuf
2024-11-22 12:10 ` [PATCH 8/9] objtool: Collapse annotate sequences Peter Zijlstra
2024-11-22 17:57   ` Josh Poimboeuf
2024-11-23 13:09     ` Peter Zijlstra
2024-11-22 12:10 ` [PATCH 9/9] objtool: Collect all annotations in objtool.h Peter Zijlstra
2024-11-22 17:54   ` Josh Poimboeuf
2024-11-23 13:19     ` Peter Zijlstra
2024-11-25 13:06       ` Peter Zijlstra
2024-11-25 13:40         ` Peter Zijlstra
2024-11-25 14:36           ` Peter Zijlstra
2024-11-22 17:40 ` [PATCH 0/9] objtool: Rewrite annotations Josh Poimboeuf
2024-11-23 13:21   ` Peter Zijlstra

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