--- /dev/null
+From fbe82156997416d75ee65f80ede3be5e0c0ff6b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jul 2020 15:59:53 +0300
+Subject: arm64/alternatives: don't patch up internal branches
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+[ Upstream commit 5679b28142193a62f6af93249c0477be9f0c669b ]
+
+Commit f7b93d42945c ("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: f7b93d42945c ("arm64/alternatives: use subsections for replacement sequences")
+Reported-by: Alexandru Elisei <alexandru.elisei@arm.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Tested-by: Alexandru Elisei <alexandru.elisei@arm.com>
+Link: https://lore.kernel.org/r/20200709125953.30918-1-ardb@kernel.org
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/alternative.c | 16 ++--------------
+ 1 file changed, 2 insertions(+), 14 deletions(-)
+
+diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c
+index d1757ef1b1e74..73039949b5ce2 100644
+--- a/arch/arm64/kernel/alternative.c
++++ b/arch/arm64/kernel/alternative.c
+@@ -43,20 +43,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))
+--
+2.25.1
+