| From foo@baz Wed May 23 19:41:15 CEST 2018 |
| From: Martin Schwidefsky <schwidefsky@de.ibm.com> |
| Date: Wed, 23 May 2018 18:21:45 +0200 |
| Subject: s390: move expoline assembler macros to a header |
| To: stable@vger.kernel.org |
| Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> |
| Message-ID: <1527092512-24300-3-git-send-email-schwidefsky@de.ibm.com> |
| |
| From: Martin Schwidefsky <schwidefsky@de.ibm.com> |
| |
| [ Upstream commit 6dd85fbb87d1d6b87a3b1f02ca28d7b2abd2e7ba ] |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/s390/include/asm/nospec-insn.h | 125 ++++++++++++++++++++++++++++++++++++ |
| arch/s390/kernel/entry.S | 105 ++++++------------------------ |
| 2 files changed, 149 insertions(+), 81 deletions(-) |
| create mode 100644 arch/s390/include/asm/nospec-insn.h |
| |
| --- /dev/null |
| +++ b/arch/s390/include/asm/nospec-insn.h |
| @@ -0,0 +1,125 @@ |
| +/* SPDX-License-Identifier: GPL-2.0 */ |
| +#ifndef _ASM_S390_NOSPEC_ASM_H |
| +#define _ASM_S390_NOSPEC_ASM_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 */ |
| --- a/arch/s390/kernel/entry.S |
| +++ b/arch/s390/kernel/entry.S |
| @@ -24,6 +24,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 |
| @@ -226,67 +227,9 @@ _PIF_WORK = (_PIF_PER_TRAP) |
| .popsection |
| .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: |
| @@ -303,7 +246,7 @@ _PIF_WORK = (_PIF_PER_TRAP) |
| ENTRY(__bpon) |
| .globl __bpon |
| BPON |
| - BR_R1USE_R14 |
| + BR_EX %r14 |
| |
| /* |
| * Scheduler resume function, called by switch_to |
| @@ -333,7 +276,7 @@ ENTRY(__switch_to) |
| TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP |
| jz 0f |
| .insn s,0xb2800000,__LC_LPP # set program parameter |
| -0: BR_R1USE_R14 |
| +0: BR_EX %r14 |
| |
| .L__critical_start: |
| |
| @@ -399,7 +342,7 @@ sie_exit: |
| xgr %r5,%r5 |
| lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers |
| lg %r2,__SF_EMPTY+16(%r15) # return exit reason code |
| - BR_R1USE_R14 |
| + BR_EX %r14 |
| .Lsie_fault: |
| lghi %r14,-EFAULT |
| stg %r14,__SF_EMPTY+16(%r15) # set exit reason code |
| @@ -458,7 +401,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: |
| @@ -598,7 +541,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 |
| @@ -622,7 +565,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 |
| |
| /* |
| @@ -698,7 +641,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 ? |
| @@ -976,7 +919,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: |
| |
| /* |
| @@ -1021,7 +964,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: |
| #if IS_ENABLED(CONFIG_KVM) |
| EXPORT_SYMBOL(save_fpu_regs) |
| @@ -1071,7 +1014,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: |
| @@ -1244,7 +1187,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: |
| @@ -1274,7 +1217,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: |
| @@ -1332,7 +1275,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 |
| @@ -1342,7 +1285,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 |
| @@ -1359,14 +1302,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 |
| @@ -1380,7 +1323,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 |
| @@ -1433,17 +1376,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 |