aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2018-04-25 12:35:26 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-05-07 15:12:38 -0400
commit23a4d7fd34856da8218c4cfc23dba7a6ec0a423a (patch)
treef6bf7c9d6e0f61af64bba6877562e63793b8e4c1
parent97489e0663fa700d6e7febddc43b58df98d7bcda (diff)
s390/ftrace: use expoline for indirect branches
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>
-rw-r--r--arch/s390/include/asm/nospec-insn.h12
-rw-r--r--arch/s390/kernel/asm-offsets.c1
-rw-r--r--arch/s390/kernel/mcount.S14
3 files changed, 22 insertions, 5 deletions
diff --git a/arch/s390/include/asm/nospec-insn.h b/arch/s390/include/asm/nospec-insn.h
index 440689cbcf51..7d7640e1cf90 100644
--- a/arch/s390/include/asm/nospec-insn.h
+++ b/arch/s390/include/asm/nospec-insn.h
@@ -2,12 +2,16 @@
2#ifndef _ASM_S390_NOSPEC_ASM_H 2#ifndef _ASM_S390_NOSPEC_ASM_H
3#define _ASM_S390_NOSPEC_ASM_H 3#define _ASM_S390_NOSPEC_ASM_H
4 4
5#include <asm/alternative-asm.h>
6#include <asm/asm-offsets.h>
5#include <asm/dwarf.h> 7#include <asm/dwarf.h>
6 8
7#ifdef __ASSEMBLY__ 9#ifdef __ASSEMBLY__
8 10
9#ifdef CONFIG_EXPOLINE 11#ifdef CONFIG_EXPOLINE
10 12
13_LC_BR_R1 = __LC_BR_R1
14
11/* 15/*
12 * The expoline macros are used to create thunks in the same format 16 * The expoline macros are used to create thunks in the same format
13 * as gcc generates them. The 'comdat' section flag makes sure that 17 * as gcc generates them. The 'comdat' section flag makes sure that
@@ -78,13 +82,21 @@
78 .endm 82 .endm
79 83
80 .macro __THUNK_EX_BR reg,ruse 84 .macro __THUNK_EX_BR reg,ruse
85 # Be very careful when adding instructions to this macro!
86 # The ALTERNATIVE replacement code has a .+10 which targets
87 # the "br \reg" after the code has been patched.
81#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES 88#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
82 exrl 0,555f 89 exrl 0,555f
83 j . 90 j .
84#else 91#else
92 .ifc \reg,%r1
93 ALTERNATIVE "ex %r0,_LC_BR_R1", ".insn ril,0xc60000000000,0,.+10", 35
94 j .
95 .else
85 larl \ruse,555f 96 larl \ruse,555f
86 ex 0,0(\ruse) 97 ex 0,0(\ruse)
87 j . 98 j .
99 .endif
88#endif 100#endif
89555: br \reg 101555: br \reg
90 .endm 102 .endm
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index eb2a5c0443cd..11aea745a2a6 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -181,6 +181,7 @@ int main(void)
181 OFFSET(__LC_MACHINE_FLAGS, lowcore, machine_flags); 181 OFFSET(__LC_MACHINE_FLAGS, lowcore, machine_flags);
182 OFFSET(__LC_PREEMPT_COUNT, lowcore, preempt_count); 182 OFFSET(__LC_PREEMPT_COUNT, lowcore, preempt_count);
183 OFFSET(__LC_GMAP, lowcore, gmap); 183 OFFSET(__LC_GMAP, lowcore, gmap);
184 OFFSET(__LC_BR_R1, lowcore, br_r1_trampoline);
184 /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */ 185 /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */
185 OFFSET(__LC_DUMP_REIPL, lowcore, ipib); 186 OFFSET(__LC_DUMP_REIPL, lowcore, ipib);
186 /* hardware defined lowcore locations 0x1000 - 0x18ff */ 187 /* hardware defined lowcore locations 0x1000 - 0x18ff */
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S
index 82df7d80fab2..27110f3294ed 100644
--- a/arch/s390/kernel/mcount.S
+++ b/arch/s390/kernel/mcount.S
@@ -9,13 +9,17 @@
9#include <linux/linkage.h> 9#include <linux/linkage.h>
10#include <asm/asm-offsets.h> 10#include <asm/asm-offsets.h>
11#include <asm/ftrace.h> 11#include <asm/ftrace.h>
12#include <asm/nospec-insn.h>
12#include <asm/ptrace.h> 13#include <asm/ptrace.h>
13#include <asm/export.h> 14#include <asm/export.h>
14 15
16 GEN_BR_THUNK %r1
17 GEN_BR_THUNK %r14
18
15 .section .kprobes.text, "ax" 19 .section .kprobes.text, "ax"
16 20
17ENTRY(ftrace_stub) 21ENTRY(ftrace_stub)
18 br %r14 22 BR_EX %r14
19 23
20#define STACK_FRAME_SIZE (STACK_FRAME_OVERHEAD + __PT_SIZE) 24#define STACK_FRAME_SIZE (STACK_FRAME_OVERHEAD + __PT_SIZE)
21#define STACK_PTREGS (STACK_FRAME_OVERHEAD) 25#define STACK_PTREGS (STACK_FRAME_OVERHEAD)
@@ -23,7 +27,7 @@ ENTRY(ftrace_stub)
23#define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW) 27#define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW)
24 28
25ENTRY(_mcount) 29ENTRY(_mcount)
26 br %r14 30 BR_EX %r14
27 31
28EXPORT_SYMBOL(_mcount) 32EXPORT_SYMBOL(_mcount)
29 33
@@ -53,7 +57,7 @@ ENTRY(ftrace_caller)
53#endif 57#endif
54 lgr %r3,%r14 58 lgr %r3,%r14
55 la %r5,STACK_PTREGS(%r15) 59 la %r5,STACK_PTREGS(%r15)
56 basr %r14,%r1 60 BASR_EX %r14,%r1
57#ifdef CONFIG_FUNCTION_GRAPH_TRACER 61#ifdef CONFIG_FUNCTION_GRAPH_TRACER
58# The j instruction gets runtime patched to a nop instruction. 62# The j instruction gets runtime patched to a nop instruction.
59# See ftrace_enable_ftrace_graph_caller. 63# See ftrace_enable_ftrace_graph_caller.
@@ -68,7 +72,7 @@ ftrace_graph_caller_end:
68#endif 72#endif
69 lg %r1,(STACK_PTREGS_PSW+8)(%r15) 73 lg %r1,(STACK_PTREGS_PSW+8)(%r15)
70 lmg %r2,%r15,(STACK_PTREGS_GPRS+2*8)(%r15) 74 lmg %r2,%r15,(STACK_PTREGS_GPRS+2*8)(%r15)
71 br %r1 75 BR_EX %r1
72 76
73#ifdef CONFIG_FUNCTION_GRAPH_TRACER 77#ifdef CONFIG_FUNCTION_GRAPH_TRACER
74 78
@@ -81,6 +85,6 @@ ENTRY(return_to_handler)
81 aghi %r15,STACK_FRAME_OVERHEAD 85 aghi %r15,STACK_FRAME_OVERHEAD
82 lgr %r14,%r2 86 lgr %r14,%r2
83 lmg %r2,%r5,32(%r15) 87 lmg %r2,%r5,32(%r15)
84 br %r14 88 BR_EX %r14
85 89
86#endif 90#endif