lkml.org 
[lkml]   [2018]   [Apr]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 84/95] powerpc/lib: Fix off-by-one in alternate feature patching
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

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

    From: Michael Ellerman <mpe@ellerman.id.au>

    commit b8858581febb050688e276b956796bc4a78299ed upstream.

    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: d20fe50a7b3c ("KVM: PPC: Book3S HV: Branch inside feature section")
    Fixes: 9b1a735de64c ("powerpc: Add logic to patch alternative feature sections")
    Cc: stable@vger.kernel.org # v2.6.27+
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/powerpc/lib/feature-fixups.c | 2 +-
    1 file changed, 1 insertion(+), 1 deletion(-)

    --- a/arch/powerpc/lib/feature-fixups.c
    +++ b/arch/powerpc/lib/feature-fixups.c
    @@ -55,7 +55,7 @@ static int patch_alt_instruction(unsigne
    unsigned int *target = (unsigned int *)branch_target(src);

    /* 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);
    if (!instr)
    return 1;

    \
     
     \ /
      Last update: 2018-04-22 16:15    [W:2.642 / U:0.084 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site