aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/net
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2014-05-29 04:22:50 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-02 01:16:58 -0400
commit3480593131e0b781287dae0139bf7ccee7cba7ff (patch)
tree6e259a45b3767bd80b789814e4d484ee0ac069bf /arch/s390/net
parentd50bc1575096250aa37f17299c86ea548156efe8 (diff)
net: filter: get rid of BPF_S_* enum
This patch finally allows us to get rid of the BPF_S_* enum. Currently, the code performs unnecessary encode and decode workarounds in seccomp and filter migration itself when a filter is being attached in order to overcome BPF_S_* encoding which is not used anymore by the new interpreter resp. JIT compilers. Keeping it around would mean that also in future we would need to extend and maintain this enum and related encoders/decoders. We can get rid of all that and save us these operations during filter attaching. Naturally, also JIT compilers need to be updated by this. Before JIT conversion is being done, each compiler checks if A is being loaded at startup to obtain information if it needs to emit instructions to clear A first. Since BPF extensions are a subset of BPF_LD | BPF_{W,H,B} | BPF_ABS variants, case statements for extensions can be removed at that point. To ease and minimalize code changes in the classic JITs, we have introduced bpf_anc_helper(). Tested with test_bpf on x86_64 (JIT, int), s390x (JIT, int), arm (JIT, int), i368 (int), ppc64 (JIT, int); for sparc we unfortunately didn't have access, but changes are analogous to the rest. Joint work with Alexei Starovoitov. Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Mircea Gherzan <mgherzan@gmail.com> Cc: Kees Cook <keescook@chromium.org> Acked-by: Chema Gonzalez <chemag@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/s390/net')
-rw-r--r--arch/s390/net/bpf_jit_comp.c163
1 files changed, 78 insertions, 85 deletions
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
index e9f8fa9337fe..a2cbd875543a 100644
--- a/arch/s390/net/bpf_jit_comp.c
+++ b/arch/s390/net/bpf_jit_comp.c
@@ -269,27 +269,17 @@ static void bpf_jit_noleaks(struct bpf_jit *jit, struct sock_filter *filter)
269 EMIT4(0xa7c80000); 269 EMIT4(0xa7c80000);
270 /* Clear A if the first register does not set it. */ 270 /* Clear A if the first register does not set it. */
271 switch (filter[0].code) { 271 switch (filter[0].code) {
272 case BPF_S_LD_W_ABS: 272 case BPF_LD | BPF_W | BPF_ABS:
273 case BPF_S_LD_H_ABS: 273 case BPF_LD | BPF_H | BPF_ABS:
274 case BPF_S_LD_B_ABS: 274 case BPF_LD | BPF_B | BPF_ABS:
275 case BPF_S_LD_W_LEN: 275 case BPF_LD | BPF_W | BPF_LEN:
276 case BPF_S_LD_W_IND: 276 case BPF_LD | BPF_W | BPF_IND:
277 case BPF_S_LD_H_IND: 277 case BPF_LD | BPF_H | BPF_IND:
278 case BPF_S_LD_B_IND: 278 case BPF_LD | BPF_B | BPF_IND:
279 case BPF_S_LD_IMM: 279 case BPF_LD | BPF_IMM:
280 case BPF_S_LD_MEM: 280 case BPF_LD | BPF_MEM:
281 case BPF_S_MISC_TXA: 281 case BPF_MISC | BPF_TXA:
282 case BPF_S_ANC_PROTOCOL: 282 case BPF_RET | BPF_K:
283 case BPF_S_ANC_PKTTYPE:
284 case BPF_S_ANC_IFINDEX:
285 case BPF_S_ANC_MARK:
286 case BPF_S_ANC_QUEUE:
287 case BPF_S_ANC_HATYPE:
288 case BPF_S_ANC_RXHASH:
289 case BPF_S_ANC_CPU:
290 case BPF_S_ANC_VLAN_TAG:
291 case BPF_S_ANC_VLAN_TAG_PRESENT:
292 case BPF_S_RET_K:
293 /* first instruction sets A register */ 283 /* first instruction sets A register */
294 break; 284 break;
295 default: /* A = 0 */ 285 default: /* A = 0 */
@@ -304,15 +294,18 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
304 unsigned int K; 294 unsigned int K;
305 int offset; 295 int offset;
306 unsigned int mask; 296 unsigned int mask;
297 u16 code;
307 298
308 K = filter->k; 299 K = filter->k;
309 switch (filter->code) { 300 code = bpf_anc_helper(filter);
310 case BPF_S_ALU_ADD_X: /* A += X */ 301
302 switch (code) {
303 case BPF_ALU | BPF_ADD | BPF_X: /* A += X */
311 jit->seen |= SEEN_XREG; 304 jit->seen |= SEEN_XREG;
312 /* ar %r5,%r12 */ 305 /* ar %r5,%r12 */
313 EMIT2(0x1a5c); 306 EMIT2(0x1a5c);
314 break; 307 break;
315 case BPF_S_ALU_ADD_K: /* A += K */ 308 case BPF_ALU | BPF_ADD | BPF_K: /* A += K */
316 if (!K) 309 if (!K)
317 break; 310 break;
318 if (K <= 16383) 311 if (K <= 16383)
@@ -325,12 +318,12 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
325 /* a %r5,<d(K)>(%r13) */ 318 /* a %r5,<d(K)>(%r13) */
326 EMIT4_DISP(0x5a50d000, EMIT_CONST(K)); 319 EMIT4_DISP(0x5a50d000, EMIT_CONST(K));
327 break; 320 break;
328 case BPF_S_ALU_SUB_X: /* A -= X */ 321 case BPF_ALU | BPF_SUB | BPF_X: /* A -= X */
329 jit->seen |= SEEN_XREG; 322 jit->seen |= SEEN_XREG;
330 /* sr %r5,%r12 */ 323 /* sr %r5,%r12 */
331 EMIT2(0x1b5c); 324 EMIT2(0x1b5c);
332 break; 325 break;
333 case BPF_S_ALU_SUB_K: /* A -= K */ 326 case BPF_ALU | BPF_SUB | BPF_K: /* A -= K */
334 if (!K) 327 if (!K)
335 break; 328 break;
336 if (K <= 16384) 329 if (K <= 16384)
@@ -343,12 +336,12 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
343 /* s %r5,<d(K)>(%r13) */ 336 /* s %r5,<d(K)>(%r13) */
344 EMIT4_DISP(0x5b50d000, EMIT_CONST(K)); 337 EMIT4_DISP(0x5b50d000, EMIT_CONST(K));
345 break; 338 break;
346 case BPF_S_ALU_MUL_X: /* A *= X */ 339 case BPF_ALU | BPF_MUL | BPF_X: /* A *= X */
347 jit->seen |= SEEN_XREG; 340 jit->seen |= SEEN_XREG;
348 /* msr %r5,%r12 */ 341 /* msr %r5,%r12 */
349 EMIT4(0xb252005c); 342 EMIT4(0xb252005c);
350 break; 343 break;
351 case BPF_S_ALU_MUL_K: /* A *= K */ 344 case BPF_ALU | BPF_MUL | BPF_K: /* A *= K */
352 if (K <= 16383) 345 if (K <= 16383)
353 /* mhi %r5,K */ 346 /* mhi %r5,K */
354 EMIT4_IMM(0xa75c0000, K); 347 EMIT4_IMM(0xa75c0000, K);
@@ -359,7 +352,7 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
359 /* ms %r5,<d(K)>(%r13) */ 352 /* ms %r5,<d(K)>(%r13) */
360 EMIT4_DISP(0x7150d000, EMIT_CONST(K)); 353 EMIT4_DISP(0x7150d000, EMIT_CONST(K));
361 break; 354 break;
362 case BPF_S_ALU_DIV_X: /* A /= X */ 355 case BPF_ALU | BPF_DIV | BPF_X: /* A /= X */
363 jit->seen |= SEEN_XREG | SEEN_RET0; 356 jit->seen |= SEEN_XREG | SEEN_RET0;
364 /* ltr %r12,%r12 */ 357 /* ltr %r12,%r12 */
365 EMIT2(0x12cc); 358 EMIT2(0x12cc);
@@ -370,7 +363,7 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
370 /* dlr %r4,%r12 */ 363 /* dlr %r4,%r12 */
371 EMIT4(0xb997004c); 364 EMIT4(0xb997004c);
372 break; 365 break;
373 case BPF_S_ALU_DIV_K: /* A /= K */ 366 case BPF_ALU | BPF_DIV | BPF_K: /* A /= K */
374 if (K == 1) 367 if (K == 1)
375 break; 368 break;
376 /* lhi %r4,0 */ 369 /* lhi %r4,0 */
@@ -378,7 +371,7 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
378 /* dl %r4,<d(K)>(%r13) */ 371 /* dl %r4,<d(K)>(%r13) */
379 EMIT6_DISP(0xe340d000, 0x0097, EMIT_CONST(K)); 372 EMIT6_DISP(0xe340d000, 0x0097, EMIT_CONST(K));
380 break; 373 break;
381 case BPF_S_ALU_MOD_X: /* A %= X */ 374 case BPF_ALU | BPF_MOD | BPF_X: /* A %= X */
382 jit->seen |= SEEN_XREG | SEEN_RET0; 375 jit->seen |= SEEN_XREG | SEEN_RET0;
383 /* ltr %r12,%r12 */ 376 /* ltr %r12,%r12 */
384 EMIT2(0x12cc); 377 EMIT2(0x12cc);
@@ -391,7 +384,7 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
391 /* lr %r5,%r4 */ 384 /* lr %r5,%r4 */
392 EMIT2(0x1854); 385 EMIT2(0x1854);
393 break; 386 break;
394 case BPF_S_ALU_MOD_K: /* A %= K */ 387 case BPF_ALU | BPF_MOD | BPF_K: /* A %= K */
395 if (K == 1) { 388 if (K == 1) {
396 /* lhi %r5,0 */ 389 /* lhi %r5,0 */
397 EMIT4(0xa7580000); 390 EMIT4(0xa7580000);
@@ -404,12 +397,12 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
404 /* lr %r5,%r4 */ 397 /* lr %r5,%r4 */
405 EMIT2(0x1854); 398 EMIT2(0x1854);
406 break; 399 break;
407 case BPF_S_ALU_AND_X: /* A &= X */ 400 case BPF_ALU | BPF_AND | BPF_X: /* A &= X */
408 jit->seen |= SEEN_XREG; 401 jit->seen |= SEEN_XREG;
409 /* nr %r5,%r12 */ 402 /* nr %r5,%r12 */
410 EMIT2(0x145c); 403 EMIT2(0x145c);
411 break; 404 break;
412 case BPF_S_ALU_AND_K: /* A &= K */ 405 case BPF_ALU | BPF_AND | BPF_K: /* A &= K */
413 if (test_facility(21)) 406 if (test_facility(21))
414 /* nilf %r5,<K> */ 407 /* nilf %r5,<K> */
415 EMIT6_IMM(0xc05b0000, K); 408 EMIT6_IMM(0xc05b0000, K);
@@ -417,12 +410,12 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
417 /* n %r5,<d(K)>(%r13) */ 410 /* n %r5,<d(K)>(%r13) */
418 EMIT4_DISP(0x5450d000, EMIT_CONST(K)); 411 EMIT4_DISP(0x5450d000, EMIT_CONST(K));
419 break; 412 break;
420 case BPF_S_ALU_OR_X: /* A |= X */ 413 case BPF_ALU | BPF_OR | BPF_X: /* A |= X */
421 jit->seen |= SEEN_XREG; 414 jit->seen |= SEEN_XREG;
422 /* or %r5,%r12 */ 415 /* or %r5,%r12 */
423 EMIT2(0x165c); 416 EMIT2(0x165c);
424 break; 417 break;
425 case BPF_S_ALU_OR_K: /* A |= K */ 418 case BPF_ALU | BPF_OR | BPF_K: /* A |= K */
426 if (test_facility(21)) 419 if (test_facility(21))
427 /* oilf %r5,<K> */ 420 /* oilf %r5,<K> */
428 EMIT6_IMM(0xc05d0000, K); 421 EMIT6_IMM(0xc05d0000, K);
@@ -430,55 +423,55 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
430 /* o %r5,<d(K)>(%r13) */ 423 /* o %r5,<d(K)>(%r13) */
431 EMIT4_DISP(0x5650d000, EMIT_CONST(K)); 424 EMIT4_DISP(0x5650d000, EMIT_CONST(K));
432 break; 425 break;
433 case BPF_S_ANC_ALU_XOR_X: /* A ^= X; */ 426 case BPF_ANC | SKF_AD_ALU_XOR_X: /* A ^= X; */
434 case BPF_S_ALU_XOR_X: 427 case BPF_ALU | BPF_XOR | BPF_X:
435 jit->seen |= SEEN_XREG; 428 jit->seen |= SEEN_XREG;
436 /* xr %r5,%r12 */ 429 /* xr %r5,%r12 */
437 EMIT2(0x175c); 430 EMIT2(0x175c);
438 break; 431 break;
439 case BPF_S_ALU_XOR_K: /* A ^= K */ 432 case BPF_ALU | BPF_XOR | BPF_K: /* A ^= K */
440 if (!K) 433 if (!K)
441 break; 434 break;
442 /* x %r5,<d(K)>(%r13) */ 435 /* x %r5,<d(K)>(%r13) */
443 EMIT4_DISP(0x5750d000, EMIT_CONST(K)); 436 EMIT4_DISP(0x5750d000, EMIT_CONST(K));
444 break; 437 break;
445 case BPF_S_ALU_LSH_X: /* A <<= X; */ 438 case BPF_ALU | BPF_LSH | BPF_X: /* A <<= X; */
446 jit->seen |= SEEN_XREG; 439 jit->seen |= SEEN_XREG;
447 /* sll %r5,0(%r12) */ 440 /* sll %r5,0(%r12) */
448 EMIT4(0x8950c000); 441 EMIT4(0x8950c000);
449 break; 442 break;
450 case BPF_S_ALU_LSH_K: /* A <<= K */ 443 case BPF_ALU | BPF_LSH | BPF_K: /* A <<= K */
451 if (K == 0) 444 if (K == 0)
452 break; 445 break;
453 /* sll %r5,K */ 446 /* sll %r5,K */
454 EMIT4_DISP(0x89500000, K); 447 EMIT4_DISP(0x89500000, K);
455 break; 448 break;
456 case BPF_S_ALU_RSH_X: /* A >>= X; */ 449 case BPF_ALU | BPF_RSH | BPF_X: /* A >>= X; */
457 jit->seen |= SEEN_XREG; 450 jit->seen |= SEEN_XREG;
458 /* srl %r5,0(%r12) */ 451 /* srl %r5,0(%r12) */
459 EMIT4(0x8850c000); 452 EMIT4(0x8850c000);
460 break; 453 break;
461 case BPF_S_ALU_RSH_K: /* A >>= K; */ 454 case BPF_ALU | BPF_RSH | BPF_K: /* A >>= K; */
462 if (K == 0) 455 if (K == 0)
463 break; 456 break;
464 /* srl %r5,K */ 457 /* srl %r5,K */
465 EMIT4_DISP(0x88500000, K); 458 EMIT4_DISP(0x88500000, K);
466 break; 459 break;
467 case BPF_S_ALU_NEG: /* A = -A */ 460 case BPF_ALU | BPF_NEG: /* A = -A */
468 /* lnr %r5,%r5 */ 461 /* lnr %r5,%r5 */
469 EMIT2(0x1155); 462 EMIT2(0x1155);
470 break; 463 break;
471 case BPF_S_JMP_JA: /* ip += K */ 464 case BPF_JMP | BPF_JA: /* ip += K */
472 offset = addrs[i + K] + jit->start - jit->prg; 465 offset = addrs[i + K] + jit->start - jit->prg;
473 EMIT4_PCREL(0xa7f40000, offset); 466 EMIT4_PCREL(0xa7f40000, offset);
474 break; 467 break;
475 case BPF_S_JMP_JGT_K: /* ip += (A > K) ? jt : jf */ 468 case BPF_JMP | BPF_JGT | BPF_K: /* ip += (A > K) ? jt : jf */
476 mask = 0x200000; /* jh */ 469 mask = 0x200000; /* jh */
477 goto kbranch; 470 goto kbranch;
478 case BPF_S_JMP_JGE_K: /* ip += (A >= K) ? jt : jf */ 471 case BPF_JMP | BPF_JGE | BPF_K: /* ip += (A >= K) ? jt : jf */
479 mask = 0xa00000; /* jhe */ 472 mask = 0xa00000; /* jhe */
480 goto kbranch; 473 goto kbranch;
481 case BPF_S_JMP_JEQ_K: /* ip += (A == K) ? jt : jf */ 474 case BPF_JMP | BPF_JEQ | BPF_K: /* ip += (A == K) ? jt : jf */
482 mask = 0x800000; /* je */ 475 mask = 0x800000; /* je */
483kbranch: /* Emit compare if the branch targets are different */ 476kbranch: /* Emit compare if the branch targets are different */
484 if (filter->jt != filter->jf) { 477 if (filter->jt != filter->jf) {
@@ -511,7 +504,7 @@ branch: if (filter->jt == filter->jf) {
511 EMIT4_PCREL(0xa7040000 | (mask ^ 0xf00000), offset); 504 EMIT4_PCREL(0xa7040000 | (mask ^ 0xf00000), offset);
512 } 505 }
513 break; 506 break;
514 case BPF_S_JMP_JSET_K: /* ip += (A & K) ? jt : jf */ 507 case BPF_JMP | BPF_JSET | BPF_K: /* ip += (A & K) ? jt : jf */
515 mask = 0x700000; /* jnz */ 508 mask = 0x700000; /* jnz */
516 /* Emit test if the branch targets are different */ 509 /* Emit test if the branch targets are different */
517 if (filter->jt != filter->jf) { 510 if (filter->jt != filter->jf) {
@@ -525,13 +518,13 @@ branch: if (filter->jt == filter->jf) {
525 EMIT4_IMM(0xa7510000, K); 518 EMIT4_IMM(0xa7510000, K);
526 } 519 }
527 goto branch; 520 goto branch;
528 case BPF_S_JMP_JGT_X: /* ip += (A > X) ? jt : jf */ 521 case BPF_JMP | BPF_JGT | BPF_X: /* ip += (A > X) ? jt : jf */
529 mask = 0x200000; /* jh */ 522 mask = 0x200000; /* jh */
530 goto xbranch; 523 goto xbranch;
531 case BPF_S_JMP_JGE_X: /* ip += (A >= X) ? jt : jf */ 524 case BPF_JMP | BPF_JGE | BPF_X: /* ip += (A >= X) ? jt : jf */
532 mask = 0xa00000; /* jhe */ 525 mask = 0xa00000; /* jhe */
533 goto xbranch; 526 goto xbranch;
534 case BPF_S_JMP_JEQ_X: /* ip += (A == X) ? jt : jf */ 527 case BPF_JMP | BPF_JEQ | BPF_X: /* ip += (A == X) ? jt : jf */
535 mask = 0x800000; /* je */ 528 mask = 0x800000; /* je */
536xbranch: /* Emit compare if the branch targets are different */ 529xbranch: /* Emit compare if the branch targets are different */
537 if (filter->jt != filter->jf) { 530 if (filter->jt != filter->jf) {
@@ -540,7 +533,7 @@ xbranch: /* Emit compare if the branch targets are different */
540 EMIT2(0x195c); 533 EMIT2(0x195c);
541 } 534 }
542 goto branch; 535 goto branch;
543 case BPF_S_JMP_JSET_X: /* ip += (A & X) ? jt : jf */ 536 case BPF_JMP | BPF_JSET | BPF_X: /* ip += (A & X) ? jt : jf */
544 mask = 0x700000; /* jnz */ 537 mask = 0x700000; /* jnz */
545 /* Emit test if the branch targets are different */ 538 /* Emit test if the branch targets are different */
546 if (filter->jt != filter->jf) { 539 if (filter->jt != filter->jf) {
@@ -551,15 +544,15 @@ xbranch: /* Emit compare if the branch targets are different */
551 EMIT2(0x144c); 544 EMIT2(0x144c);
552 } 545 }
553 goto branch; 546 goto branch;
554 case BPF_S_LD_W_ABS: /* A = *(u32 *) (skb->data+K) */ 547 case BPF_LD | BPF_W | BPF_ABS: /* A = *(u32 *) (skb->data+K) */
555 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_WORD; 548 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_WORD;
556 offset = jit->off_load_word; 549 offset = jit->off_load_word;
557 goto load_abs; 550 goto load_abs;
558 case BPF_S_LD_H_ABS: /* A = *(u16 *) (skb->data+K) */ 551 case BPF_LD | BPF_H | BPF_ABS: /* A = *(u16 *) (skb->data+K) */
559 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_HALF; 552 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_HALF;
560 offset = jit->off_load_half; 553 offset = jit->off_load_half;
561 goto load_abs; 554 goto load_abs;
562 case BPF_S_LD_B_ABS: /* A = *(u8 *) (skb->data+K) */ 555 case BPF_LD | BPF_B | BPF_ABS: /* A = *(u8 *) (skb->data+K) */
563 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_BYTE; 556 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_BYTE;
564 offset = jit->off_load_byte; 557 offset = jit->off_load_byte;
565load_abs: if ((int) K < 0) 558load_abs: if ((int) K < 0)
@@ -573,19 +566,19 @@ call_fn: /* lg %r1,<d(function)>(%r13) */
573 /* jnz <ret0> */ 566 /* jnz <ret0> */
574 EMIT4_PCREL(0xa7740000, (jit->ret0_ip - jit->prg)); 567 EMIT4_PCREL(0xa7740000, (jit->ret0_ip - jit->prg));
575 break; 568 break;
576 case BPF_S_LD_W_IND: /* A = *(u32 *) (skb->data+K+X) */ 569 case BPF_LD | BPF_W | BPF_IND: /* A = *(u32 *) (skb->data+K+X) */
577 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_IWORD; 570 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_IWORD;
578 offset = jit->off_load_iword; 571 offset = jit->off_load_iword;
579 goto call_fn; 572 goto call_fn;
580 case BPF_S_LD_H_IND: /* A = *(u16 *) (skb->data+K+X) */ 573 case BPF_LD | BPF_H | BPF_IND: /* A = *(u16 *) (skb->data+K+X) */
581 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_IHALF; 574 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_IHALF;
582 offset = jit->off_load_ihalf; 575 offset = jit->off_load_ihalf;
583 goto call_fn; 576 goto call_fn;
584 case BPF_S_LD_B_IND: /* A = *(u8 *) (skb->data+K+X) */ 577 case BPF_LD | BPF_B | BPF_IND: /* A = *(u8 *) (skb->data+K+X) */
585 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_IBYTE; 578 jit->seen |= SEEN_DATAREF | SEEN_RET0 | SEEN_LOAD_IBYTE;
586 offset = jit->off_load_ibyte; 579 offset = jit->off_load_ibyte;
587 goto call_fn; 580 goto call_fn;
588 case BPF_S_LDX_B_MSH: 581 case BPF_LDX | BPF_B | BPF_MSH:
589 /* X = (*(u8 *)(skb->data+K) & 0xf) << 2 */ 582 /* X = (*(u8 *)(skb->data+K) & 0xf) << 2 */
590 jit->seen |= SEEN_RET0; 583 jit->seen |= SEEN_RET0;
591 if ((int) K < 0) { 584 if ((int) K < 0) {
@@ -596,17 +589,17 @@ call_fn: /* lg %r1,<d(function)>(%r13) */
596 jit->seen |= SEEN_DATAREF | SEEN_LOAD_BMSH; 589 jit->seen |= SEEN_DATAREF | SEEN_LOAD_BMSH;
597 offset = jit->off_load_bmsh; 590 offset = jit->off_load_bmsh;
598 goto call_fn; 591 goto call_fn;
599 case BPF_S_LD_W_LEN: /* A = skb->len; */ 592 case BPF_LD | BPF_W | BPF_LEN: /* A = skb->len; */
600 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); 593 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
601 /* l %r5,<d(len)>(%r2) */ 594 /* l %r5,<d(len)>(%r2) */
602 EMIT4_DISP(0x58502000, offsetof(struct sk_buff, len)); 595 EMIT4_DISP(0x58502000, offsetof(struct sk_buff, len));
603 break; 596 break;
604 case BPF_S_LDX_W_LEN: /* X = skb->len; */ 597 case BPF_LDX | BPF_W | BPF_LEN: /* X = skb->len; */
605 jit->seen |= SEEN_XREG; 598 jit->seen |= SEEN_XREG;
606 /* l %r12,<d(len)>(%r2) */ 599 /* l %r12,<d(len)>(%r2) */
607 EMIT4_DISP(0x58c02000, offsetof(struct sk_buff, len)); 600 EMIT4_DISP(0x58c02000, offsetof(struct sk_buff, len));
608 break; 601 break;
609 case BPF_S_LD_IMM: /* A = K */ 602 case BPF_LD | BPF_IMM: /* A = K */
610 if (K <= 16383) 603 if (K <= 16383)
611 /* lhi %r5,K */ 604 /* lhi %r5,K */
612 EMIT4_IMM(0xa7580000, K); 605 EMIT4_IMM(0xa7580000, K);
@@ -617,7 +610,7 @@ call_fn: /* lg %r1,<d(function)>(%r13) */
617 /* l %r5,<d(K)>(%r13) */ 610 /* l %r5,<d(K)>(%r13) */
618 EMIT4_DISP(0x5850d000, EMIT_CONST(K)); 611 EMIT4_DISP(0x5850d000, EMIT_CONST(K));
619 break; 612 break;
620 case BPF_S_LDX_IMM: /* X = K */ 613 case BPF_LDX | BPF_IMM: /* X = K */
621 jit->seen |= SEEN_XREG; 614 jit->seen |= SEEN_XREG;
622 if (K <= 16383) 615 if (K <= 16383)
623 /* lhi %r12,<K> */ 616 /* lhi %r12,<K> */
@@ -629,29 +622,29 @@ call_fn: /* lg %r1,<d(function)>(%r13) */
629 /* l %r12,<d(K)>(%r13) */ 622 /* l %r12,<d(K)>(%r13) */
630 EMIT4_DISP(0x58c0d000, EMIT_CONST(K)); 623 EMIT4_DISP(0x58c0d000, EMIT_CONST(K));
631 break; 624 break;
632 case BPF_S_LD_MEM: /* A = mem[K] */ 625 case BPF_LD | BPF_MEM: /* A = mem[K] */
633 jit->seen |= SEEN_MEM; 626 jit->seen |= SEEN_MEM;
634 /* l %r5,<K>(%r15) */ 627 /* l %r5,<K>(%r15) */
635 EMIT4_DISP(0x5850f000, 628 EMIT4_DISP(0x5850f000,
636 (jit->seen & SEEN_DATAREF) ? 160 + K*4 : K*4); 629 (jit->seen & SEEN_DATAREF) ? 160 + K*4 : K*4);
637 break; 630 break;
638 case BPF_S_LDX_MEM: /* X = mem[K] */ 631 case BPF_LDX | BPF_MEM: /* X = mem[K] */
639 jit->seen |= SEEN_XREG | SEEN_MEM; 632 jit->seen |= SEEN_XREG | SEEN_MEM;
640 /* l %r12,<K>(%r15) */ 633 /* l %r12,<K>(%r15) */
641 EMIT4_DISP(0x58c0f000, 634 EMIT4_DISP(0x58c0f000,
642 (jit->seen & SEEN_DATAREF) ? 160 + K*4 : K*4); 635 (jit->seen & SEEN_DATAREF) ? 160 + K*4 : K*4);
643 break; 636 break;
644 case BPF_S_MISC_TAX: /* X = A */ 637 case BPF_MISC | BPF_TAX: /* X = A */
645 jit->seen |= SEEN_XREG; 638 jit->seen |= SEEN_XREG;
646 /* lr %r12,%r5 */ 639 /* lr %r12,%r5 */
647 EMIT2(0x18c5); 640 EMIT2(0x18c5);
648 break; 641 break;
649 case BPF_S_MISC_TXA: /* A = X */ 642 case BPF_MISC | BPF_TXA: /* A = X */
650 jit->seen |= SEEN_XREG; 643 jit->seen |= SEEN_XREG;
651 /* lr %r5,%r12 */ 644 /* lr %r5,%r12 */
652 EMIT2(0x185c); 645 EMIT2(0x185c);
653 break; 646 break;
654 case BPF_S_RET_K: 647 case BPF_RET | BPF_K:
655 if (K == 0) { 648 if (K == 0) {
656 jit->seen |= SEEN_RET0; 649 jit->seen |= SEEN_RET0;
657 if (last) 650 if (last)
@@ -671,33 +664,33 @@ call_fn: /* lg %r1,<d(function)>(%r13) */
671 EMIT4_PCREL(0xa7f40000, jit->exit_ip - jit->prg); 664 EMIT4_PCREL(0xa7f40000, jit->exit_ip - jit->prg);
672 } 665 }
673 break; 666 break;
674 case BPF_S_RET_A: 667 case BPF_RET | BPF_A:
675 /* llgfr %r2,%r5 */ 668 /* llgfr %r2,%r5 */
676 EMIT4(0xb9160025); 669 EMIT4(0xb9160025);
677 /* j <exit> */ 670 /* j <exit> */
678 EMIT4_PCREL(0xa7f40000, jit->exit_ip - jit->prg); 671 EMIT4_PCREL(0xa7f40000, jit->exit_ip - jit->prg);
679 break; 672 break;
680 case BPF_S_ST: /* mem[K] = A */ 673 case BPF_ST: /* mem[K] = A */
681 jit->seen |= SEEN_MEM; 674 jit->seen |= SEEN_MEM;
682 /* st %r5,<K>(%r15) */ 675 /* st %r5,<K>(%r15) */
683 EMIT4_DISP(0x5050f000, 676 EMIT4_DISP(0x5050f000,
684 (jit->seen & SEEN_DATAREF) ? 160 + K*4 : K*4); 677 (jit->seen & SEEN_DATAREF) ? 160 + K*4 : K*4);
685 break; 678 break;
686 case BPF_S_STX: /* mem[K] = X : mov %ebx,off8(%rbp) */ 679 case BPF_STX: /* mem[K] = X : mov %ebx,off8(%rbp) */
687 jit->seen |= SEEN_XREG | SEEN_MEM; 680 jit->seen |= SEEN_XREG | SEEN_MEM;
688 /* st %r12,<K>(%r15) */ 681 /* st %r12,<K>(%r15) */
689 EMIT4_DISP(0x50c0f000, 682 EMIT4_DISP(0x50c0f000,
690 (jit->seen & SEEN_DATAREF) ? 160 + K*4 : K*4); 683 (jit->seen & SEEN_DATAREF) ? 160 + K*4 : K*4);
691 break; 684 break;
692 case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */ 685 case BPF_ANC | SKF_AD_PROTOCOL: /* A = ntohs(skb->protocol); */
693 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, protocol) != 2); 686 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, protocol) != 2);
694 /* lhi %r5,0 */ 687 /* lhi %r5,0 */
695 EMIT4(0xa7580000); 688 EMIT4(0xa7580000);
696 /* icm %r5,3,<d(protocol)>(%r2) */ 689 /* icm %r5,3,<d(protocol)>(%r2) */
697 EMIT4_DISP(0xbf532000, offsetof(struct sk_buff, protocol)); 690 EMIT4_DISP(0xbf532000, offsetof(struct sk_buff, protocol));
698 break; 691 break;
699 case BPF_S_ANC_IFINDEX: /* if (!skb->dev) return 0; 692 case BPF_ANC | SKF_AD_IFINDEX: /* if (!skb->dev) return 0;
700 * A = skb->dev->ifindex */ 693 * A = skb->dev->ifindex */
701 BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, ifindex) != 4); 694 BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, ifindex) != 4);
702 jit->seen |= SEEN_RET0; 695 jit->seen |= SEEN_RET0;
703 /* lg %r1,<d(dev)>(%r2) */ 696 /* lg %r1,<d(dev)>(%r2) */
@@ -709,20 +702,20 @@ call_fn: /* lg %r1,<d(function)>(%r13) */
709 /* l %r5,<d(ifindex)>(%r1) */ 702 /* l %r5,<d(ifindex)>(%r1) */
710 EMIT4_DISP(0x58501000, offsetof(struct net_device, ifindex)); 703 EMIT4_DISP(0x58501000, offsetof(struct net_device, ifindex));
711 break; 704 break;
712 case BPF_S_ANC_MARK: /* A = skb->mark */ 705 case BPF_ANC | SKF_AD_MARK: /* A = skb->mark */
713 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); 706 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
714 /* l %r5,<d(mark)>(%r2) */ 707 /* l %r5,<d(mark)>(%r2) */
715 EMIT4_DISP(0x58502000, offsetof(struct sk_buff, mark)); 708 EMIT4_DISP(0x58502000, offsetof(struct sk_buff, mark));
716 break; 709 break;
717 case BPF_S_ANC_QUEUE: /* A = skb->queue_mapping */ 710 case BPF_ANC | SKF_AD_QUEUE: /* A = skb->queue_mapping */
718 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, queue_mapping) != 2); 711 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, queue_mapping) != 2);
719 /* lhi %r5,0 */ 712 /* lhi %r5,0 */
720 EMIT4(0xa7580000); 713 EMIT4(0xa7580000);
721 /* icm %r5,3,<d(queue_mapping)>(%r2) */ 714 /* icm %r5,3,<d(queue_mapping)>(%r2) */
722 EMIT4_DISP(0xbf532000, offsetof(struct sk_buff, queue_mapping)); 715 EMIT4_DISP(0xbf532000, offsetof(struct sk_buff, queue_mapping));
723 break; 716 break;
724 case BPF_S_ANC_HATYPE: /* if (!skb->dev) return 0; 717 case BPF_ANC | SKF_AD_HATYPE: /* if (!skb->dev) return 0;
725 * A = skb->dev->type */ 718 * A = skb->dev->type */
726 BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, type) != 2); 719 BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, type) != 2);
727 jit->seen |= SEEN_RET0; 720 jit->seen |= SEEN_RET0;
728 /* lg %r1,<d(dev)>(%r2) */ 721 /* lg %r1,<d(dev)>(%r2) */
@@ -736,20 +729,20 @@ call_fn: /* lg %r1,<d(function)>(%r13) */
736 /* icm %r5,3,<d(type)>(%r1) */ 729 /* icm %r5,3,<d(type)>(%r1) */
737 EMIT4_DISP(0xbf531000, offsetof(struct net_device, type)); 730 EMIT4_DISP(0xbf531000, offsetof(struct net_device, type));
738 break; 731 break;
739 case BPF_S_ANC_RXHASH: /* A = skb->hash */ 732 case BPF_ANC | SKF_AD_RXHASH: /* A = skb->hash */
740 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); 733 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4);
741 /* l %r5,<d(hash)>(%r2) */ 734 /* l %r5,<d(hash)>(%r2) */
742 EMIT4_DISP(0x58502000, offsetof(struct sk_buff, hash)); 735 EMIT4_DISP(0x58502000, offsetof(struct sk_buff, hash));
743 break; 736 break;
744 case BPF_S_ANC_VLAN_TAG: 737 case BPF_ANC | SKF_AD_VLAN_TAG:
745 case BPF_S_ANC_VLAN_TAG_PRESENT: 738 case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT:
746 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2); 739 BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2);
747 BUILD_BUG_ON(VLAN_TAG_PRESENT != 0x1000); 740 BUILD_BUG_ON(VLAN_TAG_PRESENT != 0x1000);
748 /* lhi %r5,0 */ 741 /* lhi %r5,0 */
749 EMIT4(0xa7580000); 742 EMIT4(0xa7580000);
750 /* icm %r5,3,<d(vlan_tci)>(%r2) */ 743 /* icm %r5,3,<d(vlan_tci)>(%r2) */
751 EMIT4_DISP(0xbf532000, offsetof(struct sk_buff, vlan_tci)); 744 EMIT4_DISP(0xbf532000, offsetof(struct sk_buff, vlan_tci));
752 if (filter->code == BPF_S_ANC_VLAN_TAG) { 745 if (code == (BPF_ANC | SKF_AD_VLAN_TAG)) {
753 /* nill %r5,0xefff */ 746 /* nill %r5,0xefff */
754 EMIT4_IMM(0xa5570000, ~VLAN_TAG_PRESENT); 747 EMIT4_IMM(0xa5570000, ~VLAN_TAG_PRESENT);
755 } else { 748 } else {
@@ -759,7 +752,7 @@ call_fn: /* lg %r1,<d(function)>(%r13) */
759 EMIT4_DISP(0x88500000, 12); 752 EMIT4_DISP(0x88500000, 12);
760 } 753 }
761 break; 754 break;
762 case BPF_S_ANC_PKTTYPE: 755 case BPF_ANC | SKF_AD_PKTTYPE:
763 if (pkt_type_offset < 0) 756 if (pkt_type_offset < 0)
764 goto out; 757 goto out;
765 /* lhi %r5,0 */ 758 /* lhi %r5,0 */
@@ -769,7 +762,7 @@ call_fn: /* lg %r1,<d(function)>(%r13) */
769 /* srl %r5,5 */ 762 /* srl %r5,5 */
770 EMIT4_DISP(0x88500000, 5); 763 EMIT4_DISP(0x88500000, 5);
771 break; 764 break;
772 case BPF_S_ANC_CPU: /* A = smp_processor_id() */ 765 case BPF_ANC | SKF_AD_CPU: /* A = smp_processor_id() */
773#ifdef CONFIG_SMP 766#ifdef CONFIG_SMP
774 /* l %r5,<d(cpu_nr)> */ 767 /* l %r5,<d(cpu_nr)> */
775 EMIT4_DISP(0x58500000, offsetof(struct _lowcore, cpu_nr)); 768 EMIT4_DISP(0x58500000, offsetof(struct _lowcore, cpu_nr));