diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-17 13:11:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-17 13:11:44 -0400 |
commit | 3e9245c5fa3092de19b95f03817b02469bcf146c (patch) | |
tree | a388e64d6cd075d20b355e9e5810ea7f4c361556 | |
parent | 305bb55212822f13ddbfcb7518d999c6369942ba (diff) | |
parent | 2e68adcd2fb21b7188ba449f0fab3bee2910e500 (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-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | arch/s390/configs/debug_defconfig | 9 | ||||
-rw-r--r-- | arch/s390/configs/performance_defconfig | 8 | ||||
-rw-r--r-- | arch/s390/crypto/crc32be-vx.S | 5 | ||||
-rw-r--r-- | arch/s390/crypto/crc32le-vx.S | 4 | ||||
-rw-r--r-- | arch/s390/include/asm/nospec-insn.h | 196 | ||||
-rw-r--r-- | arch/s390/include/asm/purgatory.h | 6 | ||||
-rw-r--r-- | arch/s390/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/s390/kernel/asm-offsets.c | 1 | ||||
-rw-r--r-- | arch/s390/kernel/base.S | 24 | ||||
-rw-r--r-- | arch/s390/kernel/entry.S | 105 | ||||
-rw-r--r-- | arch/s390/kernel/irq.c | 5 | ||||
-rw-r--r-- | arch/s390/kernel/mcount.S | 14 | ||||
-rw-r--r-- | arch/s390/kernel/nospec-branch.c | 44 | ||||
-rw-r--r-- | arch/s390/kernel/nospec-sysfs.c | 21 | ||||
-rw-r--r-- | arch/s390/kernel/perf_cpum_sf.c | 4 | ||||
-rw-r--r-- | arch/s390/kernel/reipl.S | 7 | ||||
-rw-r--r-- | arch/s390/kernel/swsusp.S | 10 | ||||
-rw-r--r-- | arch/s390/lib/mem.S | 19 | ||||
-rw-r--r-- | arch/s390/net/bpf_jit.S | 16 | ||||
-rw-r--r-- | arch/s390/net/bpf_jit_comp.c | 63 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_setup.c | 12 | ||||
-rw-r--r-- | drivers/s390/cio/vfio_ccw_cp.c | 13 |
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 | |||
12220 | F: include/uapi/linux/vfio_ccw.h | 12220 | F: include/uapi/linux/vfio_ccw.h |
12221 | 12221 | ||
12222 | S390 ZCRYPT DRIVER | 12222 | S390 ZCRYPT DRIVER |
12223 | M: Harald Freudenberger <freude@de.ibm.com> | 12223 | M: Harald Freudenberger <freude@linux.ibm.com> |
12224 | L: linux-s390@vger.kernel.org | 12224 | L: linux-s390@vger.kernel.org |
12225 | W: http://www.ibm.com/developerworks/linux/linux390/ | 12225 | W: http://www.ibm.com/developerworks/linux/linux390/ |
12226 | S: Supported | 12226 | S: 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 | |||
261 | CONFIG_IP_VS_FTP=m | 261 | CONFIG_IP_VS_FTP=m |
262 | CONFIG_IP_VS_PE_SIP=m | 262 | CONFIG_IP_VS_PE_SIP=m |
263 | CONFIG_NF_CONNTRACK_IPV4=m | 263 | CONFIG_NF_CONNTRACK_IPV4=m |
264 | CONFIG_NF_TABLES_IPV4=m | 264 | CONFIG_NF_TABLES_IPV4=y |
265 | CONFIG_NFT_CHAIN_ROUTE_IPV4=m | 265 | CONFIG_NFT_CHAIN_ROUTE_IPV4=m |
266 | CONFIG_NF_TABLES_ARP=m | 266 | CONFIG_NF_TABLES_ARP=y |
267 | CONFIG_NFT_CHAIN_NAT_IPV4=m | 267 | CONFIG_NFT_CHAIN_NAT_IPV4=m |
268 | CONFIG_IP_NF_IPTABLES=m | 268 | CONFIG_IP_NF_IPTABLES=m |
269 | CONFIG_IP_NF_MATCH_AH=m | 269 | CONFIG_IP_NF_MATCH_AH=m |
@@ -284,7 +284,7 @@ CONFIG_IP_NF_ARPTABLES=m | |||
284 | CONFIG_IP_NF_ARPFILTER=m | 284 | CONFIG_IP_NF_ARPFILTER=m |
285 | CONFIG_IP_NF_ARP_MANGLE=m | 285 | CONFIG_IP_NF_ARP_MANGLE=m |
286 | CONFIG_NF_CONNTRACK_IPV6=m | 286 | CONFIG_NF_CONNTRACK_IPV6=m |
287 | CONFIG_NF_TABLES_IPV6=m | 287 | CONFIG_NF_TABLES_IPV6=y |
288 | CONFIG_NFT_CHAIN_ROUTE_IPV6=m | 288 | CONFIG_NFT_CHAIN_ROUTE_IPV6=m |
289 | CONFIG_NFT_CHAIN_NAT_IPV6=m | 289 | CONFIG_NFT_CHAIN_NAT_IPV6=m |
290 | CONFIG_IP6_NF_IPTABLES=m | 290 | CONFIG_IP6_NF_IPTABLES=m |
@@ -305,7 +305,7 @@ CONFIG_IP6_NF_RAW=m | |||
305 | CONFIG_IP6_NF_SECURITY=m | 305 | CONFIG_IP6_NF_SECURITY=m |
306 | CONFIG_IP6_NF_NAT=m | 306 | CONFIG_IP6_NF_NAT=m |
307 | CONFIG_IP6_NF_TARGET_MASQUERADE=m | 307 | CONFIG_IP6_NF_TARGET_MASQUERADE=m |
308 | CONFIG_NF_TABLES_BRIDGE=m | 308 | CONFIG_NF_TABLES_BRIDGE=y |
309 | CONFIG_RDS=m | 309 | CONFIG_RDS=m |
310 | CONFIG_RDS_RDMA=m | 310 | CONFIG_RDS_RDMA=m |
311 | CONFIG_RDS_TCP=m | 311 | CONFIG_RDS_TCP=m |
@@ -604,7 +604,6 @@ CONFIG_DETECT_HUNG_TASK=y | |||
604 | CONFIG_WQ_WATCHDOG=y | 604 | CONFIG_WQ_WATCHDOG=y |
605 | CONFIG_PANIC_ON_OOPS=y | 605 | CONFIG_PANIC_ON_OOPS=y |
606 | CONFIG_DEBUG_TIMEKEEPING=y | 606 | CONFIG_DEBUG_TIMEKEEPING=y |
607 | CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y | ||
608 | CONFIG_PROVE_LOCKING=y | 607 | CONFIG_PROVE_LOCKING=y |
609 | CONFIG_LOCK_STAT=y | 608 | CONFIG_LOCK_STAT=y |
610 | CONFIG_DEBUG_LOCKDEP=y | 609 | CONFIG_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 | |||
259 | CONFIG_IP_VS_FTP=m | 259 | CONFIG_IP_VS_FTP=m |
260 | CONFIG_IP_VS_PE_SIP=m | 260 | CONFIG_IP_VS_PE_SIP=m |
261 | CONFIG_NF_CONNTRACK_IPV4=m | 261 | CONFIG_NF_CONNTRACK_IPV4=m |
262 | CONFIG_NF_TABLES_IPV4=m | 262 | CONFIG_NF_TABLES_IPV4=y |
263 | CONFIG_NFT_CHAIN_ROUTE_IPV4=m | 263 | CONFIG_NFT_CHAIN_ROUTE_IPV4=m |
264 | CONFIG_NF_TABLES_ARP=m | 264 | CONFIG_NF_TABLES_ARP=y |
265 | CONFIG_NFT_CHAIN_NAT_IPV4=m | 265 | CONFIG_NFT_CHAIN_NAT_IPV4=m |
266 | CONFIG_IP_NF_IPTABLES=m | 266 | CONFIG_IP_NF_IPTABLES=m |
267 | CONFIG_IP_NF_MATCH_AH=m | 267 | CONFIG_IP_NF_MATCH_AH=m |
@@ -282,7 +282,7 @@ CONFIG_IP_NF_ARPTABLES=m | |||
282 | CONFIG_IP_NF_ARPFILTER=m | 282 | CONFIG_IP_NF_ARPFILTER=m |
283 | CONFIG_IP_NF_ARP_MANGLE=m | 283 | CONFIG_IP_NF_ARP_MANGLE=m |
284 | CONFIG_NF_CONNTRACK_IPV6=m | 284 | CONFIG_NF_CONNTRACK_IPV6=m |
285 | CONFIG_NF_TABLES_IPV6=m | 285 | CONFIG_NF_TABLES_IPV6=y |
286 | CONFIG_NFT_CHAIN_ROUTE_IPV6=m | 286 | CONFIG_NFT_CHAIN_ROUTE_IPV6=m |
287 | CONFIG_NFT_CHAIN_NAT_IPV6=m | 287 | CONFIG_NFT_CHAIN_NAT_IPV6=m |
288 | CONFIG_IP6_NF_IPTABLES=m | 288 | CONFIG_IP6_NF_IPTABLES=m |
@@ -303,7 +303,7 @@ CONFIG_IP6_NF_RAW=m | |||
303 | CONFIG_IP6_NF_SECURITY=m | 303 | CONFIG_IP6_NF_SECURITY=m |
304 | CONFIG_IP6_NF_NAT=m | 304 | CONFIG_IP6_NF_NAT=m |
305 | CONFIG_IP6_NF_TARGET_MASQUERADE=m | 305 | CONFIG_IP6_NF_TARGET_MASQUERADE=m |
306 | CONFIG_NF_TABLES_BRIDGE=m | 306 | CONFIG_NF_TABLES_BRIDGE=y |
307 | CONFIG_RDS=m | 307 | CONFIG_RDS=m |
308 | CONFIG_RDS_RDMA=m | 308 | CONFIG_RDS_RDMA=m |
309 | CONFIG_RDS_TCP=m | 309 | CONFIG_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 | ||
126 | 555: 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 | ||
138 | 556: 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 | ||
154 | 557: __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 | ||
161 | 558: __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 | ||
168 | 559: __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 | ||
14 | int verify_sha256_digest(void); | 14 | int verify_sha256_digest(void); |
15 | 15 | ||
16 | extern u64 kernel_entry; | ||
17 | extern u64 kernel_type; | ||
18 | |||
19 | extern u64 crash_start; | ||
20 | extern 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 | ||
66 | extra-y += head.o head64.o vmlinux.lds | 66 | extra-y += head.o head64.o vmlinux.lds |
67 | 67 | ||
68 | obj-$(CONFIG_SYSFS) += nospec-sysfs.o | ||
68 | CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE) | 69 | CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE) |
69 | 70 | ||
70 | obj-$(CONFIG_MODULES) += module.o | 71 | obj-$(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 | |||
15 | ENTRY(s390_base_mcck_handler) | 19 | ENTRY(s390_base_mcck_handler) |
16 | basr %r13,0 | 20 | basr %r13,0 |
17 | 0: lg %r15,__LC_PANIC_STACK # load panic stack | 21 | 0: 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 |
24 | 1: la %r1,4095 | 28 | 1: 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 |
38 | 0: aghi %r15,-STACK_FRAME_OVERHEAD | 42 | 0: 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 |
44 | 1: lmg %r0,%r15,__LC_SAVE_AREA_ASYNC | 48 | 1: 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 |
58 | 0: aghi %r15,-STACK_FRAME_OVERHEAD | 62 | 0: 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 |
66 | 1: lpswe disabled_wait_psw-0b(%r13) | 70 | 1: 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 . | ||
202 | 0: 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 | ||
211 | 0: 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 | ||
218 | 0: 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 | ||
225 | 0: 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 | |||
260 | ENTRY(__bpon) | 203 | ENTRY(__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 |
620 | ENTRY(kernel_thread_starter) | 563 | ENTRY(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: |
1066 | EXPORT_SYMBOL(save_fpu_regs) | 1009 | EXPORT_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 |
1325 | 0: BR_R11USE_R14 | 1268 | 0: 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) |
1443 | 1: lmg %r8,%r9,__LC_RETURN_PSW | 1386 | 1: 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) |
1464 | 1: lmg %r8,%r9,__LC_RETURN_PSW | 1407 | 1: 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 | ||
17 | ENTRY(ftrace_stub) | 21 | ENTRY(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 | ||
25 | ENTRY(_mcount) | 29 | ENTRY(_mcount) |
26 | br %r14 | 30 | BR_EX %r14 |
27 | 31 | ||
28 | EXPORT_SYMBOL(_mcount) | 32 | EXPORT_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 | ||
7 | static int __init nobp_setup_early(char *str) | 6 | static int __init nobp_setup_early(char *str) |
@@ -44,24 +43,6 @@ static int __init nospec_report(void) | |||
44 | } | 43 | } |
45 | arch_initcall(nospec_report); | 44 | arch_initcall(nospec_report); |
46 | 45 | ||
47 | #ifdef CONFIG_SYSFS | ||
48 | ssize_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 | |||
54 | ssize_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 | ||
67 | int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF); | 48 | int 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 | |||
7 | ssize_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 | |||
13 | ssize_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 |
28 | ENTRY(swsusp_arch_suspend) | 31 | ENTRY(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) |
207 | 4: | 209 | 4: |
@@ -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) |
46 | EXPORT_SYMBOL(memmove) | 49 | EXPORT_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 | \ |
59 | sk_load_##NAME##_slow:; \ | 60 | sk_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 | ||
69 | sk_load_common(word, 4, llgf) /* r14 = *(u32 *) (skb->data+offset) */ | 70 | sk_load_common(word, 4, llgf) /* r14 = *(u32 *) (skb->data+offset) */ |
70 | sk_load_common(half, 2, llgh) /* r14 = *(u16 *) (skb->data+offset) */ | 71 | sk_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 | ||
85 | sk_load_byte_slow: | 89 | sk_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) \ |
96 | sk_load_##NAME##_slow_neg:; \ | 100 | sk_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 | ||
109 | sk_negative_common(word, 4, llgf) | 113 | sk_negative_common(word, 4, llgf) |
110 | sk_negative_common(half, 2, llgh) | 114 | sk_negative_common(half, 2, llgh) |
@@ -113,4 +117,4 @@ sk_negative_common(byte, 1, llgc) | |||
113 | bpf_error: | 117 | bpf_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; |
515 | out_err: | ||
516 | qdio_release_memory(irq_ptr); | ||
517 | return rc; | ||
518 | } | 512 | } |
519 | 513 | ||
520 | void qdio_print_subchannel_info(struct qdio_irq *irq_ptr, | 514 | void 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; |
761 | out_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 | /** |