Skip to content
Snippets Groups Projects
Commit 668f513a authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Yang Yingliang
Browse files

arm64/alternatives: don't patch up internal branches


stable inclusion
from linux-4.19.134
commit 47fed9aa3fe0838eee41cb4f94c386aa18729b9e

--------------------------------

[ Upstream commit 5679b281 ]

Commit f7b93d42 ("arm64/alternatives: use subsections for replacement
sequences") moved the alternatives replacement sequences into subsections,
in order to keep the as close as possible to the code that they replace.

Unfortunately, this broke the logic in branch_insn_requires_update,
which assumed that any branch into kernel executable code was a branch
that required updating, which is no longer the case now that the code
sequences that are patched in are in the same section as the patch site
itself.

So the only way to discriminate branches that require updating and ones
that don't is to check whether the branch targets the replacement sequence
itself, and so we can drop the call to kernel_text_address() entirely.

Fixes: f7b93d42 ("arm64/alternatives: use subsections for replacement sequences")
Reported-by: default avatarAlexandru Elisei <alexandru.elisei@arm.com>
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
Tested-by: default avatarAlexandru Elisei <alexandru.elisei@arm.com>
Link: https://lore.kernel.org/r/20200709125953.30918-1-ardb@kernel.org


Signed-off-by: default avatarWill Deacon <will@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parent 2b69cb40
No related branches found
No related tags found
No related merge requests found
......@@ -54,20 +54,8 @@ bool alternative_is_applied(u16 cpufeature)
*/
static bool branch_insn_requires_update(struct alt_instr *alt, unsigned long pc)
{
unsigned long replptr;
if (kernel_text_address(pc))
return true;
replptr = (unsigned long)ALT_REPL_PTR(alt);
if (pc >= replptr && pc <= (replptr + alt->alt_len))
return false;
/*
* Branching into *another* alternate sequence is doomed, and
* we're not even trying to fix it up.
*/
BUG();
unsigned long replptr = (unsigned long)ALT_REPL_PTR(alt);
return !(pc >= replptr && pc <= (replptr + alt->alt_len));
}
#define align_down(x, a) ((unsigned long)(x) & ~(((unsigned long)(a)) - 1))
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment