lkml.org 
[lkml]   [2018]   [May]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.16 059/161] s390/ftrace: use expoline for indirect branches
    Date
    4.16-stable review patch.  If anyone has any objections, please let me know.

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

    From: Martin Schwidefsky <schwidefsky@de.ibm.com>

    [ Upstream commit 23a4d7fd34856da8218c4cfc23dba7a6ec0a423a ]

    The return from the ftrace_stub, _mcount, ftrace_caller and
    return_to_handler functions is done with "br %r14" and "br %r1".
    These are indirect branches as well and need to use execute
    trampolines for CONFIG_EXPOLINE=y.

    The ftrace_caller function is a special case as it returns to the
    start of a function and may only use %r0 and %r1. For a pre z10
    machine the standard execute trampoline uses a LARL + EX to do
    this, but this requires *two* registers in the range %r1..%r15.
    To get around this the 'br %r1' located in the lowcore is used,
    then the EX instruction does not need an address register.
    But the lowcore trick may only be used for pre z14 machines,
    with noexec=on the mapping for the first page may not contain
    instructions. The solution for that is an ALTERNATIVE in the
    expoline THUNK generated by 'GEN_BR_THUNK %r1' to switch to
    EXRL, this relies on the fact that a machine that supports
    noexec=on has EXRL as well.

    Cc: stable@vger.kernel.org # 4.16
    Fixes: f19fbd5ed6 ("s390: introduce execute-trampolines for branches")
    Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    arch/s390/include/asm/nospec-insn.h | 12 ++++++++++++
    arch/s390/kernel/asm-offsets.c | 1 +
    arch/s390/kernel/mcount.S | 14 +++++++++-----
    3 files changed, 22 insertions(+), 5 deletions(-)

    --- a/arch/s390/include/asm/nospec-insn.h
    +++ b/arch/s390/include/asm/nospec-insn.h
    @@ -2,12 +2,16 @@
    #ifndef _ASM_S390_NOSPEC_ASM_H
    #define _ASM_S390_NOSPEC_ASM_H

    +#include <asm/alternative-asm.h>
    +#include <asm/asm-offsets.h>
    #include <asm/dwarf.h>

    #ifdef __ASSEMBLY__

    #ifdef CONFIG_EXPOLINE

    +_LC_BR_R1 = __LC_BR_R1
    +
    /*
    * The expoline macros are used to create thunks in the same format
    * as gcc generates them. The 'comdat' section flag makes sure that
    @@ -78,13 +82,21 @@
    .endm

    .macro __THUNK_EX_BR reg,ruse
    + # Be very careful when adding instructions to this macro!
    + # The ALTERNATIVE replacement code has a .+10 which targets
    + # the "br \reg" after the code has been patched.
    #ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
    exrl 0,555f
    j .
    #else
    + .ifc \reg,%r1
    + ALTERNATIVE "ex %r0,_LC_BR_R1", ".insn ril,0xc60000000000,0,.+10", 35
    + j .
    + .else
    larl \ruse,555f
    ex 0,0(\ruse)
    j .
    + .endif
    #endif
    555: br \reg
    .endm
    --- a/arch/s390/kernel/asm-offsets.c
    +++ b/arch/s390/kernel/asm-offsets.c
    @@ -179,6 +179,7 @@ int main(void)
    OFFSET(__LC_MACHINE_FLAGS, lowcore, machine_flags);
    OFFSET(__LC_PREEMPT_COUNT, lowcore, preempt_count);
    OFFSET(__LC_GMAP, lowcore, gmap);
    + OFFSET(__LC_BR_R1, lowcore, br_r1_trampoline);
    /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */
    OFFSET(__LC_DUMP_REIPL, lowcore, ipib);
    /* hardware defined lowcore locations 0x1000 - 0x18ff */
    --- a/arch/s390/kernel/mcount.S
    +++ b/arch/s390/kernel/mcount.S
    @@ -9,13 +9,17 @@
    #include <linux/linkage.h>
    #include <asm/asm-offsets.h>
    #include <asm/ftrace.h>
    +#include <asm/nospec-insn.h>
    #include <asm/ptrace.h>
    #include <asm/export.h>

    + GEN_BR_THUNK %r1
    + GEN_BR_THUNK %r14
    +
    .section .kprobes.text, "ax"

    ENTRY(ftrace_stub)
    - br %r14
    + BR_EX %r14

    #define STACK_FRAME_SIZE (STACK_FRAME_OVERHEAD + __PT_SIZE)
    #define STACK_PTREGS (STACK_FRAME_OVERHEAD)
    @@ -23,7 +27,7 @@ ENTRY(ftrace_stub)
    #define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW)

    ENTRY(_mcount)
    - br %r14
    + BR_EX %r14

    EXPORT_SYMBOL(_mcount)

    @@ -53,7 +57,7 @@ ENTRY(ftrace_caller)
    #endif
    lgr %r3,%r14
    la %r5,STACK_PTREGS(%r15)
    - basr %r14,%r1
    + BASR_EX %r14,%r1
    #ifdef CONFIG_FUNCTION_GRAPH_TRACER
    # The j instruction gets runtime patched to a nop instruction.
    # See ftrace_enable_ftrace_graph_caller.
    @@ -68,7 +72,7 @@ ftrace_graph_caller_end:
    #endif
    lg %r1,(STACK_PTREGS_PSW+8)(%r15)
    lmg %r2,%r15,(STACK_PTREGS_GPRS+2*8)(%r15)
    - br %r1
    + BR_EX %r1

    #ifdef CONFIG_FUNCTION_GRAPH_TRACER

    @@ -81,6 +85,6 @@ ENTRY(return_to_handler)
    aghi %r15,STACK_FRAME_OVERHEAD
    lgr %r14,%r2
    lmg %r2,%r5,32(%r15)
    - br %r14
    + BR_EX %r14

    #endif

    \
     
     \ /
      Last update: 2018-05-24 12:02    [W:3.900 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site