aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-05-17 13:11:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-05-17 13:11:44 -0400
commit3e9245c5fa3092de19b95f03817b02469bcf146c (patch)
treea388e64d6cd075d20b355e9e5810ea7f4c361556
parent305bb55212822f13ddbfcb7518d999c6369942ba (diff)
parent2e68adcd2fb21b7188ba449f0fab3bee2910e500 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Martin Schwidefsky: - a fix for the vfio ccw translation code - update an incorrect email address in the MAINTAINERS file - fix a division by zero oops in the cpum_sf code found by trinity - two fixes for the error handling of the qdio code - several spectre related patches to convert all left-over indirect branches in the kernel to expoline branches - update defconfigs to avoid warnings due to the netfilter Kconfig changes - avoid several compiler warnings in the kexec_file code for s390 * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/qdio: don't release memory in qdio_setup_irq() s390/qdio: fix access to uninitialized qdio_q fields s390/cpum_sf: ensure sample frequency of perf event attributes is non-zero s390: use expoline thunks in the BPF JIT s390: extend expoline to BC instructions s390: remove indirect branch from do_softirq_own_stack s390: move spectre sysfs attribute code s390/kernel: use expoline for indirect branches s390/ftrace: use expoline for indirect branches s390/lib: use expoline for indirect branches s390/crc32-vx: use expoline for indirect branches s390: move expoline assembler macros to a header vfio: ccw: fix cleanup if cp_prefetch fails s390/kexec_file: add declaration of purgatory related globals s390: update defconfigs MAINTAINERS: update s390 zcrypt maintainers email address
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/s390/configs/debug_defconfig9
-rw-r--r--arch/s390/configs/performance_defconfig8
-rw-r--r--arch/s390/crypto/crc32be-vx.S5
-rw-r--r--arch/s390/crypto/crc32le-vx.S4
-rw-r--r--arch/s390/include/asm/nospec-insn.h196
-rw-r--r--arch/s390/include/asm/purgatory.h6
-rw-r--r--arch/s390/kernel/Makefile1
-rw-r--r--arch/s390/kernel/asm-offsets.c1
-rw-r--r--arch/s390/kernel/base.S24
-rw-r--r--arch/s390/kernel/entry.S105
-rw-r--r--arch/s390/kernel/irq.c5
-rw-r--r--arch/s390/kernel/mcount.S14
-rw-r--r--arch/s390/kernel/nospec-branch.c44
-rw-r--r--arch/s390/kernel/nospec-sysfs.c21
-rw-r--r--arch/s390/kernel/perf_cpum_sf.c4
-rw-r--r--arch/s390/kernel/reipl.S7
-rw-r--r--arch/s390/kernel/swsusp.S10
-rw-r--r--arch/s390/lib/mem.S19
-rw-r--r--arch/s390/net/bpf_jit.S16
-rw-r--r--arch/s390/net/bpf_jit_comp.c63
-rw-r--r--drivers/s390/cio/qdio_setup.c12
-rw-r--r--drivers/s390/cio/vfio_ccw_cp.c13
23 files changed, 422 insertions, 167 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 58b9861ccf99..92e47b5b0480 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12220,7 +12220,7 @@ F: Documentation/s390/vfio-ccw.txt
12220F: include/uapi/linux/vfio_ccw.h 12220F: include/uapi/linux/vfio_ccw.h
12221 12221
12222S390 ZCRYPT DRIVER 12222S390 ZCRYPT DRIVER
12223M: Harald Freudenberger <freude@de.ibm.com> 12223M: Harald Freudenberger <freude@linux.ibm.com>
12224L: linux-s390@vger.kernel.org 12224L: linux-s390@vger.kernel.org
12225W: http://www.ibm.com/developerworks/linux/linux390/ 12225W: http://www.ibm.com/developerworks/linux/linux390/
12226S: Supported 12226S: Supported
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index 6176fe9795ca..941d8cc6c9f5 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -261,9 +261,9 @@ CONFIG_IP_VS_NQ=m
261CONFIG_IP_VS_FTP=m 261CONFIG_IP_VS_FTP=m
262CONFIG_IP_VS_PE_SIP=m 262CONFIG_IP_VS_PE_SIP=m
263CONFIG_NF_CONNTRACK_IPV4=m 263CONFIG_NF_CONNTRACK_IPV4=m
264CONFIG_NF_TABLES_IPV4=m 264CONFIG_NF_TABLES_IPV4=y
265CONFIG_NFT_CHAIN_ROUTE_IPV4=m 265CONFIG_NFT_CHAIN_ROUTE_IPV4=m
266CONFIG_NF_TABLES_ARP=m 266CONFIG_NF_TABLES_ARP=y
267CONFIG_NFT_CHAIN_NAT_IPV4=m 267CONFIG_NFT_CHAIN_NAT_IPV4=m
268CONFIG_IP_NF_IPTABLES=m 268CONFIG_IP_NF_IPTABLES=m
269CONFIG_IP_NF_MATCH_AH=m 269CONFIG_IP_NF_MATCH_AH=m
@@ -284,7 +284,7 @@ CONFIG_IP_NF_ARPTABLES=m
284CONFIG_IP_NF_ARPFILTER=m 284CONFIG_IP_NF_ARPFILTER=m
285CONFIG_IP_NF_ARP_MANGLE=m 285CONFIG_IP_NF_ARP_MANGLE=m
286CONFIG_NF_CONNTRACK_IPV6=m 286CONFIG_NF_CONNTRACK_IPV6=m
287CONFIG_NF_TABLES_IPV6=m 287CONFIG_NF_TABLES_IPV6=y
288CONFIG_NFT_CHAIN_ROUTE_IPV6=m 288CONFIG_NFT_CHAIN_ROUTE_IPV6=m
289CONFIG_NFT_CHAIN_NAT_IPV6=m 289CONFIG_NFT_CHAIN_NAT_IPV6=m
290CONFIG_IP6_NF_IPTABLES=m 290CONFIG_IP6_NF_IPTABLES=m
@@ -305,7 +305,7 @@ CONFIG_IP6_NF_RAW=m
305CONFIG_IP6_NF_SECURITY=m 305CONFIG_IP6_NF_SECURITY=m
306CONFIG_IP6_NF_NAT=m 306CONFIG_IP6_NF_NAT=m
307CONFIG_IP6_NF_TARGET_MASQUERADE=m 307CONFIG_IP6_NF_TARGET_MASQUERADE=m
308CONFIG_NF_TABLES_BRIDGE=m 308CONFIG_NF_TABLES_BRIDGE=y
309CONFIG_RDS=m 309CONFIG_RDS=m
310CONFIG_RDS_RDMA=m 310CONFIG_RDS_RDMA=m
311CONFIG_RDS_TCP=m 311CONFIG_RDS_TCP=m
@@ -604,7 +604,6 @@ CONFIG_DETECT_HUNG_TASK=y
604CONFIG_WQ_WATCHDOG=y 604CONFIG_WQ_WATCHDOG=y
605CONFIG_PANIC_ON_OOPS=y 605CONFIG_PANIC_ON_OOPS=y
606CONFIG_DEBUG_TIMEKEEPING=y 606CONFIG_DEBUG_TIMEKEEPING=y
607CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
608CONFIG_PROVE_LOCKING=y 607CONFIG_PROVE_LOCKING=y
609CONFIG_LOCK_STAT=y 608CONFIG_LOCK_STAT=y
610CONFIG_DEBUG_LOCKDEP=y 609CONFIG_DEBUG_LOCKDEP=y
diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig
index c105bcc6d7a6..eb6f75f24208 100644
--- a/arch/s390/configs/performance_defconfig
+++ b/arch/s390/configs/performance_defconfig
@@ -259,9 +259,9 @@ CONFIG_IP_VS_NQ=m
259CONFIG_IP_VS_FTP=m 259CONFIG_IP_VS_FTP=m
260CONFIG_IP_VS_PE_SIP=m 260CONFIG_IP_VS_PE_SIP=m
261CONFIG_NF_CONNTRACK_IPV4=m 261CONFIG_NF_CONNTRACK_IPV4=m
262CONFIG_NF_TABLES_IPV4=m 262CONFIG_NF_TABLES_IPV4=y
263CONFIG_NFT_CHAIN_ROUTE_IPV4=m 263CONFIG_NFT_CHAIN_ROUTE_IPV4=m
264CONFIG_NF_TABLES_ARP=m 264CONFIG_NF_TABLES_ARP=y
265CONFIG_NFT_CHAIN_NAT_IPV4=m 265CONFIG_NFT_CHAIN_NAT_IPV4=m
266CONFIG_IP_NF_IPTABLES=m 266CONFIG_IP_NF_IPTABLES=m
267CONFIG_IP_NF_MATCH_AH=m 267CONFIG_IP_NF_MATCH_AH=m
@@ -282,7 +282,7 @@ CONFIG_IP_NF_ARPTABLES=m
282CONFIG_IP_NF_ARPFILTER=m 282CONFIG_IP_NF_ARPFILTER=m
283CONFIG_IP_NF_ARP_MANGLE=m 283CONFIG_IP_NF_ARP_MANGLE=m
284CONFIG_NF_CONNTRACK_IPV6=m 284CONFIG_NF_CONNTRACK_IPV6=m
285CONFIG_NF_TABLES_IPV6=m 285CONFIG_NF_TABLES_IPV6=y
286CONFIG_NFT_CHAIN_ROUTE_IPV6=m 286CONFIG_NFT_CHAIN_ROUTE_IPV6=m
287CONFIG_NFT_CHAIN_NAT_IPV6=m 287CONFIG_NFT_CHAIN_NAT_IPV6=m
288CONFIG_IP6_NF_IPTABLES=m 288CONFIG_IP6_NF_IPTABLES=m
@@ -303,7 +303,7 @@ CONFIG_IP6_NF_RAW=m
303CONFIG_IP6_NF_SECURITY=m 303CONFIG_IP6_NF_SECURITY=m
304CONFIG_IP6_NF_NAT=m 304CONFIG_IP6_NF_NAT=m
305CONFIG_IP6_NF_TARGET_MASQUERADE=m 305CONFIG_IP6_NF_TARGET_MASQUERADE=m
306CONFIG_NF_TABLES_BRIDGE=m 306CONFIG_NF_TABLES_BRIDGE=y
307CONFIG_RDS=m 307CONFIG_RDS=m
308CONFIG_RDS_RDMA=m 308CONFIG_RDS_RDMA=m
309CONFIG_RDS_TCP=m 309CONFIG_RDS_TCP=m
diff --git a/arch/s390/crypto/crc32be-vx.S b/arch/s390/crypto/crc32be-vx.S
index e8077f0971f8..2bf01ba44107 100644
--- a/arch/s390/crypto/crc32be-vx.S
+++ b/arch/s390/crypto/crc32be-vx.S
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <linux/linkage.h> 15#include <linux/linkage.h>
16#include <asm/nospec-insn.h>
16#include <asm/vx-insn.h> 17#include <asm/vx-insn.h>
17 18
18/* Vector register range containing CRC-32 constants */ 19/* Vector register range containing CRC-32 constants */
@@ -67,6 +68,8 @@
67 68
68.previous 69.previous
69 70
71 GEN_BR_THUNK %r14
72
70.text 73.text
71/* 74/*
72 * The CRC-32 function(s) use these calling conventions: 75 * The CRC-32 function(s) use these calling conventions:
@@ -203,6 +206,6 @@ ENTRY(crc32_be_vgfm_16)
203 206
204.Ldone: 207.Ldone:
205 VLGVF %r2,%v2,3 208 VLGVF %r2,%v2,3
206 br %r14 209 BR_EX %r14
207 210
208.previous 211.previous
diff --git a/arch/s390/crypto/crc32le-vx.S b/arch/s390/crypto/crc32le-vx.S
index d8c67a58c0c5..7d6f568bd3ad 100644
--- a/arch/s390/crypto/crc32le-vx.S
+++ b/arch/s390/crypto/crc32le-vx.S
@@ -14,6 +14,7 @@
14 */ 14 */
15 15
16#include <linux/linkage.h> 16#include <linux/linkage.h>
17#include <asm/nospec-insn.h>
17#include <asm/vx-insn.h> 18#include <asm/vx-insn.h>
18 19
19/* Vector register range containing CRC-32 constants */ 20/* Vector register range containing CRC-32 constants */
@@ -76,6 +77,7 @@
76 77
77.previous 78.previous
78 79
80 GEN_BR_THUNK %r14
79 81
80.text 82.text
81 83
@@ -264,6 +266,6 @@ crc32_le_vgfm_generic:
264 266
265.Ldone: 267.Ldone:
266 VLGVF %r2,%v2,2 268 VLGVF %r2,%v2,2
267 br %r14 269 BR_EX %r14
268 270
269.previous 271.previous
diff --git a/arch/s390/include/asm/nospec-insn.h b/arch/s390/include/asm/nospec-insn.h
new file mode 100644
index 000000000000..a01f81186e86
--- /dev/null
+++ b/arch/s390/include/asm/nospec-insn.h
@@ -0,0 +1,196 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_S390_NOSPEC_ASM_H
3#define _ASM_S390_NOSPEC_ASM_H
4
5#include <asm/alternative-asm.h>
6#include <asm/asm-offsets.h>
7#include <asm/dwarf.h>
8
9#ifdef __ASSEMBLY__
10
11#ifdef CONFIG_EXPOLINE
12
13_LC_BR_R1 = __LC_BR_R1
14
15/*
16 * The expoline macros are used to create thunks in the same format
17 * as gcc generates them. The 'comdat' section flag makes sure that
18 * the various thunks are merged into a single copy.
19 */
20 .macro __THUNK_PROLOG_NAME name
21 .pushsection .text.\name,"axG",@progbits,\name,comdat
22 .globl \name
23 .hidden \name
24 .type \name,@function
25\name:
26 CFI_STARTPROC
27 .endm
28
29 .macro __THUNK_EPILOG
30 CFI_ENDPROC
31 .popsection
32 .endm
33
34 .macro __THUNK_PROLOG_BR r1,r2
35 __THUNK_PROLOG_NAME __s390x_indirect_jump_r\r2\()use_r\r1
36 .endm
37
38 .macro __THUNK_PROLOG_BC d0,r1,r2
39 __THUNK_PROLOG_NAME __s390x_indirect_branch_\d0\()_\r2\()use_\r1
40 .endm
41
42 .macro __THUNK_BR r1,r2
43 jg __s390x_indirect_jump_r\r2\()use_r\r1
44 .endm
45
46 .macro __THUNK_BC d0,r1,r2
47 jg __s390x_indirect_branch_\d0\()_\r2\()use_\r1
48 .endm
49
50 .macro __THUNK_BRASL r1,r2,r3
51 brasl \r1,__s390x_indirect_jump_r\r3\()use_r\r2
52 .endm
53
54 .macro __DECODE_RR expand,reg,ruse
55 .set __decode_fail,1
56 .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
57 .ifc \reg,%r\r1
58 .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
59 .ifc \ruse,%r\r2
60 \expand \r1,\r2
61 .set __decode_fail,0
62 .endif
63 .endr
64 .endif
65 .endr
66 .if __decode_fail == 1
67 .error "__DECODE_RR failed"
68 .endif
69 .endm
70
71 .macro __DECODE_RRR expand,rsave,rtarget,ruse
72 .set __decode_fail,1
73 .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
74 .ifc \rsave,%r\r1
75 .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
76 .ifc \rtarget,%r\r2
77 .irp r3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
78 .ifc \ruse,%r\r3
79 \expand \r1,\r2,\r3
80 .set __decode_fail,0
81 .endif
82 .endr
83 .endif
84 .endr
85 .endif
86 .endr
87 .if __decode_fail == 1
88 .error "__DECODE_RRR failed"
89 .endif
90 .endm
91
92 .macro __DECODE_DRR expand,disp,reg,ruse
93 .set __decode_fail,1
94 .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
95 .ifc \reg,%r\r1
96 .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
97 .ifc \ruse,%r\r2
98 \expand \disp,\r1,\r2
99 .set __decode_fail,0
100 .endif
101 .endr
102 .endif
103 .endr
104 .if __decode_fail == 1
105 .error "__DECODE_DRR failed"
106 .endif
107 .endm
108
109 .macro __THUNK_EX_BR reg,ruse
110 # Be very careful when adding instructions to this macro!
111 # The ALTERNATIVE replacement code has a .+10 which targets
112 # the "br \reg" after the code has been patched.
113#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
114 exrl 0,555f
115 j .
116#else
117 .ifc \reg,%r1
118 ALTERNATIVE "ex %r0,_LC_BR_R1", ".insn ril,0xc60000000000,0,.+10", 35
119 j .
120 .else
121 larl \ruse,555f
122 ex 0,0(\ruse)
123 j .
124 .endif
125#endif
126555: br \reg
127 .endm
128
129 .macro __THUNK_EX_BC disp,reg,ruse
130#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
131 exrl 0,556f
132 j .
133#else
134 larl \ruse,556f
135 ex 0,0(\ruse)
136 j .
137#endif
138556: b \disp(\reg)
139 .endm
140
141 .macro GEN_BR_THUNK reg,ruse=%r1
142 __DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse
143 __THUNK_EX_BR \reg,\ruse
144 __THUNK_EPILOG
145 .endm
146
147 .macro GEN_B_THUNK disp,reg,ruse=%r1
148 __DECODE_DRR __THUNK_PROLOG_BC,\disp,\reg,\ruse
149 __THUNK_EX_BC \disp,\reg,\ruse
150 __THUNK_EPILOG
151 .endm
152
153 .macro BR_EX reg,ruse=%r1
154557: __DECODE_RR __THUNK_BR,\reg,\ruse
155 .pushsection .s390_indirect_branches,"a",@progbits
156 .long 557b-.
157 .popsection
158 .endm
159
160 .macro B_EX disp,reg,ruse=%r1
161558: __DECODE_DRR __THUNK_BC,\disp,\reg,\ruse
162 .pushsection .s390_indirect_branches,"a",@progbits
163 .long 558b-.
164 .popsection
165 .endm
166
167 .macro BASR_EX rsave,rtarget,ruse=%r1
168559: __DECODE_RRR __THUNK_BRASL,\rsave,\rtarget,\ruse
169 .pushsection .s390_indirect_branches,"a",@progbits
170 .long 559b-.
171 .popsection
172 .endm
173
174#else
175 .macro GEN_BR_THUNK reg,ruse=%r1
176 .endm
177
178 .macro GEN_B_THUNK disp,reg,ruse=%r1
179 .endm
180
181 .macro BR_EX reg,ruse=%r1
182 br \reg
183 .endm
184
185 .macro B_EX disp,reg,ruse=%r1
186 b \disp(\reg)
187 .endm
188
189 .macro BASR_EX rsave,rtarget,ruse=%r1
190 basr \rsave,\rtarget
191 .endm
192#endif
193
194#endif /* __ASSEMBLY__ */
195
196#endif /* _ASM_S390_NOSPEC_ASM_H */
diff --git a/arch/s390/include/asm/purgatory.h b/arch/s390/include/asm/purgatory.h
index e297bcfc476f..6090670df51f 100644
--- a/arch/s390/include/asm/purgatory.h
+++ b/arch/s390/include/asm/purgatory.h
@@ -13,5 +13,11 @@
13 13
14int verify_sha256_digest(void); 14int verify_sha256_digest(void);
15 15
16extern u64 kernel_entry;
17extern u64 kernel_type;
18
19extern u64 crash_start;
20extern u64 crash_size;
21
16#endif /* __ASSEMBLY__ */ 22#endif /* __ASSEMBLY__ */
17#endif /* _S390_PURGATORY_H_ */ 23#endif /* _S390_PURGATORY_H_ */
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 84ea6225efb4..f92dd8ed3884 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -65,6 +65,7 @@ obj-y += nospec-branch.o
65 65
66extra-y += head.o head64.o vmlinux.lds 66extra-y += head.o head64.o vmlinux.lds
67 67
68obj-$(CONFIG_SYSFS) += nospec-sysfs.o
68CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE) 69CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE)
69 70
70obj-$(CONFIG_MODULES) += module.o 71obj-$(CONFIG_MODULES) += module.o
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/base.S b/arch/s390/kernel/base.S
index f6c56009e822..b65874b0b412 100644
--- a/arch/s390/kernel/base.S
+++ b/arch/s390/kernel/base.S
@@ -9,18 +9,22 @@
9 9
10#include <linux/linkage.h> 10#include <linux/linkage.h>
11#include <asm/asm-offsets.h> 11#include <asm/asm-offsets.h>
12#include <asm/nospec-insn.h>
12#include <asm/ptrace.h> 13#include <asm/ptrace.h>
13#include <asm/sigp.h> 14#include <asm/sigp.h>
14 15
16 GEN_BR_THUNK %r9
17 GEN_BR_THUNK %r14
18
15ENTRY(s390_base_mcck_handler) 19ENTRY(s390_base_mcck_handler)
16 basr %r13,0 20 basr %r13,0
170: lg %r15,__LC_PANIC_STACK # load panic stack 210: lg %r15,__LC_PANIC_STACK # load panic stack
18 aghi %r15,-STACK_FRAME_OVERHEAD 22 aghi %r15,-STACK_FRAME_OVERHEAD
19 larl %r1,s390_base_mcck_handler_fn 23 larl %r1,s390_base_mcck_handler_fn
20 lg %r1,0(%r1) 24 lg %r9,0(%r1)
21 ltgr %r1,%r1 25 ltgr %r9,%r9
22 jz 1f 26 jz 1f
23 basr %r14,%r1 27 BASR_EX %r14,%r9
241: la %r1,4095 281: la %r1,4095
25 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1) 29 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)
26 lpswe __LC_MCK_OLD_PSW 30 lpswe __LC_MCK_OLD_PSW
@@ -37,10 +41,10 @@ ENTRY(s390_base_ext_handler)
37 basr %r13,0 41 basr %r13,0
380: aghi %r15,-STACK_FRAME_OVERHEAD 420: aghi %r15,-STACK_FRAME_OVERHEAD
39 larl %r1,s390_base_ext_handler_fn 43 larl %r1,s390_base_ext_handler_fn
40 lg %r1,0(%r1) 44 lg %r9,0(%r1)
41 ltgr %r1,%r1 45 ltgr %r9,%r9
42 jz 1f 46 jz 1f
43 basr %r14,%r1 47 BASR_EX %r14,%r9
441: lmg %r0,%r15,__LC_SAVE_AREA_ASYNC 481: lmg %r0,%r15,__LC_SAVE_AREA_ASYNC
45 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit 49 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit
46 lpswe __LC_EXT_OLD_PSW 50 lpswe __LC_EXT_OLD_PSW
@@ -57,10 +61,10 @@ ENTRY(s390_base_pgm_handler)
57 basr %r13,0 61 basr %r13,0
580: aghi %r15,-STACK_FRAME_OVERHEAD 620: aghi %r15,-STACK_FRAME_OVERHEAD
59 larl %r1,s390_base_pgm_handler_fn 63 larl %r1,s390_base_pgm_handler_fn
60 lg %r1,0(%r1) 64 lg %r9,0(%r1)
61 ltgr %r1,%r1 65 ltgr %r9,%r9
62 jz 1f 66 jz 1f
63 basr %r14,%r1 67 BASR_EX %r14,%r9
64 lmg %r0,%r15,__LC_SAVE_AREA_SYNC 68 lmg %r0,%r15,__LC_SAVE_AREA_SYNC
65 lpswe __LC_PGM_OLD_PSW 69 lpswe __LC_PGM_OLD_PSW
661: lpswe disabled_wait_psw-0b(%r13) 701: lpswe disabled_wait_psw-0b(%r13)
@@ -117,7 +121,7 @@ ENTRY(diag308_reset)
117 larl %r4,.Lcontinue_psw # Restore PSW flags 121 larl %r4,.Lcontinue_psw # Restore PSW flags
118 lpswe 0(%r4) 122 lpswe 0(%r4)
119.Lcontinue: 123.Lcontinue:
120 br %r14 124 BR_EX %r14
121.align 16 125.align 16
122.Lrestart_psw: 126.Lrestart_psw:
123 .long 0x00080000,0x80000000 + .Lrestart_part2 127 .long 0x00080000,0x80000000 + .Lrestart_part2
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 3f22f139a041..f03402efab4b 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -28,6 +28,7 @@
28#include <asm/setup.h> 28#include <asm/setup.h>
29#include <asm/nmi.h> 29#include <asm/nmi.h>
30#include <asm/export.h> 30#include <asm/export.h>
31#include <asm/nospec-insn.h>
31 32
32__PT_R0 = __PT_GPRS 33__PT_R0 = __PT_GPRS
33__PT_R1 = __PT_GPRS + 8 34__PT_R1 = __PT_GPRS + 8
@@ -183,67 +184,9 @@ _LPP_OFFSET = __LC_LPP
183 "jnz .+8; .long 0xb2e8d000", 82 184 "jnz .+8; .long 0xb2e8d000", 82
184 .endm 185 .endm
185 186
186#ifdef CONFIG_EXPOLINE 187 GEN_BR_THUNK %r9
187 188 GEN_BR_THUNK %r14
188 .macro GEN_BR_THUNK name,reg,tmp 189 GEN_BR_THUNK %r14,%r11
189 .section .text.\name,"axG",@progbits,\name,comdat
190 .globl \name
191 .hidden \name
192 .type \name,@function
193\name:
194 CFI_STARTPROC
195#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
196 exrl 0,0f
197#else
198 larl \tmp,0f
199 ex 0,0(\tmp)
200#endif
201 j .
2020: br \reg
203 CFI_ENDPROC
204 .endm
205
206 GEN_BR_THUNK __s390x_indirect_jump_r1use_r9,%r9,%r1
207 GEN_BR_THUNK __s390x_indirect_jump_r1use_r14,%r14,%r1
208 GEN_BR_THUNK __s390x_indirect_jump_r11use_r14,%r14,%r11
209
210 .macro BASR_R14_R9
2110: brasl %r14,__s390x_indirect_jump_r1use_r9
212 .pushsection .s390_indirect_branches,"a",@progbits
213 .long 0b-.
214 .popsection
215 .endm
216
217 .macro BR_R1USE_R14
2180: jg __s390x_indirect_jump_r1use_r14
219 .pushsection .s390_indirect_branches,"a",@progbits
220 .long 0b-.
221 .popsection
222 .endm
223
224 .macro BR_R11USE_R14
2250: jg __s390x_indirect_jump_r11use_r14
226 .pushsection .s390_indirect_branches,"a",@progbits
227 .long 0b-.
228 .popsection
229 .endm
230
231#else /* CONFIG_EXPOLINE */
232
233 .macro BASR_R14_R9
234 basr %r14,%r9
235 .endm
236
237 .macro BR_R1USE_R14
238 br %r14
239 .endm
240
241 .macro BR_R11USE_R14
242 br %r14
243 .endm
244
245#endif /* CONFIG_EXPOLINE */
246
247 190
248 .section .kprobes.text, "ax" 191 .section .kprobes.text, "ax"
249.Ldummy: 192.Ldummy:
@@ -260,7 +203,7 @@ _LPP_OFFSET = __LC_LPP
260ENTRY(__bpon) 203ENTRY(__bpon)
261 .globl __bpon 204 .globl __bpon
262 BPON 205 BPON
263 BR_R1USE_R14 206 BR_EX %r14
264 207
265/* 208/*
266 * Scheduler resume function, called by switch_to 209 * Scheduler resume function, called by switch_to
@@ -284,7 +227,7 @@ ENTRY(__switch_to)
284 mvc __LC_CURRENT_PID(4,%r0),0(%r3) # store pid of next 227 mvc __LC_CURRENT_PID(4,%r0),0(%r3) # store pid of next
285 lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task 228 lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
286 ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40 229 ALTERNATIVE "", ".insn s,0xb2800000,_LPP_OFFSET", 40
287 BR_R1USE_R14 230 BR_EX %r14
288 231
289.L__critical_start: 232.L__critical_start:
290 233
@@ -351,7 +294,7 @@ sie_exit:
351 xgr %r5,%r5 294 xgr %r5,%r5
352 lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers 295 lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers
353 lg %r2,__SF_SIE_REASON(%r15) # return exit reason code 296 lg %r2,__SF_SIE_REASON(%r15) # return exit reason code
354 BR_R1USE_R14 297 BR_EX %r14
355.Lsie_fault: 298.Lsie_fault:
356 lghi %r14,-EFAULT 299 lghi %r14,-EFAULT
357 stg %r14,__SF_SIE_REASON(%r15) # set exit reason code 300 stg %r14,__SF_SIE_REASON(%r15) # set exit reason code
@@ -410,7 +353,7 @@ ENTRY(system_call)
410 lgf %r9,0(%r8,%r10) # get system call add. 353 lgf %r9,0(%r8,%r10) # get system call add.
411 TSTMSK __TI_flags(%r12),_TIF_TRACE 354 TSTMSK __TI_flags(%r12),_TIF_TRACE
412 jnz .Lsysc_tracesys 355 jnz .Lsysc_tracesys
413 BASR_R14_R9 # call sys_xxxx 356 BASR_EX %r14,%r9 # call sys_xxxx
414 stg %r2,__PT_R2(%r11) # store return value 357 stg %r2,__PT_R2(%r11) # store return value
415 358
416.Lsysc_return: 359.Lsysc_return:
@@ -595,7 +538,7 @@ ENTRY(system_call)
595 lmg %r3,%r7,__PT_R3(%r11) 538 lmg %r3,%r7,__PT_R3(%r11)
596 stg %r7,STACK_FRAME_OVERHEAD(%r15) 539 stg %r7,STACK_FRAME_OVERHEAD(%r15)
597 lg %r2,__PT_ORIG_GPR2(%r11) 540 lg %r2,__PT_ORIG_GPR2(%r11)
598 BASR_R14_R9 # call sys_xxx 541 BASR_EX %r14,%r9 # call sys_xxx
599 stg %r2,__PT_R2(%r11) # store return value 542 stg %r2,__PT_R2(%r11) # store return value
600.Lsysc_tracenogo: 543.Lsysc_tracenogo:
601 TSTMSK __TI_flags(%r12),_TIF_TRACE 544 TSTMSK __TI_flags(%r12),_TIF_TRACE
@@ -619,7 +562,7 @@ ENTRY(ret_from_fork)
619 lmg %r9,%r10,__PT_R9(%r11) # load gprs 562 lmg %r9,%r10,__PT_R9(%r11) # load gprs
620ENTRY(kernel_thread_starter) 563ENTRY(kernel_thread_starter)
621 la %r2,0(%r10) 564 la %r2,0(%r10)
622 BASR_R14_R9 565 BASR_EX %r14,%r9
623 j .Lsysc_tracenogo 566 j .Lsysc_tracenogo
624 567
625/* 568/*
@@ -701,7 +644,7 @@ ENTRY(pgm_check_handler)
701 je .Lpgm_return 644 je .Lpgm_return
702 lgf %r9,0(%r10,%r1) # load address of handler routine 645 lgf %r9,0(%r10,%r1) # load address of handler routine
703 lgr %r2,%r11 # pass pointer to pt_regs 646 lgr %r2,%r11 # pass pointer to pt_regs
704 BASR_R14_R9 # branch to interrupt-handler 647 BASR_EX %r14,%r9 # branch to interrupt-handler
705.Lpgm_return: 648.Lpgm_return:
706 LOCKDEP_SYS_EXIT 649 LOCKDEP_SYS_EXIT
707 tm __PT_PSW+1(%r11),0x01 # returning to user ? 650 tm __PT_PSW+1(%r11),0x01 # returning to user ?
@@ -1019,7 +962,7 @@ ENTRY(psw_idle)
1019 stpt __TIMER_IDLE_ENTER(%r2) 962 stpt __TIMER_IDLE_ENTER(%r2)
1020.Lpsw_idle_lpsw: 963.Lpsw_idle_lpsw:
1021 lpswe __SF_EMPTY(%r15) 964 lpswe __SF_EMPTY(%r15)
1022 BR_R1USE_R14 965 BR_EX %r14
1023.Lpsw_idle_end: 966.Lpsw_idle_end:
1024 967
1025/* 968/*
@@ -1061,7 +1004,7 @@ ENTRY(save_fpu_regs)
1061.Lsave_fpu_regs_done: 1004.Lsave_fpu_regs_done:
1062 oi __LC_CPU_FLAGS+7,_CIF_FPU 1005 oi __LC_CPU_FLAGS+7,_CIF_FPU
1063.Lsave_fpu_regs_exit: 1006.Lsave_fpu_regs_exit:
1064 BR_R1USE_R14 1007 BR_EX %r14
1065.Lsave_fpu_regs_end: 1008.Lsave_fpu_regs_end:
1066EXPORT_SYMBOL(save_fpu_regs) 1009EXPORT_SYMBOL(save_fpu_regs)
1067 1010
@@ -1107,7 +1050,7 @@ load_fpu_regs:
1107.Lload_fpu_regs_done: 1050.Lload_fpu_regs_done:
1108 ni __LC_CPU_FLAGS+7,255-_CIF_FPU 1051 ni __LC_CPU_FLAGS+7,255-_CIF_FPU
1109.Lload_fpu_regs_exit: 1052.Lload_fpu_regs_exit:
1110 BR_R1USE_R14 1053 BR_EX %r14
1111.Lload_fpu_regs_end: 1054.Lload_fpu_regs_end:
1112 1055
1113.L__critical_end: 1056.L__critical_end:
@@ -1322,7 +1265,7 @@ cleanup_critical:
1322 jl 0f 1265 jl 0f
1323 clg %r9,BASED(.Lcleanup_table+104) # .Lload_fpu_regs_end 1266 clg %r9,BASED(.Lcleanup_table+104) # .Lload_fpu_regs_end
1324 jl .Lcleanup_load_fpu_regs 1267 jl .Lcleanup_load_fpu_regs
13250: BR_R11USE_R14 12680: BR_EX %r14
1326 1269
1327 .align 8 1270 .align 8
1328.Lcleanup_table: 1271.Lcleanup_table:
@@ -1358,7 +1301,7 @@ cleanup_critical:
1358 ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE 1301 ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
1359 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce 1302 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
1360 larl %r9,sie_exit # skip forward to sie_exit 1303 larl %r9,sie_exit # skip forward to sie_exit
1361 BR_R11USE_R14 1304 BR_EX %r14
1362#endif 1305#endif
1363 1306
1364.Lcleanup_system_call: 1307.Lcleanup_system_call:
@@ -1412,7 +1355,7 @@ cleanup_critical:
1412 stg %r15,56(%r11) # r15 stack pointer 1355 stg %r15,56(%r11) # r15 stack pointer
1413 # set new psw address and exit 1356 # set new psw address and exit
1414 larl %r9,.Lsysc_do_svc 1357 larl %r9,.Lsysc_do_svc
1415 BR_R11USE_R14 1358 BR_EX %r14,%r11
1416.Lcleanup_system_call_insn: 1359.Lcleanup_system_call_insn:
1417 .quad system_call 1360 .quad system_call
1418 .quad .Lsysc_stmg 1361 .quad .Lsysc_stmg
@@ -1424,7 +1367,7 @@ cleanup_critical:
1424 1367
1425.Lcleanup_sysc_tif: 1368.Lcleanup_sysc_tif:
1426 larl %r9,.Lsysc_tif 1369 larl %r9,.Lsysc_tif
1427 BR_R11USE_R14 1370 BR_EX %r14,%r11
1428 1371
1429.Lcleanup_sysc_restore: 1372.Lcleanup_sysc_restore:
1430 # check if stpt has been executed 1373 # check if stpt has been executed
@@ -1441,14 +1384,14 @@ cleanup_critical:
1441 mvc 0(64,%r11),__PT_R8(%r9) 1384 mvc 0(64,%r11),__PT_R8(%r9)
1442 lmg %r0,%r7,__PT_R0(%r9) 1385 lmg %r0,%r7,__PT_R0(%r9)
14431: lmg %r8,%r9,__LC_RETURN_PSW 13861: lmg %r8,%r9,__LC_RETURN_PSW
1444 BR_R11USE_R14 1387 BR_EX %r14,%r11
1445.Lcleanup_sysc_restore_insn: 1388.Lcleanup_sysc_restore_insn:
1446 .quad .Lsysc_exit_timer 1389 .quad .Lsysc_exit_timer
1447 .quad .Lsysc_done - 4 1390 .quad .Lsysc_done - 4
1448 1391
1449.Lcleanup_io_tif: 1392.Lcleanup_io_tif:
1450 larl %r9,.Lio_tif 1393 larl %r9,.Lio_tif
1451 BR_R11USE_R14 1394 BR_EX %r14,%r11
1452 1395
1453.Lcleanup_io_restore: 1396.Lcleanup_io_restore:
1454 # check if stpt has been executed 1397 # check if stpt has been executed
@@ -1462,7 +1405,7 @@ cleanup_critical:
1462 mvc 0(64,%r11),__PT_R8(%r9) 1405 mvc 0(64,%r11),__PT_R8(%r9)
1463 lmg %r0,%r7,__PT_R0(%r9) 1406 lmg %r0,%r7,__PT_R0(%r9)
14641: lmg %r8,%r9,__LC_RETURN_PSW 14071: lmg %r8,%r9,__LC_RETURN_PSW
1465 BR_R11USE_R14 1408 BR_EX %r14,%r11
1466.Lcleanup_io_restore_insn: 1409.Lcleanup_io_restore_insn:
1467 .quad .Lio_exit_timer 1410 .quad .Lio_exit_timer
1468 .quad .Lio_done - 4 1411 .quad .Lio_done - 4
@@ -1515,17 +1458,17 @@ cleanup_critical:
1515 # prepare return psw 1458 # prepare return psw
1516 nihh %r8,0xfcfd # clear irq & wait state bits 1459 nihh %r8,0xfcfd # clear irq & wait state bits
1517 lg %r9,48(%r11) # return from psw_idle 1460 lg %r9,48(%r11) # return from psw_idle
1518 BR_R11USE_R14 1461 BR_EX %r14,%r11
1519.Lcleanup_idle_insn: 1462.Lcleanup_idle_insn:
1520 .quad .Lpsw_idle_lpsw 1463 .quad .Lpsw_idle_lpsw
1521 1464
1522.Lcleanup_save_fpu_regs: 1465.Lcleanup_save_fpu_regs:
1523 larl %r9,save_fpu_regs 1466 larl %r9,save_fpu_regs
1524 BR_R11USE_R14 1467 BR_EX %r14,%r11
1525 1468
1526.Lcleanup_load_fpu_regs: 1469.Lcleanup_load_fpu_regs:
1527 larl %r9,load_fpu_regs 1470 larl %r9,load_fpu_regs
1528 BR_R11USE_R14 1471 BR_EX %r14,%r11
1529 1472
1530/* 1473/*
1531 * Integer constants 1474 * Integer constants
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 94f2099bceb0..3d17c41074ca 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -176,10 +176,9 @@ void do_softirq_own_stack(void)
176 new -= STACK_FRAME_OVERHEAD; 176 new -= STACK_FRAME_OVERHEAD;
177 ((struct stack_frame *) new)->back_chain = old; 177 ((struct stack_frame *) new)->back_chain = old;
178 asm volatile(" la 15,0(%0)\n" 178 asm volatile(" la 15,0(%0)\n"
179 " basr 14,%2\n" 179 " brasl 14,__do_softirq\n"
180 " la 15,0(%1)\n" 180 " la 15,0(%1)\n"
181 : : "a" (new), "a" (old), 181 : : "a" (new), "a" (old)
182 "a" (__do_softirq)
183 : "0", "1", "2", "3", "4", "5", "14", 182 : "0", "1", "2", "3", "4", "5", "14",
184 "cc", "memory" ); 183 "cc", "memory" );
185 } else { 184 } else {
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
diff --git a/arch/s390/kernel/nospec-branch.c b/arch/s390/kernel/nospec-branch.c
index 46d49a11663f..8ad6a7128b3a 100644
--- a/arch/s390/kernel/nospec-branch.c
+++ b/arch/s390/kernel/nospec-branch.c
@@ -1,7 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <linux/module.h> 2#include <linux/module.h>
3#include <linux/device.h> 3#include <linux/device.h>
4#include <linux/cpu.h>
5#include <asm/nospec-branch.h> 4#include <asm/nospec-branch.h>
6 5
7static int __init nobp_setup_early(char *str) 6static int __init nobp_setup_early(char *str)
@@ -44,24 +43,6 @@ static int __init nospec_report(void)
44} 43}
45arch_initcall(nospec_report); 44arch_initcall(nospec_report);
46 45
47#ifdef CONFIG_SYSFS
48ssize_t cpu_show_spectre_v1(struct device *dev,
49 struct device_attribute *attr, char *buf)
50{
51 return sprintf(buf, "Mitigation: __user pointer sanitization\n");
52}
53
54ssize_t cpu_show_spectre_v2(struct device *dev,
55 struct device_attribute *attr, char *buf)
56{
57 if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable)
58 return sprintf(buf, "Mitigation: execute trampolines\n");
59 if (__test_facility(82, S390_lowcore.alt_stfle_fac_list))
60 return sprintf(buf, "Mitigation: limited branch prediction.\n");
61 return sprintf(buf, "Vulnerable\n");
62}
63#endif
64
65#ifdef CONFIG_EXPOLINE 46#ifdef CONFIG_EXPOLINE
66 47
67int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF); 48int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF);
@@ -112,7 +93,6 @@ static void __init_or_module __nospec_revert(s32 *start, s32 *end)
112 s32 *epo; 93 s32 *epo;
113 94
114 /* Second part of the instruction replace is always a nop */ 95 /* Second part of the instruction replace is always a nop */
115 memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x00, 0x00 }, 4);
116 for (epo = start; epo < end; epo++) { 96 for (epo = start; epo < end; epo++) {
117 instr = (u8 *) epo + *epo; 97 instr = (u8 *) epo + *epo;
118 if (instr[0] == 0xc0 && (instr[1] & 0x0f) == 0x04) 98 if (instr[0] == 0xc0 && (instr[1] & 0x0f) == 0x04)
@@ -133,18 +113,34 @@ static void __init_or_module __nospec_revert(s32 *start, s32 *end)
133 br = thunk + (*(int *)(thunk + 2)) * 2; 113 br = thunk + (*(int *)(thunk + 2)) * 2;
134 else 114 else
135 continue; 115 continue;
136 if (br[0] != 0x07 || (br[1] & 0xf0) != 0xf0) 116 /* Check for unconditional branch 0x07f? or 0x47f???? */
117 if ((br[0] & 0xbf) != 0x07 || (br[1] & 0xf0) != 0xf0)
137 continue; 118 continue;
119
120 memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x07, 0x00 }, 4);
138 switch (type) { 121 switch (type) {
139 case BRCL_EXPOLINE: 122 case BRCL_EXPOLINE:
140 /* brcl to thunk, replace with br + nop */
141 insnbuf[0] = br[0]; 123 insnbuf[0] = br[0];
142 insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f); 124 insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f);
125 if (br[0] == 0x47) {
126 /* brcl to b, replace with bc + nopr */
127 insnbuf[2] = br[2];
128 insnbuf[3] = br[3];
129 } else {
130 /* brcl to br, replace with bcr + nop */
131 }
143 break; 132 break;
144 case BRASL_EXPOLINE: 133 case BRASL_EXPOLINE:
145 /* brasl to thunk, replace with basr + nop */
146 insnbuf[0] = 0x0d;
147 insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f); 134 insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f);
135 if (br[0] == 0x47) {
136 /* brasl to b, replace with bas + nopr */
137 insnbuf[0] = 0x4d;
138 insnbuf[2] = br[2];
139 insnbuf[3] = br[3];
140 } else {
141 /* brasl to br, replace with basr + nop */
142 insnbuf[0] = 0x0d;
143 }
148 break; 144 break;
149 } 145 }
150 146
diff --git a/arch/s390/kernel/nospec-sysfs.c b/arch/s390/kernel/nospec-sysfs.c
new file mode 100644
index 000000000000..8affad5f18cb
--- /dev/null
+++ b/arch/s390/kernel/nospec-sysfs.c
@@ -0,0 +1,21 @@
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/device.h>
3#include <linux/cpu.h>
4#include <asm/facility.h>
5#include <asm/nospec-branch.h>
6
7ssize_t cpu_show_spectre_v1(struct device *dev,
8 struct device_attribute *attr, char *buf)
9{
10 return sprintf(buf, "Mitigation: __user pointer sanitization\n");
11}
12
13ssize_t cpu_show_spectre_v2(struct device *dev,
14 struct device_attribute *attr, char *buf)
15{
16 if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable)
17 return sprintf(buf, "Mitigation: execute trampolines\n");
18 if (__test_facility(82, S390_lowcore.alt_stfle_fac_list))
19 return sprintf(buf, "Mitigation: limited branch prediction\n");
20 return sprintf(buf, "Vulnerable\n");
21}
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c
index 1c9ddd7aa5ec..0292d68e7dde 100644
--- a/arch/s390/kernel/perf_cpum_sf.c
+++ b/arch/s390/kernel/perf_cpum_sf.c
@@ -753,6 +753,10 @@ static int __hw_perf_event_init(struct perf_event *event)
753 */ 753 */
754 rate = 0; 754 rate = 0;
755 if (attr->freq) { 755 if (attr->freq) {
756 if (!attr->sample_freq) {
757 err = -EINVAL;
758 goto out;
759 }
756 rate = freq_to_sample_rate(&si, attr->sample_freq); 760 rate = freq_to_sample_rate(&si, attr->sample_freq);
757 rate = hw_limit_rate(&si, rate); 761 rate = hw_limit_rate(&si, rate);
758 attr->freq = 0; 762 attr->freq = 0;
diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S
index 73cc3750f0d3..7f14adf512c6 100644
--- a/arch/s390/kernel/reipl.S
+++ b/arch/s390/kernel/reipl.S
@@ -7,8 +7,11 @@
7 7
8#include <linux/linkage.h> 8#include <linux/linkage.h>
9#include <asm/asm-offsets.h> 9#include <asm/asm-offsets.h>
10#include <asm/nospec-insn.h>
10#include <asm/sigp.h> 11#include <asm/sigp.h>
11 12
13 GEN_BR_THUNK %r9
14
12# 15#
13# Issue "store status" for the current CPU to its prefix page 16# Issue "store status" for the current CPU to its prefix page
14# and call passed function afterwards 17# and call passed function afterwards
@@ -67,9 +70,9 @@ ENTRY(store_status)
67 st %r4,0(%r1) 70 st %r4,0(%r1)
68 st %r5,4(%r1) 71 st %r5,4(%r1)
69 stg %r2,8(%r1) 72 stg %r2,8(%r1)
70 lgr %r1,%r2 73 lgr %r9,%r2
71 lgr %r2,%r3 74 lgr %r2,%r3
72 br %r1 75 BR_EX %r9
73 76
74 .section .bss 77 .section .bss
75 .align 8 78 .align 8
diff --git a/arch/s390/kernel/swsusp.S b/arch/s390/kernel/swsusp.S
index e99187149f17..a049a7b9d6e8 100644
--- a/arch/s390/kernel/swsusp.S
+++ b/arch/s390/kernel/swsusp.S
@@ -13,6 +13,7 @@
13#include <asm/ptrace.h> 13#include <asm/ptrace.h>
14#include <asm/thread_info.h> 14#include <asm/thread_info.h>
15#include <asm/asm-offsets.h> 15#include <asm/asm-offsets.h>
16#include <asm/nospec-insn.h>
16#include <asm/sigp.h> 17#include <asm/sigp.h>
17 18
18/* 19/*
@@ -24,6 +25,8 @@
24 * (see below) in the resume process. 25 * (see below) in the resume process.
25 * This function runs with disabled interrupts. 26 * This function runs with disabled interrupts.
26 */ 27 */
28 GEN_BR_THUNK %r14
29
27 .section .text 30 .section .text
28ENTRY(swsusp_arch_suspend) 31ENTRY(swsusp_arch_suspend)
29 stmg %r6,%r15,__SF_GPRS(%r15) 32 stmg %r6,%r15,__SF_GPRS(%r15)
@@ -103,7 +106,7 @@ ENTRY(swsusp_arch_suspend)
103 spx 0x318(%r1) 106 spx 0x318(%r1)
104 lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) 107 lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
105 lghi %r2,0 108 lghi %r2,0
106 br %r14 109 BR_EX %r14
107 110
108/* 111/*
109 * Restore saved memory image to correct place and restore register context. 112 * Restore saved memory image to correct place and restore register context.
@@ -197,11 +200,10 @@ pgm_check_entry:
197 larl %r15,init_thread_union 200 larl %r15,init_thread_union
198 ahi %r15,1<<(PAGE_SHIFT+THREAD_SIZE_ORDER) 201 ahi %r15,1<<(PAGE_SHIFT+THREAD_SIZE_ORDER)
199 larl %r2,.Lpanic_string 202 larl %r2,.Lpanic_string
200 larl %r3,sclp_early_printk
201 lghi %r1,0 203 lghi %r1,0
202 sam31 204 sam31
203 sigp %r1,%r0,SIGP_SET_ARCHITECTURE 205 sigp %r1,%r0,SIGP_SET_ARCHITECTURE
204 basr %r14,%r3 206 brasl %r14,sclp_early_printk
205 larl %r3,.Ldisabled_wait_31 207 larl %r3,.Ldisabled_wait_31
206 lpsw 0(%r3) 208 lpsw 0(%r3)
2074: 2094:
@@ -267,7 +269,7 @@ restore_registers:
267 /* Return 0 */ 269 /* Return 0 */
268 lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) 270 lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
269 lghi %r2,0 271 lghi %r2,0
270 br %r14 272 BR_EX %r14
271 273
272 .section .data..nosave,"aw",@progbits 274 .section .data..nosave,"aw",@progbits
273 .align 8 275 .align 8
diff --git a/arch/s390/lib/mem.S b/arch/s390/lib/mem.S
index 495c9c4bacc7..2311f15be9cf 100644
--- a/arch/s390/lib/mem.S
+++ b/arch/s390/lib/mem.S
@@ -7,6 +7,9 @@
7 7
8#include <linux/linkage.h> 8#include <linux/linkage.h>
9#include <asm/export.h> 9#include <asm/export.h>
10#include <asm/nospec-insn.h>
11
12 GEN_BR_THUNK %r14
10 13
11/* 14/*
12 * void *memmove(void *dest, const void *src, size_t n) 15 * void *memmove(void *dest, const void *src, size_t n)
@@ -33,14 +36,14 @@ ENTRY(memmove)
33.Lmemmove_forward_remainder: 36.Lmemmove_forward_remainder:
34 larl %r5,.Lmemmove_mvc 37 larl %r5,.Lmemmove_mvc
35 ex %r4,0(%r5) 38 ex %r4,0(%r5)
36 br %r14 39 BR_EX %r14
37.Lmemmove_reverse: 40.Lmemmove_reverse:
38 ic %r0,0(%r4,%r3) 41 ic %r0,0(%r4,%r3)
39 stc %r0,0(%r4,%r1) 42 stc %r0,0(%r4,%r1)
40 brctg %r4,.Lmemmove_reverse 43 brctg %r4,.Lmemmove_reverse
41 ic %r0,0(%r4,%r3) 44 ic %r0,0(%r4,%r3)
42 stc %r0,0(%r4,%r1) 45 stc %r0,0(%r4,%r1)
43 br %r14 46 BR_EX %r14
44.Lmemmove_mvc: 47.Lmemmove_mvc:
45 mvc 0(1,%r1),0(%r3) 48 mvc 0(1,%r1),0(%r3)
46EXPORT_SYMBOL(memmove) 49EXPORT_SYMBOL(memmove)
@@ -77,7 +80,7 @@ ENTRY(memset)
77.Lmemset_clear_remainder: 80.Lmemset_clear_remainder:
78 larl %r3,.Lmemset_xc 81 larl %r3,.Lmemset_xc
79 ex %r4,0(%r3) 82 ex %r4,0(%r3)
80 br %r14 83 BR_EX %r14
81.Lmemset_fill: 84.Lmemset_fill:
82 cghi %r4,1 85 cghi %r4,1
83 lgr %r1,%r2 86 lgr %r1,%r2
@@ -95,10 +98,10 @@ ENTRY(memset)
95 stc %r3,0(%r1) 98 stc %r3,0(%r1)
96 larl %r5,.Lmemset_mvc 99 larl %r5,.Lmemset_mvc
97 ex %r4,0(%r5) 100 ex %r4,0(%r5)
98 br %r14 101 BR_EX %r14
99.Lmemset_fill_exit: 102.Lmemset_fill_exit:
100 stc %r3,0(%r1) 103 stc %r3,0(%r1)
101 br %r14 104 BR_EX %r14
102.Lmemset_xc: 105.Lmemset_xc:
103 xc 0(1,%r1),0(%r1) 106 xc 0(1,%r1),0(%r1)
104.Lmemset_mvc: 107.Lmemset_mvc:
@@ -121,7 +124,7 @@ ENTRY(memcpy)
121.Lmemcpy_remainder: 124.Lmemcpy_remainder:
122 larl %r5,.Lmemcpy_mvc 125 larl %r5,.Lmemcpy_mvc
123 ex %r4,0(%r5) 126 ex %r4,0(%r5)
124 br %r14 127 BR_EX %r14
125.Lmemcpy_loop: 128.Lmemcpy_loop:
126 mvc 0(256,%r1),0(%r3) 129 mvc 0(256,%r1),0(%r3)
127 la %r1,256(%r1) 130 la %r1,256(%r1)
@@ -159,10 +162,10 @@ ENTRY(__memset\bits)
159 \insn %r3,0(%r1) 162 \insn %r3,0(%r1)
160 larl %r5,.L__memset_mvc\bits 163 larl %r5,.L__memset_mvc\bits
161 ex %r4,0(%r5) 164 ex %r4,0(%r5)
162 br %r14 165 BR_EX %r14
163.L__memset_exit\bits: 166.L__memset_exit\bits:
164 \insn %r3,0(%r2) 167 \insn %r3,0(%r2)
165 br %r14 168 BR_EX %r14
166.L__memset_mvc\bits: 169.L__memset_mvc\bits:
167 mvc \bytes(1,%r1),0(%r1) 170 mvc \bytes(1,%r1),0(%r1)
168.endm 171.endm
diff --git a/arch/s390/net/bpf_jit.S b/arch/s390/net/bpf_jit.S
index 25bb4643c4f4..9f794869c1b0 100644
--- a/arch/s390/net/bpf_jit.S
+++ b/arch/s390/net/bpf_jit.S
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include <linux/linkage.h> 11#include <linux/linkage.h>
12#include <asm/nospec-insn.h>
12#include "bpf_jit.h" 13#include "bpf_jit.h"
13 14
14/* 15/*
@@ -54,7 +55,7 @@ ENTRY(sk_load_##NAME##_pos); \
54 clg %r3,STK_OFF_HLEN(%r15); /* Offset + SIZE > hlen? */ \ 55 clg %r3,STK_OFF_HLEN(%r15); /* Offset + SIZE > hlen? */ \
55 jh sk_load_##NAME##_slow; \ 56 jh sk_load_##NAME##_slow; \
56 LOAD %r14,-SIZE(%r3,%r12); /* Get data from skb */ \ 57 LOAD %r14,-SIZE(%r3,%r12); /* Get data from skb */ \
57 b OFF_OK(%r6); /* Return */ \ 58 B_EX OFF_OK,%r6; /* Return */ \
58 \ 59 \
59sk_load_##NAME##_slow:; \ 60sk_load_##NAME##_slow:; \
60 lgr %r2,%r7; /* Arg1 = skb pointer */ \ 61 lgr %r2,%r7; /* Arg1 = skb pointer */ \
@@ -64,11 +65,14 @@ sk_load_##NAME##_slow:; \
64 brasl %r14,skb_copy_bits; /* Get data from skb */ \ 65 brasl %r14,skb_copy_bits; /* Get data from skb */ \
65 LOAD %r14,STK_OFF_TMP(%r15); /* Load from temp bufffer */ \ 66 LOAD %r14,STK_OFF_TMP(%r15); /* Load from temp bufffer */ \
66 ltgr %r2,%r2; /* Set cc to (%r2 != 0) */ \ 67 ltgr %r2,%r2; /* Set cc to (%r2 != 0) */ \
67 br %r6; /* Return */ 68 BR_EX %r6; /* Return */
68 69
69sk_load_common(word, 4, llgf) /* r14 = *(u32 *) (skb->data+offset) */ 70sk_load_common(word, 4, llgf) /* r14 = *(u32 *) (skb->data+offset) */
70sk_load_common(half, 2, llgh) /* r14 = *(u16 *) (skb->data+offset) */ 71sk_load_common(half, 2, llgh) /* r14 = *(u16 *) (skb->data+offset) */
71 72
73 GEN_BR_THUNK %r6
74 GEN_B_THUNK OFF_OK,%r6
75
72/* 76/*
73 * Load 1 byte from SKB (optimized version) 77 * Load 1 byte from SKB (optimized version)
74 */ 78 */
@@ -80,7 +84,7 @@ ENTRY(sk_load_byte_pos)
80 clg %r3,STK_OFF_HLEN(%r15) # Offset >= hlen? 84 clg %r3,STK_OFF_HLEN(%r15) # Offset >= hlen?
81 jnl sk_load_byte_slow 85 jnl sk_load_byte_slow
82 llgc %r14,0(%r3,%r12) # Get byte from skb 86 llgc %r14,0(%r3,%r12) # Get byte from skb
83 b OFF_OK(%r6) # Return OK 87 B_EX OFF_OK,%r6 # Return OK
84 88
85sk_load_byte_slow: 89sk_load_byte_slow:
86 lgr %r2,%r7 # Arg1 = skb pointer 90 lgr %r2,%r7 # Arg1 = skb pointer
@@ -90,7 +94,7 @@ sk_load_byte_slow:
90 brasl %r14,skb_copy_bits # Get data from skb 94 brasl %r14,skb_copy_bits # Get data from skb
91 llgc %r14,STK_OFF_TMP(%r15) # Load result from temp buffer 95 llgc %r14,STK_OFF_TMP(%r15) # Load result from temp buffer
92 ltgr %r2,%r2 # Set cc to (%r2 != 0) 96 ltgr %r2,%r2 # Set cc to (%r2 != 0)
93 br %r6 # Return cc 97 BR_EX %r6 # Return cc
94 98
95#define sk_negative_common(NAME, SIZE, LOAD) \ 99#define sk_negative_common(NAME, SIZE, LOAD) \
96sk_load_##NAME##_slow_neg:; \ 100sk_load_##NAME##_slow_neg:; \
@@ -104,7 +108,7 @@ sk_load_##NAME##_slow_neg:; \
104 jz bpf_error; \ 108 jz bpf_error; \
105 LOAD %r14,0(%r2); /* Get data from pointer */ \ 109 LOAD %r14,0(%r2); /* Get data from pointer */ \
106 xr %r3,%r3; /* Set cc to zero */ \ 110 xr %r3,%r3; /* Set cc to zero */ \
107 br %r6; /* Return cc */ 111 BR_EX %r6; /* Return cc */
108 112
109sk_negative_common(word, 4, llgf) 113sk_negative_common(word, 4, llgf)
110sk_negative_common(half, 2, llgh) 114sk_negative_common(half, 2, llgh)
@@ -113,4 +117,4 @@ sk_negative_common(byte, 1, llgc)
113bpf_error: 117bpf_error:
114# force a return 0 from jit handler 118# force a return 0 from jit handler
115 ltgr %r15,%r15 # Set condition code 119 ltgr %r15,%r15 # Set condition code
116 br %r6 120 BR_EX %r6
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
index 78a19c93b380..dd2bcf0e7d00 100644
--- a/arch/s390/net/bpf_jit_comp.c
+++ b/arch/s390/net/bpf_jit_comp.c
@@ -25,6 +25,8 @@
25#include <linux/bpf.h> 25#include <linux/bpf.h>
26#include <asm/cacheflush.h> 26#include <asm/cacheflush.h>
27#include <asm/dis.h> 27#include <asm/dis.h>
28#include <asm/facility.h>
29#include <asm/nospec-branch.h>
28#include <asm/set_memory.h> 30#include <asm/set_memory.h>
29#include "bpf_jit.h" 31#include "bpf_jit.h"
30 32
@@ -41,6 +43,8 @@ struct bpf_jit {
41 int base_ip; /* Base address for literal pool */ 43 int base_ip; /* Base address for literal pool */
42 int ret0_ip; /* Address of return 0 */ 44 int ret0_ip; /* Address of return 0 */
43 int exit_ip; /* Address of exit */ 45 int exit_ip; /* Address of exit */
46 int r1_thunk_ip; /* Address of expoline thunk for 'br %r1' */
47 int r14_thunk_ip; /* Address of expoline thunk for 'br %r14' */
44 int tail_call_start; /* Tail call start offset */ 48 int tail_call_start; /* Tail call start offset */
45 int labels[1]; /* Labels for local jumps */ 49 int labels[1]; /* Labels for local jumps */
46}; 50};
@@ -250,6 +254,19 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
250 REG_SET_SEEN(b2); \ 254 REG_SET_SEEN(b2); \
251}) 255})
252 256
257#define EMIT6_PCREL_RILB(op, b, target) \
258({ \
259 int rel = (target - jit->prg) / 2; \
260 _EMIT6(op | reg_high(b) << 16 | rel >> 16, rel & 0xffff); \
261 REG_SET_SEEN(b); \
262})
263
264#define EMIT6_PCREL_RIL(op, target) \
265({ \
266 int rel = (target - jit->prg) / 2; \
267 _EMIT6(op | rel >> 16, rel & 0xffff); \
268})
269
253#define _EMIT6_IMM(op, imm) \ 270#define _EMIT6_IMM(op, imm) \
254({ \ 271({ \
255 unsigned int __imm = (imm); \ 272 unsigned int __imm = (imm); \
@@ -469,8 +486,45 @@ static void bpf_jit_epilogue(struct bpf_jit *jit, u32 stack_depth)
469 EMIT4(0xb9040000, REG_2, BPF_REG_0); 486 EMIT4(0xb9040000, REG_2, BPF_REG_0);
470 /* Restore registers */ 487 /* Restore registers */
471 save_restore_regs(jit, REGS_RESTORE, stack_depth); 488 save_restore_regs(jit, REGS_RESTORE, stack_depth);
489 if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) {
490 jit->r14_thunk_ip = jit->prg;
491 /* Generate __s390_indirect_jump_r14 thunk */
492 if (test_facility(35)) {
493 /* exrl %r0,.+10 */
494 EMIT6_PCREL_RIL(0xc6000000, jit->prg + 10);
495 } else {
496 /* larl %r1,.+14 */
497 EMIT6_PCREL_RILB(0xc0000000, REG_1, jit->prg + 14);
498 /* ex 0,0(%r1) */
499 EMIT4_DISP(0x44000000, REG_0, REG_1, 0);
500 }
501 /* j . */
502 EMIT4_PCREL(0xa7f40000, 0);
503 }
472 /* br %r14 */ 504 /* br %r14 */
473 _EMIT2(0x07fe); 505 _EMIT2(0x07fe);
506
507 if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable &&
508 (jit->seen & SEEN_FUNC)) {
509 jit->r1_thunk_ip = jit->prg;
510 /* Generate __s390_indirect_jump_r1 thunk */
511 if (test_facility(35)) {
512 /* exrl %r0,.+10 */
513 EMIT6_PCREL_RIL(0xc6000000, jit->prg + 10);
514 /* j . */
515 EMIT4_PCREL(0xa7f40000, 0);
516 /* br %r1 */
517 _EMIT2(0x07f1);
518 } else {
519 /* larl %r1,.+14 */
520 EMIT6_PCREL_RILB(0xc0000000, REG_1, jit->prg + 14);
521 /* ex 0,S390_lowcore.br_r1_tampoline */
522 EMIT4_DISP(0x44000000, REG_0, REG_0,
523 offsetof(struct lowcore, br_r1_trampoline));
524 /* j . */
525 EMIT4_PCREL(0xa7f40000, 0);
526 }
527 }
474} 528}
475 529
476/* 530/*
@@ -966,8 +1020,13 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
966 /* lg %w1,<d(imm)>(%l) */ 1020 /* lg %w1,<d(imm)>(%l) */
967 EMIT6_DISP_LH(0xe3000000, 0x0004, REG_W1, REG_0, REG_L, 1021 EMIT6_DISP_LH(0xe3000000, 0x0004, REG_W1, REG_0, REG_L,
968 EMIT_CONST_U64(func)); 1022 EMIT_CONST_U64(func));
969 /* basr %r14,%w1 */ 1023 if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) {
970 EMIT2(0x0d00, REG_14, REG_W1); 1024 /* brasl %r14,__s390_indirect_jump_r1 */
1025 EMIT6_PCREL_RILB(0xc0050000, REG_14, jit->r1_thunk_ip);
1026 } else {
1027 /* basr %r14,%w1 */
1028 EMIT2(0x0d00, REG_14, REG_W1);
1029 }
971 /* lgr %b0,%r2: load return value into %b0 */ 1030 /* lgr %b0,%r2: load return value into %b0 */
972 EMIT4(0xb9040000, BPF_REG_0, REG_2); 1031 EMIT4(0xb9040000, BPF_REG_0, REG_2);
973 if ((jit->seen & SEEN_SKB) && 1032 if ((jit->seen & SEEN_SKB) &&
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 439991d71b14..4c14ce428e92 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -141,7 +141,7 @@ static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues)
141 int i; 141 int i;
142 142
143 for (i = 0; i < nr_queues; i++) { 143 for (i = 0; i < nr_queues; i++) {
144 q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL); 144 q = kmem_cache_zalloc(qdio_q_cache, GFP_KERNEL);
145 if (!q) 145 if (!q)
146 return -ENOMEM; 146 return -ENOMEM;
147 147
@@ -456,7 +456,6 @@ int qdio_setup_irq(struct qdio_initialize *init_data)
456{ 456{
457 struct ciw *ciw; 457 struct ciw *ciw;
458 struct qdio_irq *irq_ptr = init_data->cdev->private->qdio_data; 458 struct qdio_irq *irq_ptr = init_data->cdev->private->qdio_data;
459 int rc;
460 459
461 memset(&irq_ptr->qib, 0, sizeof(irq_ptr->qib)); 460 memset(&irq_ptr->qib, 0, sizeof(irq_ptr->qib));
462 memset(&irq_ptr->siga_flag, 0, sizeof(irq_ptr->siga_flag)); 461 memset(&irq_ptr->siga_flag, 0, sizeof(irq_ptr->siga_flag));
@@ -493,16 +492,14 @@ int qdio_setup_irq(struct qdio_initialize *init_data)
493 ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_EQUEUE); 492 ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_EQUEUE);
494 if (!ciw) { 493 if (!ciw) {
495 DBF_ERROR("%4x NO EQ", irq_ptr->schid.sch_no); 494 DBF_ERROR("%4x NO EQ", irq_ptr->schid.sch_no);
496 rc = -EINVAL; 495 return -EINVAL;
497 goto out_err;
498 } 496 }
499 irq_ptr->equeue = *ciw; 497 irq_ptr->equeue = *ciw;
500 498
501 ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_AQUEUE); 499 ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_AQUEUE);
502 if (!ciw) { 500 if (!ciw) {
503 DBF_ERROR("%4x NO AQ", irq_ptr->schid.sch_no); 501 DBF_ERROR("%4x NO AQ", irq_ptr->schid.sch_no);
504 rc = -EINVAL; 502 return -EINVAL;
505 goto out_err;
506 } 503 }
507 irq_ptr->aqueue = *ciw; 504 irq_ptr->aqueue = *ciw;
508 505
@@ -512,9 +509,6 @@ int qdio_setup_irq(struct qdio_initialize *init_data)
512 init_data->cdev->handler = qdio_int_handler; 509 init_data->cdev->handler = qdio_int_handler;
513 spin_unlock_irq(get_ccwdev_lock(irq_ptr->cdev)); 510 spin_unlock_irq(get_ccwdev_lock(irq_ptr->cdev));
514 return 0; 511 return 0;
515out_err:
516 qdio_release_memory(irq_ptr);
517 return rc;
518} 512}
519 513
520void qdio_print_subchannel_info(struct qdio_irq *irq_ptr, 514void qdio_print_subchannel_info(struct qdio_irq *irq_ptr,
diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c
index 2c7550797ec2..dce92b2a895d 100644
--- a/drivers/s390/cio/vfio_ccw_cp.c
+++ b/drivers/s390/cio/vfio_ccw_cp.c
@@ -715,6 +715,10 @@ void cp_free(struct channel_program *cp)
715 * and stores the result to ccwchain list. @cp must have been 715 * and stores the result to ccwchain list. @cp must have been
716 * initialized by a previous call with cp_init(). Otherwise, undefined 716 * initialized by a previous call with cp_init(). Otherwise, undefined
717 * behavior occurs. 717 * behavior occurs.
718 * For each chain composing the channel program:
719 * - On entry ch_len holds the count of CCWs to be translated.
720 * - On exit ch_len is adjusted to the count of successfully translated CCWs.
721 * This allows cp_free to find in ch_len the count of CCWs to free in a chain.
718 * 722 *
719 * The S/390 CCW Translation APIS (prefixed by 'cp_') are introduced 723 * The S/390 CCW Translation APIS (prefixed by 'cp_') are introduced
720 * as helpers to do ccw chain translation inside the kernel. Basically 724 * as helpers to do ccw chain translation inside the kernel. Basically
@@ -749,11 +753,18 @@ int cp_prefetch(struct channel_program *cp)
749 for (idx = 0; idx < len; idx++) { 753 for (idx = 0; idx < len; idx++) {
750 ret = ccwchain_fetch_one(chain, idx, cp); 754 ret = ccwchain_fetch_one(chain, idx, cp);
751 if (ret) 755 if (ret)
752 return ret; 756 goto out_err;
753 } 757 }
754 } 758 }
755 759
756 return 0; 760 return 0;
761out_err:
762 /* Only cleanup the chain elements that were actually translated. */
763 chain->ch_len = idx;
764 list_for_each_entry_continue(chain, &cp->ccwchain_list, next) {
765 chain->ch_len = 0;
766 }
767 return ret;
757} 768}
758 769
759/** 770/**