]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.16.4/powerpc-lib-fix-off-by-one-in-alternate-feature-patching.patch
Fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 4.16.4 / powerpc-lib-fix-off-by-one-in-alternate-feature-patching.patch
CommitLineData
2bb7416c
GKH
1From b8858581febb050688e276b956796bc4a78299ed Mon Sep 17 00:00:00 2001
2From: Michael Ellerman <mpe@ellerman.id.au>
3Date: Mon, 16 Apr 2018 23:25:19 +1000
4Subject: powerpc/lib: Fix off-by-one in alternate feature patching
5
6From: Michael Ellerman <mpe@ellerman.id.au>
7
8commit b8858581febb050688e276b956796bc4a78299ed upstream.
9
10When we patch an alternate feature section, we have to adjust any
11relative branches that branch out of the alternate section.
12
13But currently we have a bug if we have a branch that points to past
14the last instruction of the alternate section, eg:
15
16 FTR_SECTION_ELSE
17 1: b 2f
18 or 6,6,6
19 2:
20 ALT_FTR_SECTION_END(...)
21 nop
22
23This will result in a relative branch at 1 with a target that equals
24the end of the alternate section.
25
26That branch does not need adjusting when it's moved to the non-else
27location. Currently we do adjust it, resulting in a branch that goes
28off into the link-time location of the else section, which is junk.
29
30The fix is to not patch branches that have a target == end of the
31alternate section.
32
33Fixes: d20fe50a7b3c ("KVM: PPC: Book3S HV: Branch inside feature section")
34Fixes: 9b1a735de64c ("powerpc: Add logic to patch alternative feature sections")
35Cc: stable@vger.kernel.org # v2.6.27+
36Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
37Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
38
39---
40 arch/powerpc/lib/feature-fixups.c | 2 +-
41 1 file changed, 1 insertion(+), 1 deletion(-)
42
43--- a/arch/powerpc/lib/feature-fixups.c
44+++ b/arch/powerpc/lib/feature-fixups.c
45@@ -55,7 +55,7 @@ static int patch_alt_instruction(unsigne
46 unsigned int *target = (unsigned int *)branch_target(src);
47
48 /* Branch within the section doesn't need translating */
49- if (target < alt_start || target >= alt_end) {
50+ if (target < alt_start || target > alt_end) {
51 instr = translate_branch(dest, src);
52 if (!instr)
53 return 1;