diff options
Diffstat (limited to 'arch/powerpc/net/bpf_jit_comp64.c')
-rw-r--r-- | arch/powerpc/net/bpf_jit_comp64.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c index 21a1dcd4b156..0ebd946f178b 100644 --- a/arch/powerpc/net/bpf_jit_comp64.c +++ b/arch/powerpc/net/bpf_jit_comp64.c | |||
@@ -504,6 +504,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
504 | case BPF_ALU | BPF_LSH | BPF_X: /* (u32) dst <<= (u32) src */ | 504 | case BPF_ALU | BPF_LSH | BPF_X: /* (u32) dst <<= (u32) src */ |
505 | /* slw clears top 32 bits */ | 505 | /* slw clears top 32 bits */ |
506 | PPC_SLW(dst_reg, dst_reg, src_reg); | 506 | PPC_SLW(dst_reg, dst_reg, src_reg); |
507 | /* skip zero extension move, but set address map. */ | ||
508 | if (insn_is_zext(&insn[i + 1])) | ||
509 | addrs[++i] = ctx->idx * 4; | ||
507 | break; | 510 | break; |
508 | case BPF_ALU64 | BPF_LSH | BPF_X: /* dst <<= src; */ | 511 | case BPF_ALU64 | BPF_LSH | BPF_X: /* dst <<= src; */ |
509 | PPC_SLD(dst_reg, dst_reg, src_reg); | 512 | PPC_SLD(dst_reg, dst_reg, src_reg); |
@@ -511,6 +514,8 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
511 | case BPF_ALU | BPF_LSH | BPF_K: /* (u32) dst <<== (u32) imm */ | 514 | case BPF_ALU | BPF_LSH | BPF_K: /* (u32) dst <<== (u32) imm */ |
512 | /* with imm 0, we still need to clear top 32 bits */ | 515 | /* with imm 0, we still need to clear top 32 bits */ |
513 | PPC_SLWI(dst_reg, dst_reg, imm); | 516 | PPC_SLWI(dst_reg, dst_reg, imm); |
517 | if (insn_is_zext(&insn[i + 1])) | ||
518 | addrs[++i] = ctx->idx * 4; | ||
514 | break; | 519 | break; |
515 | case BPF_ALU64 | BPF_LSH | BPF_K: /* dst <<== imm */ | 520 | case BPF_ALU64 | BPF_LSH | BPF_K: /* dst <<== imm */ |
516 | if (imm != 0) | 521 | if (imm != 0) |
@@ -518,12 +523,16 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
518 | break; | 523 | break; |
519 | case BPF_ALU | BPF_RSH | BPF_X: /* (u32) dst >>= (u32) src */ | 524 | case BPF_ALU | BPF_RSH | BPF_X: /* (u32) dst >>= (u32) src */ |
520 | PPC_SRW(dst_reg, dst_reg, src_reg); | 525 | PPC_SRW(dst_reg, dst_reg, src_reg); |
526 | if (insn_is_zext(&insn[i + 1])) | ||
527 | addrs[++i] = ctx->idx * 4; | ||
521 | break; | 528 | break; |
522 | case BPF_ALU64 | BPF_RSH | BPF_X: /* dst >>= src */ | 529 | case BPF_ALU64 | BPF_RSH | BPF_X: /* dst >>= src */ |
523 | PPC_SRD(dst_reg, dst_reg, src_reg); | 530 | PPC_SRD(dst_reg, dst_reg, src_reg); |
524 | break; | 531 | break; |
525 | case BPF_ALU | BPF_RSH | BPF_K: /* (u32) dst >>= (u32) imm */ | 532 | case BPF_ALU | BPF_RSH | BPF_K: /* (u32) dst >>= (u32) imm */ |
526 | PPC_SRWI(dst_reg, dst_reg, imm); | 533 | PPC_SRWI(dst_reg, dst_reg, imm); |
534 | if (insn_is_zext(&insn[i + 1])) | ||
535 | addrs[++i] = ctx->idx * 4; | ||
527 | break; | 536 | break; |
528 | case BPF_ALU64 | BPF_RSH | BPF_K: /* dst >>= imm */ | 537 | case BPF_ALU64 | BPF_RSH | BPF_K: /* dst >>= imm */ |
529 | if (imm != 0) | 538 | if (imm != 0) |
@@ -548,6 +557,11 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
548 | */ | 557 | */ |
549 | case BPF_ALU | BPF_MOV | BPF_X: /* (u32) dst = src */ | 558 | case BPF_ALU | BPF_MOV | BPF_X: /* (u32) dst = src */ |
550 | case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */ | 559 | case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */ |
560 | if (imm == 1) { | ||
561 | /* special mov32 for zext */ | ||
562 | PPC_RLWINM(dst_reg, dst_reg, 0, 0, 31); | ||
563 | break; | ||
564 | } | ||
551 | PPC_MR(dst_reg, src_reg); | 565 | PPC_MR(dst_reg, src_reg); |
552 | goto bpf_alu32_trunc; | 566 | goto bpf_alu32_trunc; |
553 | case BPF_ALU | BPF_MOV | BPF_K: /* (u32) dst = imm */ | 567 | case BPF_ALU | BPF_MOV | BPF_K: /* (u32) dst = imm */ |
@@ -555,11 +569,13 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
555 | PPC_LI32(dst_reg, imm); | 569 | PPC_LI32(dst_reg, imm); |
556 | if (imm < 0) | 570 | if (imm < 0) |
557 | goto bpf_alu32_trunc; | 571 | goto bpf_alu32_trunc; |
572 | else if (insn_is_zext(&insn[i + 1])) | ||
573 | addrs[++i] = ctx->idx * 4; | ||
558 | break; | 574 | break; |
559 | 575 | ||
560 | bpf_alu32_trunc: | 576 | bpf_alu32_trunc: |
561 | /* Truncate to 32-bits */ | 577 | /* Truncate to 32-bits */ |
562 | if (BPF_CLASS(code) == BPF_ALU) | 578 | if (BPF_CLASS(code) == BPF_ALU && !fp->aux->verifier_zext) |
563 | PPC_RLWINM(dst_reg, dst_reg, 0, 0, 31); | 579 | PPC_RLWINM(dst_reg, dst_reg, 0, 0, 31); |
564 | break; | 580 | break; |
565 | 581 | ||
@@ -618,10 +634,13 @@ emit_clear: | |||
618 | case 16: | 634 | case 16: |
619 | /* zero-extend 16 bits into 64 bits */ | 635 | /* zero-extend 16 bits into 64 bits */ |
620 | PPC_RLDICL(dst_reg, dst_reg, 0, 48); | 636 | PPC_RLDICL(dst_reg, dst_reg, 0, 48); |
637 | if (insn_is_zext(&insn[i + 1])) | ||
638 | addrs[++i] = ctx->idx * 4; | ||
621 | break; | 639 | break; |
622 | case 32: | 640 | case 32: |
623 | /* zero-extend 32 bits into 64 bits */ | 641 | if (!fp->aux->verifier_zext) |
624 | PPC_RLDICL(dst_reg, dst_reg, 0, 32); | 642 | /* zero-extend 32 bits into 64 bits */ |
643 | PPC_RLDICL(dst_reg, dst_reg, 0, 32); | ||
625 | break; | 644 | break; |
626 | case 64: | 645 | case 64: |
627 | /* nop */ | 646 | /* nop */ |
@@ -698,14 +717,20 @@ emit_clear: | |||
698 | /* dst = *(u8 *)(ul) (src + off) */ | 717 | /* dst = *(u8 *)(ul) (src + off) */ |
699 | case BPF_LDX | BPF_MEM | BPF_B: | 718 | case BPF_LDX | BPF_MEM | BPF_B: |
700 | PPC_LBZ(dst_reg, src_reg, off); | 719 | PPC_LBZ(dst_reg, src_reg, off); |
720 | if (insn_is_zext(&insn[i + 1])) | ||
721 | addrs[++i] = ctx->idx * 4; | ||
701 | break; | 722 | break; |
702 | /* dst = *(u16 *)(ul) (src + off) */ | 723 | /* dst = *(u16 *)(ul) (src + off) */ |
703 | case BPF_LDX | BPF_MEM | BPF_H: | 724 | case BPF_LDX | BPF_MEM | BPF_H: |
704 | PPC_LHZ(dst_reg, src_reg, off); | 725 | PPC_LHZ(dst_reg, src_reg, off); |
726 | if (insn_is_zext(&insn[i + 1])) | ||
727 | addrs[++i] = ctx->idx * 4; | ||
705 | break; | 728 | break; |
706 | /* dst = *(u32 *)(ul) (src + off) */ | 729 | /* dst = *(u32 *)(ul) (src + off) */ |
707 | case BPF_LDX | BPF_MEM | BPF_W: | 730 | case BPF_LDX | BPF_MEM | BPF_W: |
708 | PPC_LWZ(dst_reg, src_reg, off); | 731 | PPC_LWZ(dst_reg, src_reg, off); |
732 | if (insn_is_zext(&insn[i + 1])) | ||
733 | addrs[++i] = ctx->idx * 4; | ||
709 | break; | 734 | break; |
710 | /* dst = *(u64 *)(ul) (src + off) */ | 735 | /* dst = *(u64 *)(ul) (src + off) */ |
711 | case BPF_LDX | BPF_MEM | BPF_DW: | 736 | case BPF_LDX | BPF_MEM | BPF_DW: |
@@ -1046,6 +1071,11 @@ struct powerpc64_jit_data { | |||
1046 | struct codegen_context ctx; | 1071 | struct codegen_context ctx; |
1047 | }; | 1072 | }; |
1048 | 1073 | ||
1074 | bool bpf_jit_needs_zext(void) | ||
1075 | { | ||
1076 | return true; | ||
1077 | } | ||
1078 | |||
1049 | struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) | 1079 | struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) |
1050 | { | 1080 | { |
1051 | u32 proglen; | 1081 | u32 proglen; |