diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-04-10 07:12:27 -1000 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-04-10 07:12:27 -1000 |
commit | 9c6913b7499cca943776cb0b02ea282113625580 (patch) | |
tree | 31dd18a1e133af6e1182bbdf3b92f305bfc978ee /tools | |
parent | b51f86e9900ab1ff05fb5674c17fd3cb858c4500 (diff) | |
parent | 59b18a1e65b7a2134814106d0860010e10babe18 (diff) |
Merge tag 'x86_urgent_for_v5.18_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Borislav Petkov:
- Fix the MSI message data struct definition
- Use local labels in the exception table macros to avoid symbol
conflicts with clang LTO builds
- A couple of fixes to objtool checking of the relatively newly added
SLS and IBT code
- Rename a local var in the WARN* macro machinery to prevent shadowing
* tag 'x86_urgent_for_v5.18_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/msi: Fix msi message data shadow struct
x86/extable: Prefer local labels in .set directives
x86,bpf: Avoid IBT objtool warning
objtool: Fix SLS validation for kcov tail-call replacement
objtool: Fix IBT tail-call detection
x86/bug: Prevent shadowing in __WARN_FLAGS
x86/mm/tlb: Revert retpoline avoidance approach
Diffstat (limited to 'tools')
-rw-r--r-- | tools/objtool/check.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 6de5085e3e5a..bd0c2c828940 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1155,6 +1155,17 @@ static void annotate_call_site(struct objtool_file *file, : arch_nop_insn(insn->len)); insn->type = sibling ? INSN_RETURN : INSN_NOP; + + if (sibling) { + /* + * We've replaced the tail-call JMP insn by two new + * insn: RET; INT3, except we only have a single struct + * insn here. Mark it retpoline_safe to avoid the SLS + * warning, instead of adding another insn. + */ + insn->retpoline_safe = true; + } + return; } @@ -1239,11 +1250,20 @@ static bool same_function(struct instruction *insn1, struct instruction *insn2) return insn1->func->pfunc == insn2->func->pfunc; } -static bool is_first_func_insn(struct instruction *insn) +static bool is_first_func_insn(struct objtool_file *file, struct instruction *insn) { - return insn->offset == insn->func->offset || - (insn->type == INSN_ENDBR && - insn->offset == insn->func->offset + insn->len); + if (insn->offset == insn->func->offset) + return true; + + if (ibt) { + struct instruction *prev = prev_insn_same_sym(file, insn); + + if (prev && prev->type == INSN_ENDBR && + insn->offset == insn->func->offset + prev->len) + return true; + } + + return false; } /* @@ -1327,7 +1347,7 @@ static int add_jump_destinations(struct objtool_file *file) insn->jump_dest->func->pfunc = insn->func; } else if (!same_function(insn, insn->jump_dest) && - is_first_func_insn(insn->jump_dest)) { + is_first_func_insn(file, insn->jump_dest)) { /* internal sibling call (without reloc) */ add_call_dest(file, insn, insn->jump_dest->func, true); } |