• Michael Ellerman's avatar
    powerpc/modules: Never restore r2 for a mprofile-kernel style mcount() call · 31278b17
    Michael Ellerman authored
    In the module loader we process relocations, and for long jumps we
    generate trampolines (aka stubs). At the call site for one of these
    trampolines we usually need to generate a load instruction to restore
    the TOC pointer into r2.
    
    There is one exception however, which is calls to mcount() using the
    mprofile-kernel ABI, they handle the TOC inside the stub, and so for
    them we do not generate a TOC load.
    
    The bug is in how the code in restore_r2() decides if it needs to
    generate the TOC load. It does so by looking for a nop following the
    branch, and if it sees a nop, it replaces it with the load. In general
    the compiler has no reason to generate a nop following the mcount()
    call and so that check works OK.
    
    However if we combine a jump label at the start of a function, with an
    early return, such that GCC applies the shrink-wrapping optimisation, we
    can then end up with an mcount call followed immediately by a nop.
    However the nop is not there for a TOC load, it is for the jump label.
    
    That confuses restore_r2() into replacing the jump label nop with a TOC
    load, which in turn confuses ftrace into replacing the mcount call with
    a b +8 (fixed in the previous commit). The end result is we jump over
    the jump label, which if it was supposed to return means we incorrectly
    run the body of the function.
    
    We have seen this in practice with some yet-to-be-merged patches that
    use jump labels more extensively.
    
    The fix is relatively simple, in restore_r2() we check for an
    mprofile-kernel style mcount() call first, before looking for the
    presence of a nop.
    
    Fixes: 15308664 ("powerpc/ftrace: Add support for -mprofile-kernel ftrace ABI")
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    31278b17
module_64.c 22.1 KB