The existing jump test only used a 32-bit JSET mask, so the broken imm8 encoding of TEST in the x86 JIT was never exercised. Add a case with a byte-sized mask; run_test() runs it through the interpreter and the JIT.
Signed-off-by: Stephen Hemminger <[email protected]> --- app/test/test_bpf.c | 82 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/app/test/test_bpf.c b/app/test/test_bpf.c index dd24722450..e70dea736f 100644 --- a/app/test/test_bpf.c +++ b/app/test/test_bpf.c @@ -3158,7 +3158,89 @@ static const struct ebpf_insn test_ld_mbuf3_prog[] = { }; /* all bpf test cases */ +/* + * JSET with a byte-sized mask: exercises the imm8 path of the TEST + * encoding in the x86 JIT (a 32-bit mask takes a different path). + */ +static const struct ebpf_insn test_jset1_prog[] = { + { + .code = (BPF_ALU | EBPF_MOV | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 0, + }, + { + .code = (BPF_LDX | BPF_MEM | BPF_B), + .dst_reg = EBPF_REG_2, + .src_reg = EBPF_REG_1, + .off = offsetof(struct dummy_offset, u8), + }, + /* bit 0 is set in the input: branch is taken */ + { + .code = (BPF_JMP | BPF_JSET | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = 0x1, + .off = 1, + }, + { + .code = (BPF_JMP | BPF_JA), + .off = 1, + }, + { + .code = (EBPF_ALU64 | BPF_OR | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 0x1, + }, + /* bit 1 is clear in the input: branch is not taken */ + { + .code = (BPF_JMP | BPF_JSET | BPF_K), + .dst_reg = EBPF_REG_2, + .imm = 0x2, + .off = 1, + }, + { + .code = (BPF_JMP | BPF_JA), + .off = 1, + }, + { + .code = (EBPF_ALU64 | BPF_OR | BPF_K), + .dst_reg = EBPF_REG_0, + .imm = 0x2, + }, + { + .code = (BPF_JMP | EBPF_EXIT), + }, +}; + +static void +test_jset1_prepare(void *arg) +{ + struct dummy_offset *df = arg; + + memset(df, 0, sizeof(*df)); + df->u8 = 0x1; /* bit 0 set, bit 1 clear */ +} + +static int +test_jset1_check(uint64_t rc, const void *arg) +{ + return cmp_res(__func__, 0x1, rc, arg, arg, 0); +} + static const struct bpf_test tests[] = { + { + .name = "test_jset1", + .arg_sz = sizeof(struct dummy_offset), + .prm = { + .ins = test_jset1_prog, + .nb_ins = RTE_DIM(test_jset1_prog), + .prog_arg = { + .type = RTE_BPF_ARG_PTR, + .size = sizeof(struct dummy_offset), + }, + }, + .prepare = test_jset1_prepare, + .check_result = test_jset1_check, + }, { .name = "test_store1", .arg_sz = sizeof(struct dummy_offset), -- 2.53.0

