s390: move expoline assembler macros to a header
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 20 Apr 2018 14:49:46 +0000 (16:49 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 7 May 2018 07:07:32 +0000 (09:07 +0200)
To be able to use the expoline branches in different assembler
files move the associated macros from entry.S to a new header
nospec-insn.h.

While we are at it make the macros a bit nicer to use.

Cc: stable@vger.kernel.org # 4.16
Fixes: f19fbd5ed6 ("s390: introduce execute-trampolines for branches")
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/nospec-insn.h [new file with mode: 0644]
arch/s390/kernel/entry.S

diff --git a/arch/s390/include/asm/nospec-insn.h b/arch/s390/include/asm/nospec-insn.h
new file mode 100644 (file)
index 0000000..440689c
--- /dev/null
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_S390_NOSPEC_ASM_H
+#define _ASM_S390_NOSPEC_ASM_H
+
+#include <asm/dwarf.h>
+
+#ifdef __ASSEMBLY__
+
+#ifdef CONFIG_EXPOLINE
+
+/*
+ * The expoline macros are used to create thunks in the same format
+ * as gcc generates them. The 'comdat' section flag makes sure that
+ * the various thunks are merged into a single copy.
+ */
+       .macro __THUNK_PROLOG_NAME name
+       .pushsection .text.\name,"axG",@progbits,\name,comdat
+       .globl \name
+       .hidden \name
+       .type \name,@function
+\name:
+       CFI_STARTPROC
+       .endm
+
+       .macro __THUNK_EPILOG
+       CFI_ENDPROC
+       .popsection
+       .endm
+
+       .macro __THUNK_PROLOG_BR r1,r2
+       __THUNK_PROLOG_NAME __s390x_indirect_jump_r\r2\()use_r\r1
+       .endm
+
+       .macro __THUNK_BR r1,r2
+       jg      __s390x_indirect_jump_r\r2\()use_r\r1
+       .endm
+
+       .macro __THUNK_BRASL r1,r2,r3
+       brasl   \r1,__s390x_indirect_jump_r\r3\()use_r\r2
+       .endm
+
+       .macro  __DECODE_RR expand,reg,ruse
+       .set __decode_fail,1
+       .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+       .ifc \reg,%r\r1
+       .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+       .ifc \ruse,%r\r2
+       \expand \r1,\r2
+       .set __decode_fail,0
+       .endif
+       .endr
+       .endif
+       .endr
+       .if __decode_fail == 1
+       .error "__DECODE_RR failed"
+       .endif
+       .endm
+
+       .macro  __DECODE_RRR expand,rsave,rtarget,ruse
+       .set __decode_fail,1
+       .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+       .ifc \rsave,%r\r1
+       .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+       .ifc \rtarget,%r\r2
+       .irp r3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+       .ifc \ruse,%r\r3
+       \expand \r1,\r2,\r3
+       .set __decode_fail,0
+       .endif
+       .endr
+       .endif
+       .endr
+       .endif
+       .endr
+       .if __decode_fail == 1
+       .error "__DECODE_RRR failed"
+       .endif
+       .endm
+
+       .macro __THUNK_EX_BR reg,ruse
+#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
+       exrl    0,555f
+       j       .
+#else
+       larl    \ruse,555f
+       ex      0,0(\ruse)
+       j       .
+#endif
+555:   br      \reg
+       .endm
+
+       .macro GEN_BR_THUNK reg,ruse=%r1
+       __DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse
+       __THUNK_EX_BR \reg,\ruse
+       __THUNK_EPILOG
+       .endm
+
+       .macro BR_EX reg,ruse=%r1
+557:   __DECODE_RR __THUNK_BR,\reg,\ruse
+       .pushsection .s390_indirect_branches,"a",@progbits
+       .long   557b-.
+       .popsection
+       .endm
+
+       .macro BASR_EX rsave,rtarget,ruse=%r1
+559:   __DECODE_RRR __THUNK_BRASL,\rsave,\rtarget,\ruse
+       .pushsection .s390_indirect_branches,"a",@progbits
+       .long   559b-.
+       .popsection
+       .endm
+
+#else
+       .macro GEN_BR_THUNK reg,ruse=%r1
+       .endm
+
+        .macro BR_EX reg,ruse=%r1
+       br      \reg
+       .endm
+
+       .macro BASR_EX rsave,rtarget,ruse=%r1
+       basr    \rsave,\rtarget
+       .endm
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_S390_NOSPEC_ASM_H */
index 3f22f139a0413f6880118998bbbb48f280bdad5f..f03402efab4b414eefdfd59135f4ee89dda68e8a 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/setup.h>
 #include <asm/nmi.h>
 #include <asm/export.h>
+#include <asm/nospec-insn.h>
 
 __PT_R0      = __PT_GPRS
 __PT_R1      = __PT_GPRS + 8
@@ -183,67 +184,9 @@ _LPP_OFFSET        = __LC_LPP
                    "jnz .+8; .long 0xb2e8d000", 82
        .endm
 
-#ifdef CONFIG_EXPOLINE
-
-       .macro GEN_BR_THUNK name,reg,tmp
-       .section .text.\name,"axG",@progbits,\name,comdat
-       .globl \name
-       .hidden \name
-       .type \name,@function
-\name:
-       CFI_STARTPROC
-#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
-       exrl    0,0f
-#else
-       larl    \tmp,0f
-       ex      0,0(\tmp)
-#endif
-       j       .
-0:     br      \reg
-       CFI_ENDPROC
-       .endm
-
-       GEN_BR_THUNK __s390x_indirect_jump_r1use_r9,%r9,%r1
-       GEN_BR_THUNK __s390x_indirect_jump_r1use_r14,%r14,%r1
-       GEN_BR_THUNK __s390x_indirect_jump_r11use_r14,%r14,%r11
-
-       .macro BASR_R14_R9
-0:     brasl   %r14,__s390x_indirect_jump_r1use_r9
-       .pushsection .s390_indirect_branches,"a",@progbits
-       .long   0b-.
-       .popsection
-       .endm
-
-       .macro BR_R1USE_R14
-0:     jg      __s390x_indirect_jump_r1use_r14
-       .pushsection .s390_indirect_branches,"a",@progbits
-       .long   0b-.
-       .popsection
-       .endm
-
-       .macro BR_R11USE_R14
-0:     jg      __s390x_indirect_jump_r11use_r14
-       .pushsection .s390_indirect_branches,"a",@progbits
-       .long   0b-.
-       .popsection
-       .endm
-
-#else  /* CONFIG_EXPOLINE */
-
-       .macro BASR_R14_R9
-       basr    %r14,%r9
-       .endm
-
-       .macro BR_R1USE_R14
-       br      %r14
-       .endm
-
-       .macro BR_R11USE_R14
-       br      %r14
-       .endm
-
-#endif /* CONFIG_EXPOLINE */
-
+       GEN_BR_THUNK %r9
+       GEN_BR_THUNK %r14
+       GEN_BR_THUNK %r14,%r11
 
        .section .kprobes.text, "ax"
 .Ldummy:
@@ -260,7 +203,7 @@ _LPP_OFFSET = __LC_LPP
 ENTRY(__bpon)
        .globl __bpon
        BPON
-       BR_R1USE_R14
+       BR_EX   %r14
 
 /*
  * Scheduler resume function, called by switch_to
@@ -284,7 +227,7 @@ ENTRY(__switch_to)
        mvc     __LC_CURRENT_PID(4,%r0),0(%r3)  # store pid of next
        lmg     %r6,%r15,__SF_GPRS(%r15)        # load gprs of next task
        ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
-       BR_R1USE_R14
+       BR_EX   %r14
 
 .L__critical_start:
 
@@ -351,7 +294,7 @@ sie_exit:
        xgr     %r5,%r5
        lmg     %r6,%r14,__SF_GPRS(%r15)        # restore kernel registers
        lg      %r2,__SF_SIE_REASON(%r15)       # return exit reason code
-       BR_R1USE_R14
+       BR_EX   %r14
 .Lsie_fault:
        lghi    %r14,-EFAULT
        stg     %r14,__SF_SIE_REASON(%r15)      # set exit reason code
@@ -410,7 +353,7 @@ ENTRY(system_call)
        lgf     %r9,0(%r8,%r10)                 # get system call add.
        TSTMSK  __TI_flags(%r12),_TIF_TRACE
        jnz     .Lsysc_tracesys
-       BASR_R14_R9                             # call sys_xxxx
+       BASR_EX %r14,%r9                        # call sys_xxxx
        stg     %r2,__PT_R2(%r11)               # store return value
 
 .Lsysc_return:
@@ -595,7 +538,7 @@ ENTRY(system_call)
        lmg     %r3,%r7,__PT_R3(%r11)
        stg     %r7,STACK_FRAME_OVERHEAD(%r15)
        lg      %r2,__PT_ORIG_GPR2(%r11)
-       BASR_R14_R9                     # call sys_xxx
+       BASR_EX %r14,%r9                # call sys_xxx
        stg     %r2,__PT_R2(%r11)       # store return value
 .Lsysc_tracenogo:
        TSTMSK  __TI_flags(%r12),_TIF_TRACE
@@ -619,7 +562,7 @@ ENTRY(ret_from_fork)
        lmg     %r9,%r10,__PT_R9(%r11)  # load gprs
 ENTRY(kernel_thread_starter)
        la      %r2,0(%r10)
-       BASR_R14_R9
+       BASR_EX %r14,%r9
        j       .Lsysc_tracenogo
 
 /*
@@ -701,7 +644,7 @@ ENTRY(pgm_check_handler)
        je      .Lpgm_return
        lgf     %r9,0(%r10,%r1)         # load address of handler routine
        lgr     %r2,%r11                # pass pointer to pt_regs
-       BASR_R14_R9                     # branch to interrupt-handler
+       BASR_EX %r14,%r9                # branch to interrupt-handler
 .Lpgm_return:
        LOCKDEP_SYS_EXIT
        tm      __PT_PSW+1(%r11),0x01   # returning to user ?
@@ -1019,7 +962,7 @@ ENTRY(psw_idle)
        stpt    __TIMER_IDLE_ENTER(%r2)
 .Lpsw_idle_lpsw:
        lpswe   __SF_EMPTY(%r15)
-       BR_R1USE_R14
+       BR_EX   %r14
 .Lpsw_idle_end:
 
 /*
@@ -1061,7 +1004,7 @@ ENTRY(save_fpu_regs)
 .Lsave_fpu_regs_done:
        oi      __LC_CPU_FLAGS+7,_CIF_FPU
 .Lsave_fpu_regs_exit:
-       BR_R1USE_R14
+       BR_EX   %r14
 .Lsave_fpu_regs_end:
 EXPORT_SYMBOL(save_fpu_regs)
 
@@ -1107,7 +1050,7 @@ load_fpu_regs:
 .Lload_fpu_regs_done:
        ni      __LC_CPU_FLAGS+7,255-_CIF_FPU
 .Lload_fpu_regs_exit:
-       BR_R1USE_R14
+       BR_EX   %r14
 .Lload_fpu_regs_end:
 
 .L__critical_end:
@@ -1322,7 +1265,7 @@ cleanup_critical:
        jl      0f
        clg     %r9,BASED(.Lcleanup_table+104)  # .Lload_fpu_regs_end
        jl      .Lcleanup_load_fpu_regs
-0:     BR_R11USE_R14
+0:     BR_EX   %r14
 
        .align  8
 .Lcleanup_table:
@@ -1358,7 +1301,7 @@ cleanup_critical:
        ni      __SIE_PROG0C+3(%r9),0xfe        # no longer in SIE
        lctlg   %c1,%c1,__LC_USER_ASCE          # load primary asce
        larl    %r9,sie_exit                    # skip forward to sie_exit
-       BR_R11USE_R14
+       BR_EX   %r14
 #endif
 
 .Lcleanup_system_call:
@@ -1412,7 +1355,7 @@ cleanup_critical:
        stg     %r15,56(%r11)           # r15 stack pointer
        # set new psw address and exit
        larl    %r9,.Lsysc_do_svc
-       BR_R11USE_R14
+       BR_EX   %r14,%r11
 .Lcleanup_system_call_insn:
        .quad   system_call
        .quad   .Lsysc_stmg
@@ -1424,7 +1367,7 @@ cleanup_critical:
 
 .Lcleanup_sysc_tif:
        larl    %r9,.Lsysc_tif
-       BR_R11USE_R14
+       BR_EX   %r14,%r11
 
 .Lcleanup_sysc_restore:
        # check if stpt has been executed
@@ -1441,14 +1384,14 @@ cleanup_critical:
        mvc     0(64,%r11),__PT_R8(%r9)
        lmg     %r0,%r7,__PT_R0(%r9)
 1:     lmg     %r8,%r9,__LC_RETURN_PSW
-       BR_R11USE_R14
+       BR_EX   %r14,%r11
 .Lcleanup_sysc_restore_insn:
        .quad   .Lsysc_exit_timer
        .quad   .Lsysc_done - 4
 
 .Lcleanup_io_tif:
        larl    %r9,.Lio_tif
-       BR_R11USE_R14
+       BR_EX   %r14,%r11
 
 .Lcleanup_io_restore:
        # check if stpt has been executed
@@ -1462,7 +1405,7 @@ cleanup_critical:
        mvc     0(64,%r11),__PT_R8(%r9)
        lmg     %r0,%r7,__PT_R0(%r9)
 1:     lmg     %r8,%r9,__LC_RETURN_PSW
-       BR_R11USE_R14
+       BR_EX   %r14,%r11
 .Lcleanup_io_restore_insn:
        .quad   .Lio_exit_timer
        .quad   .Lio_done - 4
@@ -1515,17 +1458,17 @@ cleanup_critical:
        # prepare return psw
        nihh    %r8,0xfcfd              # clear irq & wait state bits
        lg      %r9,48(%r11)            # return from psw_idle
-       BR_R11USE_R14
+       BR_EX   %r14,%r11
 .Lcleanup_idle_insn:
        .quad   .Lpsw_idle_lpsw
 
 .Lcleanup_save_fpu_regs:
        larl    %r9,save_fpu_regs
-       BR_R11USE_R14
+       BR_EX   %r14,%r11
 
 .Lcleanup_load_fpu_regs:
        larl    %r9,load_fpu_regs
-       BR_R11USE_R14
+       BR_EX   %r14,%r11
 
 /*
  * Integer constants