lkml.org 
[lkml]   [2018]   [Oct]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 35/45] powerpc/lib: fix book3s/32 boot failure due to code patching
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

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

    From: Christophe Leroy <christophe.leroy@c-s.fr>

    commit b45ba4a51cde29b2939365ef0c07ad34c8321789 upstream.

    Commit 51c3c62b58b3 ("powerpc: Avoid code patching freed init
    sections") accesses 'init_mem_is_free' flag too early, before the
    kernel is relocated. This provokes early boot failure (before the
    console is active).

    As it is not necessary to do this verification that early, this
    patch moves the test into patch_instruction() instead of
    __patch_instruction().

    This modification also has the advantage of avoiding unnecessary
    remappings.

    Fixes: 51c3c62b58b3 ("powerpc: Avoid code patching freed init sections")
    Cc: stable@vger.kernel.org # 4.13+
    Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/powerpc/lib/code-patching.c | 20 ++++++++++++--------
    1 file changed, 12 insertions(+), 8 deletions(-)

    --- a/arch/powerpc/lib/code-patching.c
    +++ b/arch/powerpc/lib/code-patching.c
    @@ -28,12 +28,6 @@ static int __patch_instruction(unsigned
    {
    int err;

    - /* Make sure we aren't patching a freed init section */
    - if (init_mem_is_free && init_section_contains(exec_addr, 4)) {
    - pr_debug("Skipping init section patching addr: 0x%px\n", exec_addr);
    - return 0;
    - }
    -
    __put_user_size(instr, patch_addr, 4, err);
    if (err)
    return err;
    @@ -148,7 +142,7 @@ static inline int unmap_patch_area(unsig
    return 0;
    }

    -int patch_instruction(unsigned int *addr, unsigned int instr)
    +static int do_patch_instruction(unsigned int *addr, unsigned int instr)
    {
    int err;
    unsigned int *patch_addr = NULL;
    @@ -188,12 +182,22 @@ out:
    }
    #else /* !CONFIG_STRICT_KERNEL_RWX */

    -int patch_instruction(unsigned int *addr, unsigned int instr)
    +static int do_patch_instruction(unsigned int *addr, unsigned int instr)
    {
    return raw_patch_instruction(addr, instr);
    }

    #endif /* CONFIG_STRICT_KERNEL_RWX */
    +
    +int patch_instruction(unsigned int *addr, unsigned int instr)
    +{
    + /* Make sure we aren't patching a freed init section */
    + if (init_mem_is_free && init_section_contains(addr, 4)) {
    + pr_debug("Skipping init section patching addr: 0x%px\n", addr);
    + return 0;
    + }
    + return do_patch_instruction(addr, instr);
    +}
    NOKPROBE_SYMBOL(patch_instruction);

    int patch_branch(unsigned int *addr, unsigned long target, int flags)

    \
     
     \ /
      Last update: 2018-10-11 17:53    [W:4.160 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site