[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <201905031126.GbmiCqy9%lkp@intel.com>
Date: Fri, 3 May 2019 11:42:47 +0800
From: kbuild test robot <lkp@...el.com>
To: Jiong Wang <jiong.wang@...ronome.com>
Cc: kbuild-all@...org, alexei.starovoitov@...il.com,
daniel@...earbox.net, bpf@...r.kernel.org, netdev@...r.kernel.org,
oss-drivers@...ronome.com, Jiong Wang <jiong.wang@...ronome.com>,
Martin Schwidefsky <schwidefsky@...ibm.com>,
Heiko Carstens <heiko.carstens@...ibm.com>
Subject: Re: [PATCH v5 bpf-next 13/17] s390: bpf: eliminate zero extension
code-gen
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 <lkp@...el.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
Download attachment ".config.gz" of type "application/gzip" (53004 bytes)
Powered by blists - more mailing lists