Commit b8858581 authored by Michael Ellerman's avatar Michael Ellerman

powerpc/lib: Fix off-by-one in alternate feature patching

When we patch an alternate feature section, we have to adjust any
relative branches that branch out of the alternate section.

But currently we have a bug if we have a branch that points to past
the last instruction of the alternate section, eg:

  FTR_SECTION_ELSE
  1:     b       2f
         or      6,6,6
  2:
  ALT_FTR_SECTION_END(...)
         nop

This will result in a relative branch at 1 with a target that equals
the end of the alternate section.

That branch does not need adjusting when it's moved to the non-else
location. Currently we do adjust it, resulting in a branch that goes
off into the link-time location of the else section, which is junk.

The fix is to not patch branches that have a target == end of the
alternate section.

Fixes: d20fe50a ("KVM: PPC: Book3S HV: Branch inside feature section")
Fixes: 9b1a735d ("powerpc: Add logic to patch alternative feature sections")
Cc: stable@vger.kernel.org # v2.6.27+
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 60cc43fc
...@@ -55,7 +55,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest, ...@@ -55,7 +55,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
unsigned int *target = (unsigned int *)branch_target(src); unsigned int *target = (unsigned int *)branch_target(src);
/* Branch within the section doesn't need translating */ /* Branch within the section doesn't need translating */
if (target < alt_start || target >= alt_end) { if (target < alt_start || target > alt_end) {
instr = translate_branch(dest, src); instr = translate_branch(dest, src);
if (!instr) if (!instr)
return 1; return 1;
......
Markdown is supported
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