]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.44/s390-extend-expoline-to-bc-instructions.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.14.44 / s390-extend-expoline-to-bc-instructions.patch
1 From foo@baz Wed May 23 19:38:57 CEST 2018
2 From: Martin Schwidefsky <schwidefsky@de.ibm.com>
3 Date: Wed, 23 May 2018 18:22:08 +0200
4 Subject: s390: extend expoline to BC instructions
5 To: stable@vger.kernel.org
6 Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
7 Message-ID: <1527092529-24383-9-git-send-email-schwidefsky@de.ibm.com>
8
9 From: Martin Schwidefsky <schwidefsky@de.ibm.com>
10
11 [ Upstream commit 6deaa3bbca804b2a3627fd685f75de64da7be535 ]
12
13 The BPF JIT uses a 'b <disp>(%r<x>)' instruction in the definition
14 of the sk_load_word and sk_load_half functions.
15
16 Add support for branch-on-condition instructions contained in the
17 thunk code of an expoline.
18
19 Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
20 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
21 ---
22 arch/s390/include/asm/nospec-insn.h | 57 ++++++++++++++++++++++++++++++++++++
23 arch/s390/kernel/nospec-branch.c | 25 ++++++++++++---
24 2 files changed, 77 insertions(+), 5 deletions(-)
25
26 --- a/arch/s390/include/asm/nospec-insn.h
27 +++ b/arch/s390/include/asm/nospec-insn.h
28 @@ -34,10 +34,18 @@ _LC_BR_R1 = __LC_BR_R1
29 __THUNK_PROLOG_NAME __s390x_indirect_jump_r\r2\()use_r\r1
30 .endm
31
32 + .macro __THUNK_PROLOG_BC d0,r1,r2
33 + __THUNK_PROLOG_NAME __s390x_indirect_branch_\d0\()_\r2\()use_\r1
34 + .endm
35 +
36 .macro __THUNK_BR r1,r2
37 jg __s390x_indirect_jump_r\r2\()use_r\r1
38 .endm
39
40 + .macro __THUNK_BC d0,r1,r2
41 + jg __s390x_indirect_branch_\d0\()_\r2\()use_\r1
42 + .endm
43 +
44 .macro __THUNK_BRASL r1,r2,r3
45 brasl \r1,__s390x_indirect_jump_r\r3\()use_r\r2
46 .endm
47 @@ -80,6 +88,23 @@ _LC_BR_R1 = __LC_BR_R1
48 .endif
49 .endm
50
51 + .macro __DECODE_DRR expand,disp,reg,ruse
52 + .set __decode_fail,1
53 + .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
54 + .ifc \reg,%r\r1
55 + .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
56 + .ifc \ruse,%r\r2
57 + \expand \disp,\r1,\r2
58 + .set __decode_fail,0
59 + .endif
60 + .endr
61 + .endif
62 + .endr
63 + .if __decode_fail == 1
64 + .error "__DECODE_DRR failed"
65 + .endif
66 + .endm
67 +
68 .macro __THUNK_EX_BR reg,ruse
69 # Be very careful when adding instructions to this macro!
70 # The ALTERNATIVE replacement code has a .+10 which targets
71 @@ -100,12 +125,30 @@ _LC_BR_R1 = __LC_BR_R1
72 555: br \reg
73 .endm
74
75 + .macro __THUNK_EX_BC disp,reg,ruse
76 +#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
77 + exrl 0,556f
78 + j .
79 +#else
80 + larl \ruse,556f
81 + ex 0,0(\ruse)
82 + j .
83 +#endif
84 +556: b \disp(\reg)
85 + .endm
86 +
87 .macro GEN_BR_THUNK reg,ruse=%r1
88 __DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse
89 __THUNK_EX_BR \reg,\ruse
90 __THUNK_EPILOG
91 .endm
92
93 + .macro GEN_B_THUNK disp,reg,ruse=%r1
94 + __DECODE_DRR __THUNK_PROLOG_BC,\disp,\reg,\ruse
95 + __THUNK_EX_BC \disp,\reg,\ruse
96 + __THUNK_EPILOG
97 + .endm
98 +
99 .macro BR_EX reg,ruse=%r1
100 557: __DECODE_RR __THUNK_BR,\reg,\ruse
101 .pushsection .s390_indirect_branches,"a",@progbits
102 @@ -113,6 +156,13 @@ _LC_BR_R1 = __LC_BR_R1
103 .popsection
104 .endm
105
106 + .macro B_EX disp,reg,ruse=%r1
107 +558: __DECODE_DRR __THUNK_BC,\disp,\reg,\ruse
108 + .pushsection .s390_indirect_branches,"a",@progbits
109 + .long 558b-.
110 + .popsection
111 + .endm
112 +
113 .macro BASR_EX rsave,rtarget,ruse=%r1
114 559: __DECODE_RRR __THUNK_BRASL,\rsave,\rtarget,\ruse
115 .pushsection .s390_indirect_branches,"a",@progbits
116 @@ -124,10 +174,17 @@ _LC_BR_R1 = __LC_BR_R1
117 .macro GEN_BR_THUNK reg,ruse=%r1
118 .endm
119
120 + .macro GEN_B_THUNK disp,reg,ruse=%r1
121 + .endm
122 +
123 .macro BR_EX reg,ruse=%r1
124 br \reg
125 .endm
126
127 + .macro B_EX disp,reg,ruse=%r1
128 + b \disp(\reg)
129 + .endm
130 +
131 .macro BASR_EX rsave,rtarget,ruse=%r1
132 basr \rsave,\rtarget
133 .endm
134 --- a/arch/s390/kernel/nospec-branch.c
135 +++ b/arch/s390/kernel/nospec-branch.c
136 @@ -94,7 +94,6 @@ static void __init_or_module __nospec_re
137 s32 *epo;
138
139 /* Second part of the instruction replace is always a nop */
140 - memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x00, 0x00 }, 4);
141 for (epo = start; epo < end; epo++) {
142 instr = (u8 *) epo + *epo;
143 if (instr[0] == 0xc0 && (instr[1] & 0x0f) == 0x04)
144 @@ -115,18 +114,34 @@ static void __init_or_module __nospec_re
145 br = thunk + (*(int *)(thunk + 2)) * 2;
146 else
147 continue;
148 - if (br[0] != 0x07 || (br[1] & 0xf0) != 0xf0)
149 + /* Check for unconditional branch 0x07f? or 0x47f???? */
150 + if ((br[0] & 0xbf) != 0x07 || (br[1] & 0xf0) != 0xf0)
151 continue;
152 +
153 + memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x07, 0x00 }, 4);
154 switch (type) {
155 case BRCL_EXPOLINE:
156 - /* brcl to thunk, replace with br + nop */
157 insnbuf[0] = br[0];
158 insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f);
159 + if (br[0] == 0x47) {
160 + /* brcl to b, replace with bc + nopr */
161 + insnbuf[2] = br[2];
162 + insnbuf[3] = br[3];
163 + } else {
164 + /* brcl to br, replace with bcr + nop */
165 + }
166 break;
167 case BRASL_EXPOLINE:
168 - /* brasl to thunk, replace with basr + nop */
169 - insnbuf[0] = 0x0d;
170 insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f);
171 + if (br[0] == 0x47) {
172 + /* brasl to b, replace with bas + nopr */
173 + insnbuf[0] = 0x4d;
174 + insnbuf[2] = br[2];
175 + insnbuf[3] = br[3];
176 + } else {
177 + /* brasl to br, replace with basr + nop */
178 + insnbuf[0] = 0x0d;
179 + }
180 break;
181 }
182