Skip to content

Commit 738476a

Browse files
iii-iAlexei Starovoitov
authored andcommitted
s390/bpf: Implement BPF_MEMSX
Implement the cpuv4 load with sign-extension, which is encoded as BPF_MEMSX (and, for internal uses cases only, BPF_PROBE_MEMSX). This is the same as BPF_MEM and BPF_PROBE_MEM, but with sign extension instead of zero extension, and s390x has the necessary instructions: lgb, lgh and lgf. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Link: https://lore.kernel.org/r/20230919101336.2223655-6-iii@linux.ibm.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 3de5589 commit 738476a

1 file changed

Lines changed: 27 additions & 5 deletions

File tree

arch/s390/net/bpf_jit_comp.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -670,15 +670,18 @@ static void bpf_jit_epilogue(struct bpf_jit *jit, u32 stack_depth)
670670
static int get_probe_mem_regno(const u8 *insn)
671671
{
672672
/*
673-
* insn must point to llgc, llgh, llgf or lg, which have destination
674-
* register at the same position.
673+
* insn must point to llgc, llgh, llgf, lg, lgb, lgh or lgf, which have
674+
* destination register at the same position.
675675
*/
676-
if (insn[0] != 0xe3) /* common llgc, llgh, llgf and lg prefix */
676+
if (insn[0] != 0xe3) /* common prefix */
677677
return -1;
678678
if (insn[5] != 0x90 && /* llgc */
679679
insn[5] != 0x91 && /* llgh */
680680
insn[5] != 0x16 && /* llgf */
681-
insn[5] != 0x04) /* lg */
681+
insn[5] != 0x04 && /* lg */
682+
insn[5] != 0x77 && /* lgb */
683+
insn[5] != 0x15 && /* lgh */
684+
insn[5] != 0x14) /* lgf */
682685
return -1;
683686
return insn[1] >> 4;
684687
}
@@ -788,7 +791,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
788791
int err;
789792

790793
if (BPF_CLASS(insn->code) == BPF_LDX &&
791-
BPF_MODE(insn->code) == BPF_PROBE_MEM)
794+
(BPF_MODE(insn->code) == BPF_PROBE_MEM ||
795+
BPF_MODE(insn->code) == BPF_PROBE_MEMSX))
792796
probe_prg = jit->prg;
793797

794798
switch (insn->code) {
@@ -1406,6 +1410,12 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
14061410
if (insn_is_zext(&insn[1]))
14071411
insn_count = 2;
14081412
break;
1413+
case BPF_LDX | BPF_MEMSX | BPF_B: /* dst = *(s8 *)(ul) (src + off) */
1414+
case BPF_LDX | BPF_PROBE_MEMSX | BPF_B:
1415+
/* lgb %dst,0(off,%src) */
1416+
EMIT6_DISP_LH(0xe3000000, 0x0077, dst_reg, src_reg, REG_0, off);
1417+
jit->seen |= SEEN_MEM;
1418+
break;
14091419
case BPF_LDX | BPF_MEM | BPF_H: /* dst = *(u16 *)(ul) (src + off) */
14101420
case BPF_LDX | BPF_PROBE_MEM | BPF_H:
14111421
/* llgh %dst,0(off,%src) */
@@ -1414,6 +1424,12 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
14141424
if (insn_is_zext(&insn[1]))
14151425
insn_count = 2;
14161426
break;
1427+
case BPF_LDX | BPF_MEMSX | BPF_H: /* dst = *(s16 *)(ul) (src + off) */
1428+
case BPF_LDX | BPF_PROBE_MEMSX | BPF_H:
1429+
/* lgh %dst,0(off,%src) */
1430+
EMIT6_DISP_LH(0xe3000000, 0x0015, dst_reg, src_reg, REG_0, off);
1431+
jit->seen |= SEEN_MEM;
1432+
break;
14171433
case BPF_LDX | BPF_MEM | BPF_W: /* dst = *(u32 *)(ul) (src + off) */
14181434
case BPF_LDX | BPF_PROBE_MEM | BPF_W:
14191435
/* llgf %dst,off(%src) */
@@ -1422,6 +1438,12 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
14221438
if (insn_is_zext(&insn[1]))
14231439
insn_count = 2;
14241440
break;
1441+
case BPF_LDX | BPF_MEMSX | BPF_W: /* dst = *(s32 *)(ul) (src + off) */
1442+
case BPF_LDX | BPF_PROBE_MEMSX | BPF_W:
1443+
/* lgf %dst,off(%src) */
1444+
jit->seen |= SEEN_MEM;
1445+
EMIT6_DISP_LH(0xe3000000, 0x0014, dst_reg, src_reg, REG_0, off);
1446+
break;
14251447
case BPF_LDX | BPF_MEM | BPF_DW: /* dst = *(u64 *)(ul) (src + off) */
14261448
case BPF_LDX | BPF_PROBE_MEM | BPF_DW:
14271449
/* lg %dst,0(off,%src) */

0 commit comments

Comments
 (0)