},
};
+static const struct ebpf_insn test_call2_prog[] = {
+
+ {
+ .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
+ .dst_reg = EBPF_REG_1,
+ .src_reg = EBPF_REG_10,
+ },
+ {
+ .code = (EBPF_ALU64 | BPF_ADD | BPF_K),
+ .dst_reg = EBPF_REG_1,
+ .imm = -(int32_t)sizeof(struct dummy_offset),
+ },
+ {
+ .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
+ .dst_reg = EBPF_REG_2,
+ .src_reg = EBPF_REG_10,
+ },
+ {
+ .code = (EBPF_ALU64 | BPF_ADD | BPF_K),
+ .dst_reg = EBPF_REG_2,
+ .imm = -2 * (int32_t)sizeof(struct dummy_offset),
+ },
+ {
+ .code = (BPF_JMP | EBPF_CALL),
+ .imm = 0,
+ },
+ {
+ .code = (BPF_LDX | BPF_MEM | EBPF_DW),
+ .dst_reg = EBPF_REG_1,
+ .src_reg = EBPF_REG_10,
+ .off = -(int32_t)(sizeof(struct dummy_offset) -
+ offsetof(struct dummy_offset, u64)),
+ },
+ {
+ .code = (BPF_LDX | BPF_MEM | BPF_W),
+ .dst_reg = EBPF_REG_0,
+ .src_reg = EBPF_REG_10,
+ .off = -(int32_t)(sizeof(struct dummy_offset) -
+ offsetof(struct dummy_offset, u32)),
+ },
+ {
+ .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
+ .dst_reg = EBPF_REG_0,
+ .src_reg = EBPF_REG_1,
+ },
+ {
+ .code = (BPF_LDX | BPF_MEM | BPF_H),
+ .dst_reg = EBPF_REG_1,
+ .src_reg = EBPF_REG_10,
+ .off = -(int32_t)(2 * sizeof(struct dummy_offset) -
+ offsetof(struct dummy_offset, u16)),
+ },
+ {
+ .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
+ .dst_reg = EBPF_REG_0,
+ .src_reg = EBPF_REG_1,
+ },
+ {
+ .code = (BPF_LDX | BPF_MEM | BPF_B),
+ .dst_reg = EBPF_REG_1,
+ .src_reg = EBPF_REG_10,
+ .off = -(int32_t)(2 * sizeof(struct dummy_offset) -
+ offsetof(struct dummy_offset, u8)),
+ },
+ {
+ .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
+ .dst_reg = EBPF_REG_0,
+ .src_reg = EBPF_REG_1,
+ },
+ {
+ .code = (BPF_JMP | EBPF_EXIT),
+ },
+
+};
+
+static void
+dummy_func2(struct dummy_offset *a, struct dummy_offset *b)
+{
+ uint64_t v;
+
+ v = 0;
+ a->u64 = v++;
+ a->u32 = v++;
+ a->u16 = v++;
+ a->u8 = v++;
+ b->u64 = v++;
+ b->u32 = v++;
+ b->u16 = v++;
+ b->u8 = v++;
+}
+
+static int
+test_call2_check(uint64_t rc, const void *arg)
+{
+ uint64_t v;
+ struct dummy_offset a, b;
+
+ RTE_SET_USED(arg);
+
+ dummy_func2(&a, &b);
+ v = a.u64 + a.u32 + b.u16 + b.u8;
+
+ if (v != rc) {
+ printf("%s@%d: invalid return value "
+ "expected=0x%" PRIx64 ", actual=0x%" PRIx64 "\n",
+ __func__, __LINE__, v, rc);
+ return -1;
+ }
+ return 0;
+}
+
+static const struct rte_bpf_xsym test_call2_xsym[] = {
+ {
+ .name = RTE_STR(dummy_func2),
+ .type = RTE_BPF_XTYPE_FUNC,
+ .func = {
+ .val = (void *)dummy_func2,
+ .nb_args = 2,
+ .args = {
+ [0] = {
+ .type = RTE_BPF_ARG_PTR,
+ .size = sizeof(struct dummy_offset),
+ },
+ [1] = {
+ .type = RTE_BPF_ARG_PTR,
+ .size = sizeof(struct dummy_offset),
+ },
+ },
+ },
+ },
+};
+
static const struct bpf_test tests[] = {
{
.name = "test_store1",
/* for now don't support function calls on 32 bit platform */
.allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)),
},
+ {
+ .name = "test_call2",
+ .arg_sz = sizeof(struct dummy_offset),
+ .prm = {
+ .ins = test_call2_prog,
+ .nb_ins = RTE_DIM(test_call2_prog),
+ .prog_arg = {
+ .type = RTE_BPF_ARG_PTR,
+ .size = sizeof(struct dummy_offset),
+ },
+ .xsym = test_call2_xsym,
+ .nb_xsym = RTE_DIM(test_call2_xsym),
+ },
+ .prepare = test_store1_prepare,
+ .check_result = test_call2_check,
+ /* for now don't support function calls on 32 bit platform */
+ .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)),
+ },
};
static int