hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/powerpc/net/bpf_jit_comp.c
....@@ -1,14 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* bpf_jit_comp.c: BPF JIT compiler
23 *
34 * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation
45 *
56 * Based on the x86 BPF compiler, by Eric Dumazet (eric.dumazet@gmail.com)
67 * Ported to ppc32 by Denis Kirjanov <kda@linux-powerpc.org>
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License
10
- * as published by the Free Software Foundation; version 2
11
- * of the License.
128 */
139 #include <linux/moduleloader.h>
1410 #include <asm/cacheflush.h>
....@@ -65,7 +61,7 @@
6561 PPC_LWZ_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
6662 data_len));
6763 PPC_LWZ_OFFS(r_HL, r_skb, offsetof(struct sk_buff, len));
68
- PPC_SUB(r_HL, r_HL, r_scratch1);
64
+ EMIT(PPC_RAW_SUB(r_HL, r_HL, r_scratch1));
6965 PPC_LL_OFFS(r_D, r_skb, offsetof(struct sk_buff, data));
7066 }
7167
....@@ -74,12 +70,12 @@
7470 * TODO: Could also detect whether first instr. sets X and
7571 * avoid this (as below, with A).
7672 */
77
- PPC_LI(r_X, 0);
73
+ EMIT(PPC_RAW_LI(r_X, 0));
7874 }
7975
8076 /* make sure we dont leak kernel information to user */
8177 if (bpf_needs_clear_a(&filter[0]))
82
- PPC_LI(r_A, 0);
78
+ EMIT(PPC_RAW_LI(r_A, 0));
8379 }
8480
8581 static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
....@@ -87,10 +83,10 @@
8783 int i;
8884
8985 if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) {
90
- PPC_ADDI(1, 1, BPF_PPC_STACKFRAME);
86
+ EMIT(PPC_RAW_ADDI(1, 1, BPF_PPC_STACKFRAME));
9187 if (ctx->seen & SEEN_DATAREF) {
9288 PPC_BPF_LL(0, 1, PPC_LR_STKOFF);
93
- PPC_MTLR(0);
89
+ EMIT(PPC_RAW_MTLR(0));
9490 PPC_BPF_LL(r_D, 1, -(REG_SZ*(32-r_D)));
9591 PPC_BPF_LL(r_HL, 1, -(REG_SZ*(32-r_HL)));
9692 }
....@@ -104,7 +100,7 @@
104100 }
105101 /* The RETs have left a return value in R3. */
106102
107
- PPC_BLR();
103
+ EMIT(PPC_RAW_BLR());
108104 }
109105
110106 #define CHOOSE_LOAD_FUNC(K, func) \
....@@ -138,124 +134,124 @@
138134 /*** ALU ops ***/
139135 case BPF_ALU | BPF_ADD | BPF_X: /* A += X; */
140136 ctx->seen |= SEEN_XREG;
141
- PPC_ADD(r_A, r_A, r_X);
137
+ EMIT(PPC_RAW_ADD(r_A, r_A, r_X));
142138 break;
143139 case BPF_ALU | BPF_ADD | BPF_K: /* A += K; */
144140 if (!K)
145141 break;
146
- PPC_ADDI(r_A, r_A, IMM_L(K));
142
+ EMIT(PPC_RAW_ADDI(r_A, r_A, IMM_L(K)));
147143 if (K >= 32768)
148
- PPC_ADDIS(r_A, r_A, IMM_HA(K));
144
+ EMIT(PPC_RAW_ADDIS(r_A, r_A, IMM_HA(K)));
149145 break;
150146 case BPF_ALU | BPF_SUB | BPF_X: /* A -= X; */
151147 ctx->seen |= SEEN_XREG;
152
- PPC_SUB(r_A, r_A, r_X);
148
+ EMIT(PPC_RAW_SUB(r_A, r_A, r_X));
153149 break;
154150 case BPF_ALU | BPF_SUB | BPF_K: /* A -= K */
155151 if (!K)
156152 break;
157
- PPC_ADDI(r_A, r_A, IMM_L(-K));
153
+ EMIT(PPC_RAW_ADDI(r_A, r_A, IMM_L(-K)));
158154 if (K >= 32768)
159
- PPC_ADDIS(r_A, r_A, IMM_HA(-K));
155
+ EMIT(PPC_RAW_ADDIS(r_A, r_A, IMM_HA(-K)));
160156 break;
161157 case BPF_ALU | BPF_MUL | BPF_X: /* A *= X; */
162158 ctx->seen |= SEEN_XREG;
163
- PPC_MULW(r_A, r_A, r_X);
159
+ EMIT(PPC_RAW_MULW(r_A, r_A, r_X));
164160 break;
165161 case BPF_ALU | BPF_MUL | BPF_K: /* A *= K */
166162 if (K < 32768)
167
- PPC_MULI(r_A, r_A, K);
163
+ EMIT(PPC_RAW_MULI(r_A, r_A, K));
168164 else {
169165 PPC_LI32(r_scratch1, K);
170
- PPC_MULW(r_A, r_A, r_scratch1);
166
+ EMIT(PPC_RAW_MULW(r_A, r_A, r_scratch1));
171167 }
172168 break;
173169 case BPF_ALU | BPF_MOD | BPF_X: /* A %= X; */
174170 case BPF_ALU | BPF_DIV | BPF_X: /* A /= X; */
175171 ctx->seen |= SEEN_XREG;
176
- PPC_CMPWI(r_X, 0);
172
+ EMIT(PPC_RAW_CMPWI(r_X, 0));
177173 if (ctx->pc_ret0 != -1) {
178174 PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
179175 } else {
180176 PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
181
- PPC_LI(r_ret, 0);
177
+ EMIT(PPC_RAW_LI(r_ret, 0));
182178 PPC_JMP(exit_addr);
183179 }
184180 if (code == (BPF_ALU | BPF_MOD | BPF_X)) {
185
- PPC_DIVWU(r_scratch1, r_A, r_X);
186
- PPC_MULW(r_scratch1, r_X, r_scratch1);
187
- PPC_SUB(r_A, r_A, r_scratch1);
181
+ EMIT(PPC_RAW_DIVWU(r_scratch1, r_A, r_X));
182
+ EMIT(PPC_RAW_MULW(r_scratch1, r_X, r_scratch1));
183
+ EMIT(PPC_RAW_SUB(r_A, r_A, r_scratch1));
188184 } else {
189
- PPC_DIVWU(r_A, r_A, r_X);
185
+ EMIT(PPC_RAW_DIVWU(r_A, r_A, r_X));
190186 }
191187 break;
192188 case BPF_ALU | BPF_MOD | BPF_K: /* A %= K; */
193189 PPC_LI32(r_scratch2, K);
194
- PPC_DIVWU(r_scratch1, r_A, r_scratch2);
195
- PPC_MULW(r_scratch1, r_scratch2, r_scratch1);
196
- PPC_SUB(r_A, r_A, r_scratch1);
190
+ EMIT(PPC_RAW_DIVWU(r_scratch1, r_A, r_scratch2));
191
+ EMIT(PPC_RAW_MULW(r_scratch1, r_scratch2, r_scratch1));
192
+ EMIT(PPC_RAW_SUB(r_A, r_A, r_scratch1));
197193 break;
198194 case BPF_ALU | BPF_DIV | BPF_K: /* A /= K */
199195 if (K == 1)
200196 break;
201197 PPC_LI32(r_scratch1, K);
202
- PPC_DIVWU(r_A, r_A, r_scratch1);
198
+ EMIT(PPC_RAW_DIVWU(r_A, r_A, r_scratch1));
203199 break;
204200 case BPF_ALU | BPF_AND | BPF_X:
205201 ctx->seen |= SEEN_XREG;
206
- PPC_AND(r_A, r_A, r_X);
202
+ EMIT(PPC_RAW_AND(r_A, r_A, r_X));
207203 break;
208204 case BPF_ALU | BPF_AND | BPF_K:
209205 if (!IMM_H(K))
210
- PPC_ANDI(r_A, r_A, K);
206
+ EMIT(PPC_RAW_ANDI(r_A, r_A, K));
211207 else {
212208 PPC_LI32(r_scratch1, K);
213
- PPC_AND(r_A, r_A, r_scratch1);
209
+ EMIT(PPC_RAW_AND(r_A, r_A, r_scratch1));
214210 }
215211 break;
216212 case BPF_ALU | BPF_OR | BPF_X:
217213 ctx->seen |= SEEN_XREG;
218
- PPC_OR(r_A, r_A, r_X);
214
+ EMIT(PPC_RAW_OR(r_A, r_A, r_X));
219215 break;
220216 case BPF_ALU | BPF_OR | BPF_K:
221217 if (IMM_L(K))
222
- PPC_ORI(r_A, r_A, IMM_L(K));
218
+ EMIT(PPC_RAW_ORI(r_A, r_A, IMM_L(K)));
223219 if (K >= 65536)
224
- PPC_ORIS(r_A, r_A, IMM_H(K));
220
+ EMIT(PPC_RAW_ORIS(r_A, r_A, IMM_H(K)));
225221 break;
226222 case BPF_ANC | SKF_AD_ALU_XOR_X:
227223 case BPF_ALU | BPF_XOR | BPF_X: /* A ^= X */
228224 ctx->seen |= SEEN_XREG;
229
- PPC_XOR(r_A, r_A, r_X);
225
+ EMIT(PPC_RAW_XOR(r_A, r_A, r_X));
230226 break;
231227 case BPF_ALU | BPF_XOR | BPF_K: /* A ^= K */
232228 if (IMM_L(K))
233
- PPC_XORI(r_A, r_A, IMM_L(K));
229
+ EMIT(PPC_RAW_XORI(r_A, r_A, IMM_L(K)));
234230 if (K >= 65536)
235
- PPC_XORIS(r_A, r_A, IMM_H(K));
231
+ EMIT(PPC_RAW_XORIS(r_A, r_A, IMM_H(K)));
236232 break;
237233 case BPF_ALU | BPF_LSH | BPF_X: /* A <<= X; */
238234 ctx->seen |= SEEN_XREG;
239
- PPC_SLW(r_A, r_A, r_X);
235
+ EMIT(PPC_RAW_SLW(r_A, r_A, r_X));
240236 break;
241237 case BPF_ALU | BPF_LSH | BPF_K:
242238 if (K == 0)
243239 break;
244240 else
245
- PPC_SLWI(r_A, r_A, K);
241
+ EMIT(PPC_RAW_SLWI(r_A, r_A, K));
246242 break;
247243 case BPF_ALU | BPF_RSH | BPF_X: /* A >>= X; */
248244 ctx->seen |= SEEN_XREG;
249
- PPC_SRW(r_A, r_A, r_X);
245
+ EMIT(PPC_RAW_SRW(r_A, r_A, r_X));
250246 break;
251247 case BPF_ALU | BPF_RSH | BPF_K: /* A >>= K; */
252248 if (K == 0)
253249 break;
254250 else
255
- PPC_SRWI(r_A, r_A, K);
251
+ EMIT(PPC_RAW_SRWI(r_A, r_A, K));
256252 break;
257253 case BPF_ALU | BPF_NEG:
258
- PPC_NEG(r_A, r_A);
254
+ EMIT(PPC_RAW_NEG(r_A, r_A));
259255 break;
260256 case BPF_RET | BPF_K:
261257 PPC_LI32(r_ret, K);
....@@ -281,24 +277,24 @@
281277 if (ctx->seen)
282278 PPC_JMP(exit_addr);
283279 else
284
- PPC_BLR();
280
+ EMIT(PPC_RAW_BLR());
285281 }
286282 break;
287283 case BPF_RET | BPF_A:
288
- PPC_MR(r_ret, r_A);
284
+ EMIT(PPC_RAW_MR(r_ret, r_A));
289285 if (i != flen - 1) {
290286 if (ctx->seen)
291287 PPC_JMP(exit_addr);
292288 else
293
- PPC_BLR();
289
+ EMIT(PPC_RAW_BLR());
294290 }
295291 break;
296292 case BPF_MISC | BPF_TAX: /* X = A */
297
- PPC_MR(r_X, r_A);
293
+ EMIT(PPC_RAW_MR(r_X, r_A));
298294 break;
299295 case BPF_MISC | BPF_TXA: /* A = X */
300296 ctx->seen |= SEEN_XREG;
301
- PPC_MR(r_A, r_X);
297
+ EMIT(PPC_RAW_MR(r_A, r_X));
302298 break;
303299
304300 /*** Constant loads/M[] access ***/
....@@ -309,23 +305,23 @@
309305 PPC_LI32(r_X, K);
310306 break;
311307 case BPF_LD | BPF_MEM: /* A = mem[K] */
312
- PPC_MR(r_A, r_M + (K & 0xf));
308
+ EMIT(PPC_RAW_MR(r_A, r_M + (K & 0xf)));
313309 ctx->seen |= SEEN_MEM | (1<<(K & 0xf));
314310 break;
315311 case BPF_LDX | BPF_MEM: /* X = mem[K] */
316
- PPC_MR(r_X, r_M + (K & 0xf));
312
+ EMIT(PPC_RAW_MR(r_X, r_M + (K & 0xf)));
317313 ctx->seen |= SEEN_MEM | (1<<(K & 0xf));
318314 break;
319315 case BPF_ST: /* mem[K] = A */
320
- PPC_MR(r_M + (K & 0xf), r_A);
316
+ EMIT(PPC_RAW_MR(r_M + (K & 0xf), r_A));
321317 ctx->seen |= SEEN_MEM | (1<<(K & 0xf));
322318 break;
323319 case BPF_STX: /* mem[K] = X */
324
- PPC_MR(r_M + (K & 0xf), r_X);
320
+ EMIT(PPC_RAW_MR(r_M + (K & 0xf), r_X));
325321 ctx->seen |= SEEN_XREG | SEEN_MEM | (1<<(K & 0xf));
326322 break;
327323 case BPF_LD | BPF_W | BPF_LEN: /* A = skb->len; */
328
- BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
324
+ BUILD_BUG_ON(sizeof_field(struct sk_buff, len) != 4);
329325 PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, len));
330326 break;
331327 case BPF_LDX | BPF_W | BPF_ABS: /* A = *((u32 *)(seccomp_data + K)); */
....@@ -337,26 +333,26 @@
337333
338334 /*** Ancillary info loads ***/
339335 case BPF_ANC | SKF_AD_PROTOCOL: /* A = ntohs(skb->protocol); */
340
- BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
336
+ BUILD_BUG_ON(sizeof_field(struct sk_buff,
341337 protocol) != 2);
342338 PPC_NTOHS_OFFS(r_A, r_skb, offsetof(struct sk_buff,
343339 protocol));
344340 break;
345341 case BPF_ANC | SKF_AD_IFINDEX:
346342 case BPF_ANC | SKF_AD_HATYPE:
347
- BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
343
+ BUILD_BUG_ON(sizeof_field(struct net_device,
348344 ifindex) != 4);
349
- BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
345
+ BUILD_BUG_ON(sizeof_field(struct net_device,
350346 type) != 2);
351347 PPC_LL_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
352348 dev));
353
- PPC_CMPDI(r_scratch1, 0);
349
+ EMIT(PPC_RAW_CMPDI(r_scratch1, 0));
354350 if (ctx->pc_ret0 != -1) {
355351 PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
356352 } else {
357353 /* Exit, returning 0; first pass hits here. */
358354 PPC_BCC_SHORT(COND_NE, ctx->idx * 4 + 12);
359
- PPC_LI(r_ret, 0);
355
+ EMIT(PPC_RAW_LI(r_ret, 0));
360356 PPC_JMP(exit_addr);
361357 }
362358 if (code == (BPF_ANC | SKF_AD_IFINDEX)) {
....@@ -369,39 +365,38 @@
369365
370366 break;
371367 case BPF_ANC | SKF_AD_MARK:
372
- BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
368
+ BUILD_BUG_ON(sizeof_field(struct sk_buff, mark) != 4);
373369 PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
374370 mark));
375371 break;
376372 case BPF_ANC | SKF_AD_RXHASH:
377
- BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4);
373
+ BUILD_BUG_ON(sizeof_field(struct sk_buff, hash) != 4);
378374 PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
379375 hash));
380376 break;
381377 case BPF_ANC | SKF_AD_VLAN_TAG:
382
- case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT:
383
- BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2);
384
- BUILD_BUG_ON(VLAN_TAG_PRESENT != 0x1000);
378
+ BUILD_BUG_ON(sizeof_field(struct sk_buff, vlan_tci) != 2);
385379
386380 PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
387381 vlan_tci));
388
- if (code == (BPF_ANC | SKF_AD_VLAN_TAG)) {
389
- PPC_ANDI(r_A, r_A, ~VLAN_TAG_PRESENT);
390
- } else {
391
- PPC_ANDI(r_A, r_A, VLAN_TAG_PRESENT);
392
- PPC_SRWI(r_A, r_A, 12);
393
- }
382
+ break;
383
+ case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT:
384
+ PPC_LBZ_OFFS(r_A, r_skb, PKT_VLAN_PRESENT_OFFSET());
385
+ if (PKT_VLAN_PRESENT_BIT)
386
+ EMIT(PPC_RAW_SRWI(r_A, r_A, PKT_VLAN_PRESENT_BIT));
387
+ if (PKT_VLAN_PRESENT_BIT < 7)
388
+ EMIT(PPC_RAW_ANDI(r_A, r_A, 1));
394389 break;
395390 case BPF_ANC | SKF_AD_QUEUE:
396
- BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
391
+ BUILD_BUG_ON(sizeof_field(struct sk_buff,
397392 queue_mapping) != 2);
398393 PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
399394 queue_mapping));
400395 break;
401396 case BPF_ANC | SKF_AD_PKTTYPE:
402397 PPC_LBZ_OFFS(r_A, r_skb, PKT_TYPE_OFFSET());
403
- PPC_ANDI(r_A, r_A, PKT_TYPE_MAX);
404
- PPC_SRWI(r_A, r_A, 5);
398
+ EMIT(PPC_RAW_ANDI(r_A, r_A, PKT_TYPE_MAX));
399
+ EMIT(PPC_RAW_SRWI(r_A, r_A, 5));
405400 break;
406401 case BPF_ANC | SKF_AD_CPU:
407402 PPC_BPF_LOAD_CPU(r_A);
....@@ -419,9 +414,9 @@
419414 /* Load from [K]. */
420415 ctx->seen |= SEEN_DATAREF;
421416 PPC_FUNC_ADDR(r_scratch1, func);
422
- PPC_MTLR(r_scratch1);
417
+ EMIT(PPC_RAW_MTLR(r_scratch1));
423418 PPC_LI32(r_addr, K);
424
- PPC_BLRL();
419
+ EMIT(PPC_RAW_BLRL());
425420 /*
426421 * Helper returns 'lt' condition on error, and an
427422 * appropriate return value in r3
....@@ -445,11 +440,11 @@
445440 */
446441 ctx->seen |= SEEN_DATAREF | SEEN_XREG;
447442 PPC_FUNC_ADDR(r_scratch1, func);
448
- PPC_MTLR(r_scratch1);
449
- PPC_ADDI(r_addr, r_X, IMM_L(K));
443
+ EMIT(PPC_RAW_MTLR(r_scratch1));
444
+ EMIT(PPC_RAW_ADDI(r_addr, r_X, IMM_L(K)));
450445 if (K >= 32768)
451
- PPC_ADDIS(r_addr, r_addr, IMM_HA(K));
452
- PPC_BLRL();
446
+ EMIT(PPC_RAW_ADDIS(r_addr, r_addr, IMM_HA(K)));
447
+ EMIT(PPC_RAW_BLRL());
453448 /* If error, cr0.LT set */
454449 PPC_BCC(COND_LT, exit_addr);
455450 break;
....@@ -480,7 +475,6 @@
480475 case BPF_JMP | BPF_JSET | BPF_K:
481476 case BPF_JMP | BPF_JSET | BPF_X:
482477 true_cond = COND_NE;
483
- /* Fall through */
484478 cond_branch:
485479 /* same targets, can avoid doing the test :) */
486480 if (filter[i].jt == filter[i].jf) {
....@@ -494,30 +488,30 @@
494488 case BPF_JMP | BPF_JGE | BPF_X:
495489 case BPF_JMP | BPF_JEQ | BPF_X:
496490 ctx->seen |= SEEN_XREG;
497
- PPC_CMPLW(r_A, r_X);
491
+ EMIT(PPC_RAW_CMPLW(r_A, r_X));
498492 break;
499493 case BPF_JMP | BPF_JSET | BPF_X:
500494 ctx->seen |= SEEN_XREG;
501
- PPC_AND_DOT(r_scratch1, r_A, r_X);
495
+ EMIT(PPC_RAW_AND_DOT(r_scratch1, r_A, r_X));
502496 break;
503497 case BPF_JMP | BPF_JEQ | BPF_K:
504498 case BPF_JMP | BPF_JGT | BPF_K:
505499 case BPF_JMP | BPF_JGE | BPF_K:
506500 if (K < 32768)
507
- PPC_CMPLWI(r_A, K);
501
+ EMIT(PPC_RAW_CMPLWI(r_A, K));
508502 else {
509503 PPC_LI32(r_scratch1, K);
510
- PPC_CMPLW(r_A, r_scratch1);
504
+ EMIT(PPC_RAW_CMPLW(r_A, r_scratch1));
511505 }
512506 break;
513507 case BPF_JMP | BPF_JSET | BPF_K:
514508 if (K < 32768)
515509 /* PPC_ANDI is /only/ dot-form */
516
- PPC_ANDI(r_scratch1, r_A, K);
510
+ EMIT(PPC_RAW_ANDI(r_scratch1, r_A, K));
517511 else {
518512 PPC_LI32(r_scratch1, K);
519
- PPC_AND_DOT(r_scratch1, r_A,
520
- r_scratch1);
513
+ EMIT(PPC_RAW_AND_DOT(r_scratch1, r_A,
514
+ r_scratch1));
521515 }
522516 break;
523517 }