Hi Jiong, Thank you for the patch! Yet something to improve:
[auto build test ERROR on bpf-next/master] url: https://github.com/0day-ci/linux/commits/Jiong-Wang/bpf-eliminate-zero-extensions-for-sub-register-writes/20190503-104459 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master config: s390-allyesconfig (attached as .config) compiler: s390x-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=7.2.0 make.cross ARCH=s390 If you fix the issue, kindly add following tag Reported-by: kbuild test robot <l...@intel.com> All error/warnings (new ones prefixed by >>): arch/s390/net/bpf_jit_comp.c: In function 'bpf_jit_insn': >> arch/s390/net/bpf_jit_comp.c:524:21: error: 'b1' undeclared (first use in >> this function) EMIT4(0xb9160000, b1, b1); ^ arch/s390/net/bpf_jit_comp.c:148:40: note: in definition of macro '_EMIT4' *(u32 *) (jit->prg_buf + jit->prg) = op; \ ^~ >> arch/s390/net/bpf_jit_comp.c:524:3: note: in expansion of macro 'EMIT4' EMIT4(0xb9160000, b1, b1); ^~~~~ arch/s390/net/bpf_jit_comp.c:524:21: note: each undeclared identifier is reported only once for each function it appears in EMIT4(0xb9160000, b1, b1); ^ arch/s390/net/bpf_jit_comp.c:148:40: note: in definition of macro '_EMIT4' *(u32 *) (jit->prg_buf + jit->prg) = op; \ ^~ >> arch/s390/net/bpf_jit_comp.c:524:3: note: in expansion of macro 'EMIT4' EMIT4(0xb9160000, b1, b1); ^~~~~ vim +/b1 +524 arch/s390/net/bpf_jit_comp.c 498 499 /* 500 * Compile one eBPF instruction into s390x code 501 * 502 * NOTE: Use noinline because for gcov (-fprofile-arcs) gcc allocates a lot of 503 * stack space for the large switch statement. 504 */ 505 static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i) 506 { 507 struct bpf_insn *insn = &fp->insnsi[i]; 508 int jmp_off, last, insn_count = 1; 509 u32 dst_reg = insn->dst_reg; 510 u32 src_reg = insn->src_reg; 511 u32 *addrs = jit->addrs; 512 s32 imm = insn->imm; 513 s16 off = insn->off; 514 unsigned int mask; 515 516 if (dst_reg == BPF_REG_AX || src_reg == BPF_REG_AX) 517 jit->seen |= SEEN_REG_AX; 518 switch (insn->code) { 519 /* 520 * BPF_ZEXT 521 */ 522 case BPF_ALU | BPF_ZEXT: /* dst = (u32) src + always does zext */ 523 /* llgfr %dst,%dst (zero extend to 64 bit) */ > 524 EMIT4(0xb9160000, b1, b1); 525 break; 526 /* 527 * BPF_MOV 528 */ 529 case BPF_ALU | BPF_MOV | BPF_X: /* dst = (u32) src */ 530 /* llgfr %dst,%src */ 531 EMIT4(0xb9160000, dst_reg, src_reg); 532 break; 533 case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */ 534 /* lgr %dst,%src */ 535 EMIT4(0xb9040000, dst_reg, src_reg); 536 break; 537 case BPF_ALU | BPF_MOV | BPF_K: /* dst = (u32) imm */ 538 /* llilf %dst,imm */ 539 EMIT6_IMM(0xc00f0000, dst_reg, imm); 540 break; 541 case BPF_ALU64 | BPF_MOV | BPF_K: /* dst = imm */ 542 /* lgfi %dst,imm */ 543 EMIT6_IMM(0xc0010000, dst_reg, imm); 544 break; 545 /* 546 * BPF_LD 64 547 */ 548 case BPF_LD | BPF_IMM | BPF_DW: /* dst = (u64) imm */ 549 { 550 /* 16 byte instruction that uses two 'struct bpf_insn' */ 551 u64 imm64; 552 553 imm64 = (u64)(u32) insn[0].imm | ((u64)(u32) insn[1].imm) << 32; 554 /* lg %dst,<d(imm)>(%l) */ 555 EMIT6_DISP_LH(0xe3000000, 0x0004, dst_reg, REG_0, REG_L, 556 EMIT_CONST_U64(imm64)); 557 insn_count = 2; 558 break; 559 } 560 /* 561 * BPF_ADD 562 */ 563 case BPF_ALU | BPF_ADD | BPF_X: /* dst = (u32) dst + (u32) src */ 564 /* ar %dst,%src */ 565 EMIT2(0x1a00, dst_reg, src_reg); 566 EMIT_ZERO(dst_reg); 567 break; 568 case BPF_ALU64 | BPF_ADD | BPF_X: /* dst = dst + src */ 569 /* agr %dst,%src */ 570 EMIT4(0xb9080000, dst_reg, src_reg); 571 break; 572 case BPF_ALU | BPF_ADD | BPF_K: /* dst = (u32) dst + (u32) imm */ 573 if (!imm) 574 break; 575 /* alfi %dst,imm */ 576 EMIT6_IMM(0xc20b0000, dst_reg, imm); 577 EMIT_ZERO(dst_reg); 578 break; 579 case BPF_ALU64 | BPF_ADD | BPF_K: /* dst = dst + imm */ 580 if (!imm) 581 break; 582 /* agfi %dst,imm */ 583 EMIT6_IMM(0xc2080000, dst_reg, imm); 584 break; 585 /* 586 * BPF_SUB 587 */ 588 case BPF_ALU | BPF_SUB | BPF_X: /* dst = (u32) dst - (u32) src */ 589 /* sr %dst,%src */ 590 EMIT2(0x1b00, dst_reg, src_reg); 591 EMIT_ZERO(dst_reg); 592 break; 593 case BPF_ALU64 | BPF_SUB | BPF_X: /* dst = dst - src */ 594 /* sgr %dst,%src */ 595 EMIT4(0xb9090000, dst_reg, src_reg); 596 break; 597 case BPF_ALU | BPF_SUB | BPF_K: /* dst = (u32) dst - (u32) imm */ 598 if (!imm) 599 break; 600 /* alfi %dst,-imm */ 601 EMIT6_IMM(0xc20b0000, dst_reg, -imm); 602 EMIT_ZERO(dst_reg); 603 break; 604 case BPF_ALU64 | BPF_SUB | BPF_K: /* dst = dst - imm */ 605 if (!imm) 606 break; 607 /* agfi %dst,-imm */ 608 EMIT6_IMM(0xc2080000, dst_reg, -imm); 609 break; 610 /* 611 * BPF_MUL 612 */ 613 case BPF_ALU | BPF_MUL | BPF_X: /* dst = (u32) dst * (u32) src */ 614 /* msr %dst,%src */ 615 EMIT4(0xb2520000, dst_reg, src_reg); 616 EMIT_ZERO(dst_reg); 617 break; 618 case BPF_ALU64 | BPF_MUL | BPF_X: /* dst = dst * src */ 619 /* msgr %dst,%src */ 620 EMIT4(0xb90c0000, dst_reg, src_reg); 621 break; 622 case BPF_ALU | BPF_MUL | BPF_K: /* dst = (u32) dst * (u32) imm */ 623 if (imm == 1) 624 break; 625 /* msfi %r5,imm */ 626 EMIT6_IMM(0xc2010000, dst_reg, imm); 627 EMIT_ZERO(dst_reg); 628 break; 629 case BPF_ALU64 | BPF_MUL | BPF_K: /* dst = dst * imm */ 630 if (imm == 1) 631 break; 632 /* msgfi %dst,imm */ 633 EMIT6_IMM(0xc2000000, dst_reg, imm); 634 break; 635 /* 636 * BPF_DIV / BPF_MOD 637 */ 638 case BPF_ALU | BPF_DIV | BPF_X: /* dst = (u32) dst / (u32) src */ 639 case BPF_ALU | BPF_MOD | BPF_X: /* dst = (u32) dst % (u32) src */ 640 { 641 int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0; 642 643 /* lhi %w0,0 */ 644 EMIT4_IMM(0xa7080000, REG_W0, 0); 645 /* lr %w1,%dst */ 646 EMIT2(0x1800, REG_W1, dst_reg); 647 /* dlr %w0,%src */ 648 EMIT4(0xb9970000, REG_W0, src_reg); 649 /* llgfr %dst,%rc */ 650 EMIT4(0xb9160000, dst_reg, rc_reg); 651 break; 652 } 653 case BPF_ALU64 | BPF_DIV | BPF_X: /* dst = dst / src */ 654 case BPF_ALU64 | BPF_MOD | BPF_X: /* dst = dst % src */ 655 { 656 int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0; 657 658 /* lghi %w0,0 */ 659 EMIT4_IMM(0xa7090000, REG_W0, 0); 660 /* lgr %w1,%dst */ 661 EMIT4(0xb9040000, REG_W1, dst_reg); 662 /* dlgr %w0,%dst */ 663 EMIT4(0xb9870000, REG_W0, src_reg); 664 /* lgr %dst,%rc */ 665 EMIT4(0xb9040000, dst_reg, rc_reg); 666 break; 667 } 668 case BPF_ALU | BPF_DIV | BPF_K: /* dst = (u32) dst / (u32) imm */ 669 case BPF_ALU | BPF_MOD | BPF_K: /* dst = (u32) dst % (u32) imm */ 670 { 671 int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0; 672 673 if (imm == 1) { 674 if (BPF_OP(insn->code) == BPF_MOD) 675 /* lhgi %dst,0 */ 676 EMIT4_IMM(0xa7090000, dst_reg, 0); 677 break; 678 } 679 /* lhi %w0,0 */ 680 EMIT4_IMM(0xa7080000, REG_W0, 0); 681 /* lr %w1,%dst */ 682 EMIT2(0x1800, REG_W1, dst_reg); 683 /* dl %w0,<d(imm)>(%l) */ 684 EMIT6_DISP_LH(0xe3000000, 0x0097, REG_W0, REG_0, REG_L, 685 EMIT_CONST_U32(imm)); 686 /* llgfr %dst,%rc */ 687 EMIT4(0xb9160000, dst_reg, rc_reg); 688 break; 689 } 690 case BPF_ALU64 | BPF_DIV | BPF_K: /* dst = dst / imm */ 691 case BPF_ALU64 | BPF_MOD | BPF_K: /* dst = dst % imm */ 692 { 693 int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0; 694 695 if (imm == 1) { 696 if (BPF_OP(insn->code) == BPF_MOD) 697 /* lhgi %dst,0 */ 698 EMIT4_IMM(0xa7090000, dst_reg, 0); 699 break; 700 } 701 /* lghi %w0,0 */ 702 EMIT4_IMM(0xa7090000, REG_W0, 0); 703 /* lgr %w1,%dst */ 704 EMIT4(0xb9040000, REG_W1, dst_reg); 705 /* dlg %w0,<d(imm)>(%l) */ 706 EMIT6_DISP_LH(0xe3000000, 0x0087, REG_W0, REG_0, REG_L, 707 EMIT_CONST_U64(imm)); 708 /* lgr %dst,%rc */ 709 EMIT4(0xb9040000, dst_reg, rc_reg); 710 break; 711 } 712 /* 713 * BPF_AND 714 */ 715 case BPF_ALU | BPF_AND | BPF_X: /* dst = (u32) dst & (u32) src */ 716 /* nr %dst,%src */ 717 EMIT2(0x1400, dst_reg, src_reg); 718 EMIT_ZERO(dst_reg); 719 break; 720 case BPF_ALU64 | BPF_AND | BPF_X: /* dst = dst & src */ 721 /* ngr %dst,%src */ 722 EMIT4(0xb9800000, dst_reg, src_reg); 723 break; 724 case BPF_ALU | BPF_AND | BPF_K: /* dst = (u32) dst & (u32) imm */ 725 /* nilf %dst,imm */ 726 EMIT6_IMM(0xc00b0000, dst_reg, imm); 727 EMIT_ZERO(dst_reg); 728 break; 729 case BPF_ALU64 | BPF_AND | BPF_K: /* dst = dst & imm */ 730 /* ng %dst,<d(imm)>(%l) */ 731 EMIT6_DISP_LH(0xe3000000, 0x0080, dst_reg, REG_0, REG_L, 732 EMIT_CONST_U64(imm)); 733 break; 734 /* 735 * BPF_OR 736 */ 737 case BPF_ALU | BPF_OR | BPF_X: /* dst = (u32) dst | (u32) src */ 738 /* or %dst,%src */ 739 EMIT2(0x1600, dst_reg, src_reg); 740 EMIT_ZERO(dst_reg); 741 break; 742 case BPF_ALU64 | BPF_OR | BPF_X: /* dst = dst | src */ 743 /* ogr %dst,%src */ 744 EMIT4(0xb9810000, dst_reg, src_reg); 745 break; 746 case BPF_ALU | BPF_OR | BPF_K: /* dst = (u32) dst | (u32) imm */ 747 /* oilf %dst,imm */ 748 EMIT6_IMM(0xc00d0000, dst_reg, imm); 749 EMIT_ZERO(dst_reg); 750 break; 751 case BPF_ALU64 | BPF_OR | BPF_K: /* dst = dst | imm */ 752 /* og %dst,<d(imm)>(%l) */ 753 EMIT6_DISP_LH(0xe3000000, 0x0081, dst_reg, REG_0, REG_L, 754 EMIT_CONST_U64(imm)); 755 break; 756 /* 757 * BPF_XOR 758 */ 759 case BPF_ALU | BPF_XOR | BPF_X: /* dst = (u32) dst ^ (u32) src */ 760 /* xr %dst,%src */ 761 EMIT2(0x1700, dst_reg, src_reg); 762 EMIT_ZERO(dst_reg); 763 break; 764 case BPF_ALU64 | BPF_XOR | BPF_X: /* dst = dst ^ src */ 765 /* xgr %dst,%src */ 766 EMIT4(0xb9820000, dst_reg, src_reg); 767 break; 768 case BPF_ALU | BPF_XOR | BPF_K: /* dst = (u32) dst ^ (u32) imm */ 769 if (!imm) 770 break; 771 /* xilf %dst,imm */ 772 EMIT6_IMM(0xc0070000, dst_reg, imm); 773 EMIT_ZERO(dst_reg); 774 break; 775 case BPF_ALU64 | BPF_XOR | BPF_K: /* dst = dst ^ imm */ 776 /* xg %dst,<d(imm)>(%l) */ 777 EMIT6_DISP_LH(0xe3000000, 0x0082, dst_reg, REG_0, REG_L, 778 EMIT_CONST_U64(imm)); 779 break; 780 /* 781 * BPF_LSH 782 */ 783 case BPF_ALU | BPF_LSH | BPF_X: /* dst = (u32) dst << (u32) src */ 784 /* sll %dst,0(%src) */ 785 EMIT4_DISP(0x89000000, dst_reg, src_reg, 0); 786 EMIT_ZERO(dst_reg); 787 break; 788 case BPF_ALU64 | BPF_LSH | BPF_X: /* dst = dst << src */ 789 /* sllg %dst,%dst,0(%src) */ 790 EMIT6_DISP_LH(0xeb000000, 0x000d, dst_reg, dst_reg, src_reg, 0); 791 break; 792 case BPF_ALU | BPF_LSH | BPF_K: /* dst = (u32) dst << (u32) imm */ 793 if (imm == 0) 794 break; 795 /* sll %dst,imm(%r0) */ 796 EMIT4_DISP(0x89000000, dst_reg, REG_0, imm); 797 EMIT_ZERO(dst_reg); 798 break; 799 case BPF_ALU64 | BPF_LSH | BPF_K: /* dst = dst << imm */ 800 if (imm == 0) 801 break; 802 /* sllg %dst,%dst,imm(%r0) */ 803 EMIT6_DISP_LH(0xeb000000, 0x000d, dst_reg, dst_reg, REG_0, imm); 804 break; 805 /* 806 * BPF_RSH 807 */ 808 case BPF_ALU | BPF_RSH | BPF_X: /* dst = (u32) dst >> (u32) src */ 809 /* srl %dst,0(%src) */ 810 EMIT4_DISP(0x88000000, dst_reg, src_reg, 0); 811 EMIT_ZERO(dst_reg); 812 break; 813 case BPF_ALU64 | BPF_RSH | BPF_X: /* dst = dst >> src */ 814 /* srlg %dst,%dst,0(%src) */ 815 EMIT6_DISP_LH(0xeb000000, 0x000c, dst_reg, dst_reg, src_reg, 0); 816 break; 817 case BPF_ALU | BPF_RSH | BPF_K: /* dst = (u32) dst >> (u32) imm */ 818 if (imm == 0) 819 break; 820 /* srl %dst,imm(%r0) */ 821 EMIT4_DISP(0x88000000, dst_reg, REG_0, imm); 822 EMIT_ZERO(dst_reg); 823 break; 824 case BPF_ALU64 | BPF_RSH | BPF_K: /* dst = dst >> imm */ 825 if (imm == 0) 826 break; 827 /* srlg %dst,%dst,imm(%r0) */ 828 EMIT6_DISP_LH(0xeb000000, 0x000c, dst_reg, dst_reg, REG_0, imm); 829 break; 830 /* 831 * BPF_ARSH 832 */ 833 case BPF_ALU | BPF_ARSH | BPF_X: /* ((s32) dst) >>= src */ 834 /* sra %dst,%dst,0(%src) */ 835 EMIT4_DISP(0x8a000000, dst_reg, src_reg, 0); 836 EMIT_ZERO(dst_reg); 837 break; 838 case BPF_ALU64 | BPF_ARSH | BPF_X: /* ((s64) dst) >>= src */ 839 /* srag %dst,%dst,0(%src) */ 840 EMIT6_DISP_LH(0xeb000000, 0x000a, dst_reg, dst_reg, src_reg, 0); 841 break; 842 case BPF_ALU | BPF_ARSH | BPF_K: /* ((s32) dst >> imm */ 843 if (imm == 0) 844 break; 845 /* sra %dst,imm(%r0) */ 846 EMIT4_DISP(0x8a000000, dst_reg, REG_0, imm); 847 EMIT_ZERO(dst_reg); 848 break; 849 case BPF_ALU64 | BPF_ARSH | BPF_K: /* ((s64) dst) >>= imm */ 850 if (imm == 0) 851 break; 852 /* srag %dst,%dst,imm(%r0) */ 853 EMIT6_DISP_LH(0xeb000000, 0x000a, dst_reg, dst_reg, REG_0, imm); 854 break; 855 /* 856 * BPF_NEG 857 */ 858 case BPF_ALU | BPF_NEG: /* dst = (u32) -dst */ 859 /* lcr %dst,%dst */ 860 EMIT2(0x1300, dst_reg, dst_reg); 861 EMIT_ZERO(dst_reg); 862 break; 863 case BPF_ALU64 | BPF_NEG: /* dst = -dst */ 864 /* lcgr %dst,%dst */ 865 EMIT4(0xb9130000, dst_reg, dst_reg); 866 break; 867 /* 868 * BPF_FROM_BE/LE 869 */ 870 case BPF_ALU | BPF_END | BPF_FROM_BE: 871 /* s390 is big endian, therefore only clear high order bytes */ 872 switch (imm) { 873 case 16: /* dst = (u16) cpu_to_be16(dst) */ 874 /* llghr %dst,%dst */ 875 EMIT4(0xb9850000, dst_reg, dst_reg); 876 break; 877 case 32: /* dst = (u32) cpu_to_be32(dst) */ 878 /* llgfr %dst,%dst */ 879 EMIT4(0xb9160000, dst_reg, dst_reg); 880 break; 881 case 64: /* dst = (u64) cpu_to_be64(dst) */ 882 break; 883 } 884 break; 885 case BPF_ALU | BPF_END | BPF_FROM_LE: 886 switch (imm) { 887 case 16: /* dst = (u16) cpu_to_le16(dst) */ 888 /* lrvr %dst,%dst */ 889 EMIT4(0xb91f0000, dst_reg, dst_reg); 890 /* srl %dst,16(%r0) */ 891 EMIT4_DISP(0x88000000, dst_reg, REG_0, 16); 892 /* llghr %dst,%dst */ 893 EMIT4(0xb9850000, dst_reg, dst_reg); 894 break; 895 case 32: /* dst = (u32) cpu_to_le32(dst) */ 896 /* lrvr %dst,%dst */ 897 EMIT4(0xb91f0000, dst_reg, dst_reg); 898 /* llgfr %dst,%dst */ 899 EMIT4(0xb9160000, dst_reg, dst_reg); 900 break; 901 case 64: /* dst = (u64) cpu_to_le64(dst) */ 902 /* lrvgr %dst,%dst */ 903 EMIT4(0xb90f0000, dst_reg, dst_reg); 904 break; 905 } 906 break; 907 /* 908 * BPF_ST(X) 909 */ 910 case BPF_STX | BPF_MEM | BPF_B: /* *(u8 *)(dst + off) = src_reg */ 911 /* stcy %src,off(%dst) */ 912 EMIT6_DISP_LH(0xe3000000, 0x0072, src_reg, dst_reg, REG_0, off); 913 jit->seen |= SEEN_MEM; 914 break; 915 case BPF_STX | BPF_MEM | BPF_H: /* (u16 *)(dst + off) = src */ 916 /* sthy %src,off(%dst) */ 917 EMIT6_DISP_LH(0xe3000000, 0x0070, src_reg, dst_reg, REG_0, off); 918 jit->seen |= SEEN_MEM; 919 break; 920 case BPF_STX | BPF_MEM | BPF_W: /* *(u32 *)(dst + off) = src */ 921 /* sty %src,off(%dst) */ 922 EMIT6_DISP_LH(0xe3000000, 0x0050, src_reg, dst_reg, REG_0, off); 923 jit->seen |= SEEN_MEM; 924 break; 925 case BPF_STX | BPF_MEM | BPF_DW: /* (u64 *)(dst + off) = src */ 926 /* stg %src,off(%dst) */ 927 EMIT6_DISP_LH(0xe3000000, 0x0024, src_reg, dst_reg, REG_0, off); 928 jit->seen |= SEEN_MEM; 929 break; 930 case BPF_ST | BPF_MEM | BPF_B: /* *(u8 *)(dst + off) = imm */ 931 /* lhi %w0,imm */ 932 EMIT4_IMM(0xa7080000, REG_W0, (u8) imm); 933 /* stcy %w0,off(dst) */ 934 EMIT6_DISP_LH(0xe3000000, 0x0072, REG_W0, dst_reg, REG_0, off); 935 jit->seen |= SEEN_MEM; 936 break; 937 case BPF_ST | BPF_MEM | BPF_H: /* (u16 *)(dst + off) = imm */ 938 /* lhi %w0,imm */ 939 EMIT4_IMM(0xa7080000, REG_W0, (u16) imm); 940 /* sthy %w0,off(dst) */ 941 EMIT6_DISP_LH(0xe3000000, 0x0070, REG_W0, dst_reg, REG_0, off); 942 jit->seen |= SEEN_MEM; 943 break; 944 case BPF_ST | BPF_MEM | BPF_W: /* *(u32 *)(dst + off) = imm */ 945 /* llilf %w0,imm */ 946 EMIT6_IMM(0xc00f0000, REG_W0, (u32) imm); 947 /* sty %w0,off(%dst) */ 948 EMIT6_DISP_LH(0xe3000000, 0x0050, REG_W0, dst_reg, REG_0, off); 949 jit->seen |= SEEN_MEM; 950 break; 951 case BPF_ST | BPF_MEM | BPF_DW: /* *(u64 *)(dst + off) = imm */ 952 /* lgfi %w0,imm */ 953 EMIT6_IMM(0xc0010000, REG_W0, imm); 954 /* stg %w0,off(%dst) */ 955 EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W0, dst_reg, REG_0, off); 956 jit->seen |= SEEN_MEM; 957 break; 958 /* 959 * BPF_STX XADD (atomic_add) 960 */ 961 case BPF_STX | BPF_XADD | BPF_W: /* *(u32 *)(dst + off) += src */ 962 /* laal %w0,%src,off(%dst) */ 963 EMIT6_DISP_LH(0xeb000000, 0x00fa, REG_W0, src_reg, 964 dst_reg, off); 965 jit->seen |= SEEN_MEM; 966 break; 967 case BPF_STX | BPF_XADD | BPF_DW: /* *(u64 *)(dst + off) += src */ 968 /* laalg %w0,%src,off(%dst) */ 969 EMIT6_DISP_LH(0xeb000000, 0x00ea, REG_W0, src_reg, 970 dst_reg, off); 971 jit->seen |= SEEN_MEM; 972 break; 973 /* 974 * BPF_LDX 975 */ 976 case BPF_LDX | BPF_MEM | BPF_B: /* dst = *(u8 *)(ul) (src + off) */ 977 /* llgc %dst,0(off,%src) */ 978 EMIT6_DISP_LH(0xe3000000, 0x0090, dst_reg, src_reg, REG_0, off); 979 jit->seen |= SEEN_MEM; 980 break; 981 case BPF_LDX | BPF_MEM | BPF_H: /* dst = *(u16 *)(ul) (src + off) */ 982 /* llgh %dst,0(off,%src) */ 983 EMIT6_DISP_LH(0xe3000000, 0x0091, dst_reg, src_reg, REG_0, off); 984 jit->seen |= SEEN_MEM; 985 break; 986 case BPF_LDX | BPF_MEM | BPF_W: /* dst = *(u32 *)(ul) (src + off) */ 987 /* llgf %dst,off(%src) */ 988 jit->seen |= SEEN_MEM; 989 EMIT6_DISP_LH(0xe3000000, 0x0016, dst_reg, src_reg, REG_0, off); 990 break; 991 case BPF_LDX | BPF_MEM | BPF_DW: /* dst = *(u64 *)(ul) (src + off) */ 992 /* lg %dst,0(off,%src) */ 993 jit->seen |= SEEN_MEM; 994 EMIT6_DISP_LH(0xe3000000, 0x0004, dst_reg, src_reg, REG_0, off); 995 break; 996 /* 997 * BPF_JMP / CALL 998 */ 999 case BPF_JMP | BPF_CALL: 1000 { 1001 /* 1002 * b0 = (__bpf_call_base + imm)(b1, b2, b3, b4, b5) 1003 */ 1004 const u64 func = (u64)__bpf_call_base + imm; 1005 1006 REG_SET_SEEN(BPF_REG_5); 1007 jit->seen |= SEEN_FUNC; 1008 /* lg %w1,<d(imm)>(%l) */ 1009 EMIT6_DISP_LH(0xe3000000, 0x0004, REG_W1, REG_0, REG_L, 1010 EMIT_CONST_U64(func)); 1011 if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) { 1012 /* brasl %r14,__s390_indirect_jump_r1 */ 1013 EMIT6_PCREL_RILB(0xc0050000, REG_14, jit->r1_thunk_ip); 1014 } else { 1015 /* basr %r14,%w1 */ 1016 EMIT2(0x0d00, REG_14, REG_W1); 1017 } 1018 /* lgr %b0,%r2: load return value into %b0 */ 1019 EMIT4(0xb9040000, BPF_REG_0, REG_2); 1020 break; 1021 } 1022 case BPF_JMP | BPF_TAIL_CALL: 1023 /* 1024 * Implicit input: 1025 * B1: pointer to ctx 1026 * B2: pointer to bpf_array 1027 * B3: index in bpf_array 1028 */ 1029 jit->seen |= SEEN_TAIL_CALL; 1030 1031 /* 1032 * if (index >= array->map.max_entries) 1033 * goto out; 1034 */ 1035 1036 /* llgf %w1,map.max_entries(%b2) */ 1037 EMIT6_DISP_LH(0xe3000000, 0x0016, REG_W1, REG_0, BPF_REG_2, 1038 offsetof(struct bpf_array, map.max_entries)); 1039 /* clgrj %b3,%w1,0xa,label0: if %b3 >= %w1 goto out */ 1040 EMIT6_PCREL_LABEL(0xec000000, 0x0065, BPF_REG_3, 1041 REG_W1, 0, 0xa); 1042 1043 /* 1044 * if (tail_call_cnt++ > MAX_TAIL_CALL_CNT) 1045 * goto out; 1046 */ 1047 1048 if (jit->seen & SEEN_STACK) 1049 off = STK_OFF_TCCNT + STK_OFF + fp->aux->stack_depth; 1050 else 1051 off = STK_OFF_TCCNT; 1052 /* lhi %w0,1 */ 1053 EMIT4_IMM(0xa7080000, REG_W0, 1); 1054 /* laal %w1,%w0,off(%r15) */ 1055 EMIT6_DISP_LH(0xeb000000, 0x00fa, REG_W1, REG_W0, REG_15, off); 1056 /* clij %w1,MAX_TAIL_CALL_CNT,0x2,label0 */ 1057 EMIT6_PCREL_IMM_LABEL(0xec000000, 0x007f, REG_W1, 1058 MAX_TAIL_CALL_CNT, 0, 0x2); 1059 1060 /* 1061 * prog = array->ptrs[index]; 1062 * if (prog == NULL) 1063 * goto out; 1064 */ 1065 1066 /* sllg %r1,%b3,3: %r1 = index * 8 */ 1067 EMIT6_DISP_LH(0xeb000000, 0x000d, REG_1, BPF_REG_3, REG_0, 3); 1068 /* lg %r1,prog(%b2,%r1) */ 1069 EMIT6_DISP_LH(0xe3000000, 0x0004, REG_1, BPF_REG_2, 1070 REG_1, offsetof(struct bpf_array, ptrs)); 1071 /* clgij %r1,0,0x8,label0 */ 1072 EMIT6_PCREL_IMM_LABEL(0xec000000, 0x007d, REG_1, 0, 0, 0x8); 1073 1074 /* 1075 * Restore registers before calling function 1076 */ 1077 save_restore_regs(jit, REGS_RESTORE, fp->aux->stack_depth); 1078 1079 /* 1080 * goto *(prog->bpf_func + tail_call_start); 1081 */ 1082 1083 /* lg %r1,bpf_func(%r1) */ 1084 EMIT6_DISP_LH(0xe3000000, 0x0004, REG_1, REG_1, REG_0, 1085 offsetof(struct bpf_prog, bpf_func)); 1086 /* bc 0xf,tail_call_start(%r1) */ 1087 _EMIT4(0x47f01000 + jit->tail_call_start); 1088 /* out: */ 1089 jit->labels[0] = jit->prg; 1090 break; 1091 case BPF_JMP | BPF_EXIT: /* return b0 */ 1092 last = (i == fp->len - 1) ? 1 : 0; 1093 if (last && !(jit->seen & SEEN_RET0)) 1094 break; 1095 /* j <exit> */ 1096 EMIT4_PCREL(0xa7f40000, jit->exit_ip - jit->prg); 1097 break; 1098 /* 1099 * Branch relative (number of skipped instructions) to offset on 1100 * condition. 1101 * 1102 * Condition code to mask mapping: 1103 * 1104 * CC | Description | Mask 1105 * ------------------------------ 1106 * 0 | Operands equal | 8 1107 * 1 | First operand low | 4 1108 * 2 | First operand high | 2 1109 * 3 | Unused | 1 1110 * 1111 * For s390x relative branches: ip = ip + off_bytes 1112 * For BPF relative branches: insn = insn + off_insns + 1 1113 * 1114 * For example for s390x with offset 0 we jump to the branch 1115 * instruction itself (loop) and for BPF with offset 0 we 1116 * branch to the instruction behind the branch. 1117 */ 1118 case BPF_JMP | BPF_JA: /* if (true) */ 1119 mask = 0xf000; /* j */ 1120 goto branch_oc; 1121 case BPF_JMP | BPF_JSGT | BPF_K: /* ((s64) dst > (s64) imm) */ 1122 case BPF_JMP32 | BPF_JSGT | BPF_K: /* ((s32) dst > (s32) imm) */ 1123 mask = 0x2000; /* jh */ 1124 goto branch_ks; 1125 case BPF_JMP | BPF_JSLT | BPF_K: /* ((s64) dst < (s64) imm) */ 1126 case BPF_JMP32 | BPF_JSLT | BPF_K: /* ((s32) dst < (s32) imm) */ 1127 mask = 0x4000; /* jl */ 1128 goto branch_ks; 1129 case BPF_JMP | BPF_JSGE | BPF_K: /* ((s64) dst >= (s64) imm) */ 1130 case BPF_JMP32 | BPF_JSGE | BPF_K: /* ((s32) dst >= (s32) imm) */ 1131 mask = 0xa000; /* jhe */ 1132 goto branch_ks; 1133 case BPF_JMP | BPF_JSLE | BPF_K: /* ((s64) dst <= (s64) imm) */ 1134 case BPF_JMP32 | BPF_JSLE | BPF_K: /* ((s32) dst <= (s32) imm) */ 1135 mask = 0xc000; /* jle */ 1136 goto branch_ks; 1137 case BPF_JMP | BPF_JGT | BPF_K: /* (dst_reg > imm) */ 1138 case BPF_JMP32 | BPF_JGT | BPF_K: /* ((u32) dst_reg > (u32) imm) */ 1139 mask = 0x2000; /* jh */ 1140 goto branch_ku; 1141 case BPF_JMP | BPF_JLT | BPF_K: /* (dst_reg < imm) */ 1142 case BPF_JMP32 | BPF_JLT | BPF_K: /* ((u32) dst_reg < (u32) imm) */ 1143 mask = 0x4000; /* jl */ 1144 goto branch_ku; 1145 case BPF_JMP | BPF_JGE | BPF_K: /* (dst_reg >= imm) */ 1146 case BPF_JMP32 | BPF_JGE | BPF_K: /* ((u32) dst_reg >= (u32) imm) */ 1147 mask = 0xa000; /* jhe */ 1148 goto branch_ku; 1149 case BPF_JMP | BPF_JLE | BPF_K: /* (dst_reg <= imm) */ 1150 case BPF_JMP32 | BPF_JLE | BPF_K: /* ((u32) dst_reg <= (u32) imm) */ 1151 mask = 0xc000; /* jle */ 1152 goto branch_ku; 1153 case BPF_JMP | BPF_JNE | BPF_K: /* (dst_reg != imm) */ 1154 case BPF_JMP32 | BPF_JNE | BPF_K: /* ((u32) dst_reg != (u32) imm) */ 1155 mask = 0x7000; /* jne */ 1156 goto branch_ku; 1157 case BPF_JMP | BPF_JEQ | BPF_K: /* (dst_reg == imm) */ 1158 case BPF_JMP32 | BPF_JEQ | BPF_K: /* ((u32) dst_reg == (u32) imm) */ 1159 mask = 0x8000; /* je */ 1160 goto branch_ku; 1161 case BPF_JMP | BPF_JSET | BPF_K: /* (dst_reg & imm) */ 1162 case BPF_JMP32 | BPF_JSET | BPF_K: /* ((u32) dst_reg & (u32) imm) */ 1163 mask = 0x7000; /* jnz */ 1164 if (BPF_CLASS(insn->code) == BPF_JMP32) { 1165 /* llilf %w1,imm (load zero extend imm) */ 1166 EMIT6_IMM(0xc00f0000, REG_W1, imm); 1167 /* nr %w1,%dst */ 1168 EMIT2(0x1400, REG_W1, dst_reg); 1169 } else { 1170 /* lgfi %w1,imm (load sign extend imm) */ 1171 EMIT6_IMM(0xc0010000, REG_W1, imm); 1172 /* ngr %w1,%dst */ 1173 EMIT4(0xb9800000, REG_W1, dst_reg); 1174 } 1175 goto branch_oc; 1176 1177 case BPF_JMP | BPF_JSGT | BPF_X: /* ((s64) dst > (s64) src) */ 1178 case BPF_JMP32 | BPF_JSGT | BPF_X: /* ((s32) dst > (s32) src) */ 1179 mask = 0x2000; /* jh */ 1180 goto branch_xs; 1181 case BPF_JMP | BPF_JSLT | BPF_X: /* ((s64) dst < (s64) src) */ 1182 case BPF_JMP32 | BPF_JSLT | BPF_X: /* ((s32) dst < (s32) src) */ 1183 mask = 0x4000; /* jl */ 1184 goto branch_xs; 1185 case BPF_JMP | BPF_JSGE | BPF_X: /* ((s64) dst >= (s64) src) */ 1186 case BPF_JMP32 | BPF_JSGE | BPF_X: /* ((s32) dst >= (s32) src) */ 1187 mask = 0xa000; /* jhe */ 1188 goto branch_xs; 1189 case BPF_JMP | BPF_JSLE | BPF_X: /* ((s64) dst <= (s64) src) */ 1190 case BPF_JMP32 | BPF_JSLE | BPF_X: /* ((s32) dst <= (s32) src) */ 1191 mask = 0xc000; /* jle */ 1192 goto branch_xs; 1193 case BPF_JMP | BPF_JGT | BPF_X: /* (dst > src) */ 1194 case BPF_JMP32 | BPF_JGT | BPF_X: /* ((u32) dst > (u32) src) */ 1195 mask = 0x2000; /* jh */ 1196 goto branch_xu; 1197 case BPF_JMP | BPF_JLT | BPF_X: /* (dst < src) */ 1198 case BPF_JMP32 | BPF_JLT | BPF_X: /* ((u32) dst < (u32) src) */ 1199 mask = 0x4000; /* jl */ 1200 goto branch_xu; 1201 case BPF_JMP | BPF_JGE | BPF_X: /* (dst >= src) */ 1202 case BPF_JMP32 | BPF_JGE | BPF_X: /* ((u32) dst >= (u32) src) */ 1203 mask = 0xa000; /* jhe */ 1204 goto branch_xu; 1205 case BPF_JMP | BPF_JLE | BPF_X: /* (dst <= src) */ 1206 case BPF_JMP32 | BPF_JLE | BPF_X: /* ((u32) dst <= (u32) src) */ 1207 mask = 0xc000; /* jle */ 1208 goto branch_xu; 1209 case BPF_JMP | BPF_JNE | BPF_X: /* (dst != src) */ 1210 case BPF_JMP32 | BPF_JNE | BPF_X: /* ((u32) dst != (u32) src) */ 1211 mask = 0x7000; /* jne */ 1212 goto branch_xu; 1213 case BPF_JMP | BPF_JEQ | BPF_X: /* (dst == src) */ 1214 case BPF_JMP32 | BPF_JEQ | BPF_X: /* ((u32) dst == (u32) src) */ 1215 mask = 0x8000; /* je */ 1216 goto branch_xu; 1217 case BPF_JMP | BPF_JSET | BPF_X: /* (dst & src) */ 1218 case BPF_JMP32 | BPF_JSET | BPF_X: /* ((u32) dst & (u32) src) */ 1219 { 1220 bool is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32; 1221 1222 mask = 0x7000; /* jnz */ 1223 /* nrk or ngrk %w1,%dst,%src */ 1224 EMIT4_RRF((is_jmp32 ? 0xb9f40000 : 0xb9e40000), 1225 REG_W1, dst_reg, src_reg); 1226 goto branch_oc; 1227 branch_ks: 1228 is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32; 1229 /* lgfi %w1,imm (load sign extend imm) */ 1230 EMIT6_IMM(0xc0010000, REG_W1, imm); 1231 /* crj or cgrj %dst,%w1,mask,off */ 1232 EMIT6_PCREL(0xec000000, (is_jmp32 ? 0x0076 : 0x0064), 1233 dst_reg, REG_W1, i, off, mask); 1234 break; 1235 branch_ku: 1236 is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32; 1237 /* lgfi %w1,imm (load sign extend imm) */ 1238 EMIT6_IMM(0xc0010000, REG_W1, imm); 1239 /* clrj or clgrj %dst,%w1,mask,off */ 1240 EMIT6_PCREL(0xec000000, (is_jmp32 ? 0x0077 : 0x0065), 1241 dst_reg, REG_W1, i, off, mask); 1242 break; 1243 branch_xs: 1244 is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32; 1245 /* crj or cgrj %dst,%src,mask,off */ 1246 EMIT6_PCREL(0xec000000, (is_jmp32 ? 0x0076 : 0x0064), 1247 dst_reg, src_reg, i, off, mask); 1248 break; 1249 branch_xu: 1250 is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32; 1251 /* clrj or clgrj %dst,%src,mask,off */ 1252 EMIT6_PCREL(0xec000000, (is_jmp32 ? 0x0077 : 0x0065), 1253 dst_reg, src_reg, i, off, mask); 1254 break; 1255 branch_oc: 1256 /* brc mask,jmp_off (branch instruction needs 4 bytes) */ 1257 jmp_off = addrs[i + off + 1] - (addrs[i + 1] - 4); 1258 EMIT4_PCREL(0xa7040000 | mask << 8, jmp_off); 1259 break; 1260 } 1261 default: /* too complex, give up */ 1262 pr_err("Unknown opcode %02x\n", insn->code); 1263 return -1; 1264 } 1265 return insn_count; 1266 } 1267 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
.config.gz
Description: application/gzip