From: Peter Zijlstra <peterz@infradead.org>
To: jpoimboe@redhat.com, alexandre.chartre@oracle.com
Cc: linux-kernel@vger.kernel.org, jthierry@redhat.com,
tglx@linutronix.de, x86@kernel.org, peterz@infradead.org
Subject: [RFC][PATCH 3/7] objtool: Allow branches within the same alternative.
Date: Thu, 16 Apr 2020 17:07:55 +0200 [thread overview]
Message-ID: <20200416151024.885221682@infradead.org> (raw)
In-Reply-To: <20200416150752.569029800@infradead.org>
From: Alexandre Chartre <alexandre.chartre@oracle.com>
Currently objtool prevents any branch to an alternative. While preventing
branching from the outside to the middle of an alternative makes perfect
sense, branching within the same alternative should be allowed. To do so,
identify each alternative and check that a branch to an alternative comes
from the same alternative.
Signed-off-by: Alexandre Chartre <alexandre.chartre@oracle.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20200414103618.12657-3-alexandre.chartre@oracle.com
---
tools/objtool/check.c | 27 +++++++++++++++++++++------
tools/objtool/check.h | 3 ++-
2 files changed, 23 insertions(+), 7 deletions(-)
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -768,7 +768,9 @@ static int handle_group_alt(struct objto
struct instruction *orig_insn,
struct instruction **new_insn)
{
+ static unsigned int alt_group_next_index = 1;
struct instruction *last_orig_insn, *last_new_insn, *insn, *fake_jump = NULL;
+ unsigned int alt_group = alt_group_next_index++;
unsigned long dest_off;
last_orig_insn = NULL;
@@ -777,7 +779,7 @@ static int handle_group_alt(struct objto
if (insn->offset >= special_alt->orig_off + special_alt->orig_len)
break;
- insn->alt_group = true;
+ insn->alt_group = alt_group;
last_orig_insn = insn;
}
@@ -811,6 +813,7 @@ static int handle_group_alt(struct objto
}
last_new_insn = NULL;
+ alt_group = alt_group_next_index++;
insn = *new_insn;
sec_for_each_insn_from(file, insn) {
if (insn->offset >= special_alt->new_off + special_alt->new_len)
@@ -820,6 +823,7 @@ static int handle_group_alt(struct objto
insn->ignore = orig_insn->ignore_alts;
insn->func = orig_insn->func;
+ insn->alt_group = alt_group;
/*
* Since alternative replacement code is copy/pasted by the
@@ -2157,6 +2161,15 @@ static int validate_return(struct symbol
return 0;
}
+static bool is_branch_to_alternative(struct instruction *from,
+ struct instruction *to)
+{
+ if (!from || !to->alt_group || !list_empty(&to->alts))
+ return false;
+
+ return (from->alt_group != to->alt_group);
+}
+
/*
* Follow the branch starting at the given instruction, and recursively follow
* any other branches (jumps). Meanwhile, track the frame pointer state at
@@ -2164,6 +2177,7 @@ static int validate_return(struct symbol
* tools/objtool/Documentation/stack-validation.txt.
*/
static int validate_branch(struct objtool_file *file, struct symbol *func,
+ struct instruction *from,
struct instruction *insn, struct insn_state state)
{
struct alternative *alt;
@@ -2174,7 +2188,7 @@ static int validate_branch(struct objtoo
sec = insn->sec;
- if (insn->alt_group && list_empty(&insn->alts)) {
+ if (is_branch_to_alternative(from, insn)) {
WARN_FUNC("don't know how to handle branch to middle of alternative instruction group",
sec, insn->offset);
return 1;
@@ -2221,7 +2235,8 @@ static int validate_branch(struct objtoo
if (alt->skip_orig)
skip_orig = true;
- ret = validate_branch(file, func, alt->insn, state);
+ ret = validate_branch(file, func,
+ NULL, alt->insn, state);
if (ret) {
if (backtrace)
BT_FUNC("(alt)", insn);
@@ -2264,7 +2279,7 @@ static int validate_branch(struct objtoo
return ret;
} else if (insn->jump_dest) {
- ret = validate_branch(file, func,
+ ret = validate_branch(file, func, insn,
insn->jump_dest, state);
if (ret) {
if (backtrace)
@@ -2396,7 +2411,7 @@ static int validate_unwind_hints(struct
while (&insn->list != &file->insn_list && (!sec || insn->sec == sec)) {
if (insn->hint && !insn->visited) {
- ret = validate_branch(file, insn->func, insn, state);
+ ret = validate_branch(file, insn->func, NULL, insn, state);
if (ret && backtrace)
BT_FUNC("<=== (hint)", insn);
warnings += ret;
@@ -2537,7 +2552,7 @@ static int validate_symbol(struct objtoo
state->uaccess = sym->uaccess_safe;
- ret = validate_branch(file, insn->func, insn, *state);
+ ret = validate_branch(file, insn->func, NULL, insn, *state);
if (ret && backtrace)
BT_FUNC("<=== (sym)", insn);
return ret;
--- a/tools/objtool/check.h
+++ b/tools/objtool/check.h
@@ -30,7 +30,8 @@ struct instruction {
unsigned int len;
enum insn_type type;
unsigned long immediate;
- bool alt_group, dead_end, ignore, ignore_alts;
+ int alt_group;
+ bool dead_end, ignore, ignore_alts;
bool hint;
bool retpoline_safe;
s8 instr;
next prev parent reply other threads:[~2020-04-16 15:12 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-16 15:07 [RFC][PATCH 0/7] objtool vs retpoline Peter Zijlstra
2020-04-16 15:07 ` [RFC][PATCH 1/7] objtool: is_fentry_call() crashes if call has no destination Peter Zijlstra
2020-04-16 15:07 ` [RFC][PATCH 2/7] objtool: UNWIND_HINT_RET_OFFSET should not check registers Peter Zijlstra
2020-04-16 15:07 ` Peter Zijlstra [this message]
2020-04-19 16:32 ` [RFC][PATCH 3/7] objtool: Allow branches within the same alternative Josh Poimboeuf
2020-04-19 19:27 ` Peter Zijlstra
2020-04-16 15:07 ` [RFC][PATCH 4/7] objtool: Add support for intra-function calls Peter Zijlstra
2020-04-19 16:41 ` Josh Poimboeuf
2020-04-23 11:40 ` Peter Zijlstra
2020-04-16 15:07 ` [RFC][PATCH 5/7] x86/speculation: Change __FILL_RETURN_BUFFER to work with objtool Peter Zijlstra
2020-04-19 16:51 ` Josh Poimboeuf
2020-04-19 16:55 ` Josh Poimboeuf
2020-04-19 18:58 ` Peter Zijlstra
2020-04-16 15:07 ` [RFC][PATCH 6/7] x86/retpoline: Out-of-line retpoline Peter Zijlstra
2020-04-16 15:22 ` Peter Zijlstra
2020-04-16 15:07 ` [RFC][PATCH 7/7] x86/nospec: Remove ANNOTATE_NOSPEC_ALTERNATIVE Peter Zijlstra
2020-04-16 15:32 ` [RFC][PATCH 0/7] objtool vs retpoline Peter Zijlstra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200416151024.885221682@infradead.org \
--to=peterz@infradead.org \
--cc=alexandre.chartre@oracle.com \
--cc=jpoimboe@redhat.com \
--cc=jthierry@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome