aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/net/bpf_jit_comp64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/net/bpf_jit_comp64.c')
-rw-r--r--arch/powerpc/net/bpf_jit_comp64.c36
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
560bpf_alu32_trunc: 576bpf_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
1074bool bpf_jit_needs_zext(void)
1075{
1076 return true;
1077}
1078
1049struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) 1079struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
1050{ 1080{
1051 u32 proglen; 1081 u32 proglen;