lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
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