* [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