14418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause
24418919fSjohnjiang * Copyright(c) 2018 Intel Corporation
34418919fSjohnjiang */
44418919fSjohnjiang
54418919fSjohnjiang #include <stdio.h>
64418919fSjohnjiang #include <string.h>
74418919fSjohnjiang #include <stdint.h>
84418919fSjohnjiang #include <inttypes.h>
94418919fSjohnjiang
104418919fSjohnjiang #include <rte_memory.h>
114418919fSjohnjiang #include <rte_debug.h>
124418919fSjohnjiang #include <rte_hexdump.h>
134418919fSjohnjiang #include <rte_random.h>
144418919fSjohnjiang #include <rte_byteorder.h>
154418919fSjohnjiang #include <rte_errno.h>
164418919fSjohnjiang #include <rte_bpf.h>
174418919fSjohnjiang #include <rte_ether.h>
184418919fSjohnjiang #include <rte_ip.h>
194418919fSjohnjiang
204418919fSjohnjiang #include "test.h"
214418919fSjohnjiang
224418919fSjohnjiang /*
234418919fSjohnjiang * Basic functional tests for librte_bpf.
244418919fSjohnjiang * The main procedure - load eBPF program, execute it and
254418919fSjohnjiang * compare restuls with expected values.
264418919fSjohnjiang */
274418919fSjohnjiang
284418919fSjohnjiang struct dummy_offset {
294418919fSjohnjiang uint64_t u64;
304418919fSjohnjiang uint32_t u32;
314418919fSjohnjiang uint16_t u16;
324418919fSjohnjiang uint8_t u8;
334418919fSjohnjiang };
344418919fSjohnjiang
354418919fSjohnjiang struct dummy_vect8 {
364418919fSjohnjiang struct dummy_offset in[8];
374418919fSjohnjiang struct dummy_offset out[8];
384418919fSjohnjiang };
394418919fSjohnjiang
404418919fSjohnjiang struct dummy_net {
414418919fSjohnjiang struct rte_ether_hdr eth_hdr;
424418919fSjohnjiang struct rte_vlan_hdr vlan_hdr;
434418919fSjohnjiang struct rte_ipv4_hdr ip_hdr;
444418919fSjohnjiang };
454418919fSjohnjiang
46*2d9fd380Sjfb8856606 #define DUMMY_MBUF_NUM 2
47*2d9fd380Sjfb8856606
48*2d9fd380Sjfb8856606 /* first mbuf in the packet, should always be at offset 0 */
49*2d9fd380Sjfb8856606 struct dummy_mbuf {
50*2d9fd380Sjfb8856606 struct rte_mbuf mb[DUMMY_MBUF_NUM];
51*2d9fd380Sjfb8856606 uint8_t buf[DUMMY_MBUF_NUM][RTE_MBUF_DEFAULT_BUF_SIZE];
52*2d9fd380Sjfb8856606 };
53*2d9fd380Sjfb8856606
544418919fSjohnjiang #define TEST_FILL_1 0xDEADBEEF
554418919fSjohnjiang
564418919fSjohnjiang #define TEST_MUL_1 21
574418919fSjohnjiang #define TEST_MUL_2 -100
584418919fSjohnjiang
594418919fSjohnjiang #define TEST_SHIFT_1 15
604418919fSjohnjiang #define TEST_SHIFT_2 33
614418919fSjohnjiang
624418919fSjohnjiang #define TEST_JCC_1 0
634418919fSjohnjiang #define TEST_JCC_2 -123
644418919fSjohnjiang #define TEST_JCC_3 5678
654418919fSjohnjiang #define TEST_JCC_4 TEST_FILL_1
664418919fSjohnjiang
674418919fSjohnjiang #define TEST_IMM_1 UINT64_MAX
684418919fSjohnjiang #define TEST_IMM_2 ((uint64_t)INT64_MIN)
694418919fSjohnjiang #define TEST_IMM_3 ((uint64_t)INT64_MAX + INT32_MAX)
704418919fSjohnjiang #define TEST_IMM_4 ((uint64_t)UINT32_MAX)
714418919fSjohnjiang #define TEST_IMM_5 ((uint64_t)UINT32_MAX + 1)
724418919fSjohnjiang
734418919fSjohnjiang #define TEST_MEMFROB 0x2a2a2a2a
744418919fSjohnjiang
754418919fSjohnjiang #define STRING_GEEK 0x6B656567
764418919fSjohnjiang #define STRING_WEEK 0x6B656577
774418919fSjohnjiang
784418919fSjohnjiang #define TEST_NETMASK 0xffffff00
794418919fSjohnjiang #define TEST_SUBNET 0xaca80200
804418919fSjohnjiang
814418919fSjohnjiang uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
824418919fSjohnjiang uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
834418919fSjohnjiang
844418919fSjohnjiang uint32_t ip_src_addr = (172U << 24) | (168U << 16) | (2 << 8) | 1;
854418919fSjohnjiang uint32_t ip_dst_addr = (172U << 24) | (168U << 16) | (2 << 8) | 2;
864418919fSjohnjiang
874418919fSjohnjiang struct bpf_test {
884418919fSjohnjiang const char *name;
894418919fSjohnjiang size_t arg_sz;
904418919fSjohnjiang struct rte_bpf_prm prm;
914418919fSjohnjiang void (*prepare)(void *);
924418919fSjohnjiang int (*check_result)(uint64_t, const void *);
934418919fSjohnjiang uint32_t allow_fail;
944418919fSjohnjiang };
954418919fSjohnjiang
964418919fSjohnjiang /*
974418919fSjohnjiang * Compare return value and result data with expected ones.
984418919fSjohnjiang * Report a failure if they don't match.
994418919fSjohnjiang */
1004418919fSjohnjiang static int
cmp_res(const char * func,uint64_t exp_rc,uint64_t ret_rc,const void * exp_res,const void * ret_res,size_t res_sz)1014418919fSjohnjiang cmp_res(const char *func, uint64_t exp_rc, uint64_t ret_rc,
1024418919fSjohnjiang const void *exp_res, const void *ret_res, size_t res_sz)
1034418919fSjohnjiang {
1044418919fSjohnjiang int32_t ret;
1054418919fSjohnjiang
1064418919fSjohnjiang ret = 0;
1074418919fSjohnjiang if (exp_rc != ret_rc) {
1084418919fSjohnjiang printf("%s@%d: invalid return value, expected: 0x%" PRIx64
1094418919fSjohnjiang ",result: 0x%" PRIx64 "\n",
1104418919fSjohnjiang func, __LINE__, exp_rc, ret_rc);
1114418919fSjohnjiang ret |= -1;
1124418919fSjohnjiang }
1134418919fSjohnjiang
1144418919fSjohnjiang if (memcmp(exp_res, ret_res, res_sz) != 0) {
1154418919fSjohnjiang printf("%s: invalid value\n", func);
1164418919fSjohnjiang rte_memdump(stdout, "expected", exp_res, res_sz);
1174418919fSjohnjiang rte_memdump(stdout, "result", ret_res, res_sz);
1184418919fSjohnjiang ret |= -1;
1194418919fSjohnjiang }
1204418919fSjohnjiang
1214418919fSjohnjiang return ret;
1224418919fSjohnjiang }
1234418919fSjohnjiang
1244418919fSjohnjiang /* store immediate test-cases */
1254418919fSjohnjiang static const struct ebpf_insn test_store1_prog[] = {
1264418919fSjohnjiang {
1274418919fSjohnjiang .code = (BPF_ST | BPF_MEM | BPF_B),
1284418919fSjohnjiang .dst_reg = EBPF_REG_1,
1294418919fSjohnjiang .off = offsetof(struct dummy_offset, u8),
1304418919fSjohnjiang .imm = TEST_FILL_1,
1314418919fSjohnjiang },
1324418919fSjohnjiang {
1334418919fSjohnjiang .code = (BPF_ST | BPF_MEM | BPF_H),
1344418919fSjohnjiang .dst_reg = EBPF_REG_1,
1354418919fSjohnjiang .off = offsetof(struct dummy_offset, u16),
1364418919fSjohnjiang .imm = TEST_FILL_1,
1374418919fSjohnjiang },
1384418919fSjohnjiang {
1394418919fSjohnjiang .code = (BPF_ST | BPF_MEM | BPF_W),
1404418919fSjohnjiang .dst_reg = EBPF_REG_1,
1414418919fSjohnjiang .off = offsetof(struct dummy_offset, u32),
1424418919fSjohnjiang .imm = TEST_FILL_1,
1434418919fSjohnjiang },
1444418919fSjohnjiang {
1454418919fSjohnjiang .code = (BPF_ST | BPF_MEM | EBPF_DW),
1464418919fSjohnjiang .dst_reg = EBPF_REG_1,
1474418919fSjohnjiang .off = offsetof(struct dummy_offset, u64),
1484418919fSjohnjiang .imm = TEST_FILL_1,
1494418919fSjohnjiang },
1504418919fSjohnjiang /* return 1 */
1514418919fSjohnjiang {
1524418919fSjohnjiang .code = (BPF_ALU | EBPF_MOV | BPF_K),
1534418919fSjohnjiang .dst_reg = EBPF_REG_0,
1544418919fSjohnjiang .imm = 1,
1554418919fSjohnjiang },
1564418919fSjohnjiang {
1574418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
1584418919fSjohnjiang },
1594418919fSjohnjiang };
1604418919fSjohnjiang
1614418919fSjohnjiang static void
test_store1_prepare(void * arg)1624418919fSjohnjiang test_store1_prepare(void *arg)
1634418919fSjohnjiang {
1644418919fSjohnjiang struct dummy_offset *df;
1654418919fSjohnjiang
1664418919fSjohnjiang df = arg;
1674418919fSjohnjiang memset(df, 0, sizeof(*df));
1684418919fSjohnjiang }
1694418919fSjohnjiang
1704418919fSjohnjiang static int
test_store1_check(uint64_t rc,const void * arg)1714418919fSjohnjiang test_store1_check(uint64_t rc, const void *arg)
1724418919fSjohnjiang {
1734418919fSjohnjiang const struct dummy_offset *dft;
1744418919fSjohnjiang struct dummy_offset dfe;
1754418919fSjohnjiang
1764418919fSjohnjiang dft = arg;
1774418919fSjohnjiang
1784418919fSjohnjiang memset(&dfe, 0, sizeof(dfe));
1794418919fSjohnjiang dfe.u64 = (int32_t)TEST_FILL_1;
1804418919fSjohnjiang dfe.u32 = dfe.u64;
1814418919fSjohnjiang dfe.u16 = dfe.u64;
1824418919fSjohnjiang dfe.u8 = dfe.u64;
1834418919fSjohnjiang
1844418919fSjohnjiang return cmp_res(__func__, 1, rc, &dfe, dft, sizeof(dfe));
1854418919fSjohnjiang }
1864418919fSjohnjiang
1874418919fSjohnjiang /* store register test-cases */
1884418919fSjohnjiang static const struct ebpf_insn test_store2_prog[] = {
1894418919fSjohnjiang
1904418919fSjohnjiang {
1914418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
1924418919fSjohnjiang .dst_reg = EBPF_REG_2,
1934418919fSjohnjiang .imm = TEST_FILL_1,
1944418919fSjohnjiang },
1954418919fSjohnjiang {
1964418919fSjohnjiang .code = (BPF_STX | BPF_MEM | BPF_B),
1974418919fSjohnjiang .dst_reg = EBPF_REG_1,
1984418919fSjohnjiang .src_reg = EBPF_REG_2,
1994418919fSjohnjiang .off = offsetof(struct dummy_offset, u8),
2004418919fSjohnjiang },
2014418919fSjohnjiang {
2024418919fSjohnjiang .code = (BPF_STX | BPF_MEM | BPF_H),
2034418919fSjohnjiang .dst_reg = EBPF_REG_1,
2044418919fSjohnjiang .src_reg = EBPF_REG_2,
2054418919fSjohnjiang .off = offsetof(struct dummy_offset, u16),
2064418919fSjohnjiang },
2074418919fSjohnjiang {
2084418919fSjohnjiang .code = (BPF_STX | BPF_MEM | BPF_W),
2094418919fSjohnjiang .dst_reg = EBPF_REG_1,
2104418919fSjohnjiang .src_reg = EBPF_REG_2,
2114418919fSjohnjiang .off = offsetof(struct dummy_offset, u32),
2124418919fSjohnjiang },
2134418919fSjohnjiang {
2144418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
2154418919fSjohnjiang .dst_reg = EBPF_REG_1,
2164418919fSjohnjiang .src_reg = EBPF_REG_2,
2174418919fSjohnjiang .off = offsetof(struct dummy_offset, u64),
2184418919fSjohnjiang },
2194418919fSjohnjiang /* return 1 */
2204418919fSjohnjiang {
2214418919fSjohnjiang .code = (BPF_ALU | EBPF_MOV | BPF_K),
2224418919fSjohnjiang .dst_reg = EBPF_REG_0,
2234418919fSjohnjiang .imm = 1,
2244418919fSjohnjiang },
2254418919fSjohnjiang {
2264418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
2274418919fSjohnjiang },
2284418919fSjohnjiang };
2294418919fSjohnjiang
2304418919fSjohnjiang /* load test-cases */
2314418919fSjohnjiang static const struct ebpf_insn test_load1_prog[] = {
2324418919fSjohnjiang
2334418919fSjohnjiang {
2344418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_B),
2354418919fSjohnjiang .dst_reg = EBPF_REG_2,
2364418919fSjohnjiang .src_reg = EBPF_REG_1,
2374418919fSjohnjiang .off = offsetof(struct dummy_offset, u8),
2384418919fSjohnjiang },
2394418919fSjohnjiang {
2404418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_H),
2414418919fSjohnjiang .dst_reg = EBPF_REG_3,
2424418919fSjohnjiang .src_reg = EBPF_REG_1,
2434418919fSjohnjiang .off = offsetof(struct dummy_offset, u16),
2444418919fSjohnjiang },
2454418919fSjohnjiang {
2464418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
2474418919fSjohnjiang .dst_reg = EBPF_REG_4,
2484418919fSjohnjiang .src_reg = EBPF_REG_1,
2494418919fSjohnjiang .off = offsetof(struct dummy_offset, u32),
2504418919fSjohnjiang },
2514418919fSjohnjiang {
2524418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
2534418919fSjohnjiang .dst_reg = EBPF_REG_0,
2544418919fSjohnjiang .src_reg = EBPF_REG_1,
2554418919fSjohnjiang .off = offsetof(struct dummy_offset, u64),
2564418919fSjohnjiang },
2574418919fSjohnjiang /* return sum */
2584418919fSjohnjiang {
2594418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
2604418919fSjohnjiang .dst_reg = EBPF_REG_0,
2614418919fSjohnjiang .src_reg = EBPF_REG_4,
2624418919fSjohnjiang },
2634418919fSjohnjiang {
2644418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
2654418919fSjohnjiang .dst_reg = EBPF_REG_0,
2664418919fSjohnjiang .src_reg = EBPF_REG_3,
2674418919fSjohnjiang },
2684418919fSjohnjiang {
2694418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
2704418919fSjohnjiang .dst_reg = EBPF_REG_0,
2714418919fSjohnjiang .src_reg = EBPF_REG_2,
2724418919fSjohnjiang },
2734418919fSjohnjiang {
2744418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
2754418919fSjohnjiang },
2764418919fSjohnjiang };
2774418919fSjohnjiang
2784418919fSjohnjiang static void
test_load1_prepare(void * arg)2794418919fSjohnjiang test_load1_prepare(void *arg)
2804418919fSjohnjiang {
2814418919fSjohnjiang struct dummy_offset *df;
2824418919fSjohnjiang
2834418919fSjohnjiang df = arg;
2844418919fSjohnjiang
2854418919fSjohnjiang memset(df, 0, sizeof(*df));
2864418919fSjohnjiang df->u64 = (int32_t)TEST_FILL_1;
2874418919fSjohnjiang df->u32 = df->u64;
2884418919fSjohnjiang df->u16 = df->u64;
2894418919fSjohnjiang df->u8 = df->u64;
2904418919fSjohnjiang }
2914418919fSjohnjiang
2924418919fSjohnjiang static int
test_load1_check(uint64_t rc,const void * arg)2934418919fSjohnjiang test_load1_check(uint64_t rc, const void *arg)
2944418919fSjohnjiang {
2954418919fSjohnjiang uint64_t v;
2964418919fSjohnjiang const struct dummy_offset *dft;
2974418919fSjohnjiang
2984418919fSjohnjiang dft = arg;
2994418919fSjohnjiang v = dft->u64;
3004418919fSjohnjiang v += dft->u32;
3014418919fSjohnjiang v += dft->u16;
3024418919fSjohnjiang v += dft->u8;
3034418919fSjohnjiang
3044418919fSjohnjiang return cmp_res(__func__, v, rc, dft, dft, sizeof(*dft));
3054418919fSjohnjiang }
3064418919fSjohnjiang
3074418919fSjohnjiang /* load immediate test-cases */
3084418919fSjohnjiang static const struct ebpf_insn test_ldimm1_prog[] = {
3094418919fSjohnjiang
3104418919fSjohnjiang {
3114418919fSjohnjiang .code = (BPF_LD | BPF_IMM | EBPF_DW),
3124418919fSjohnjiang .dst_reg = EBPF_REG_0,
3134418919fSjohnjiang .imm = (uint32_t)TEST_IMM_1,
3144418919fSjohnjiang },
3154418919fSjohnjiang {
3164418919fSjohnjiang .imm = TEST_IMM_1 >> 32,
3174418919fSjohnjiang },
3184418919fSjohnjiang {
3194418919fSjohnjiang .code = (BPF_LD | BPF_IMM | EBPF_DW),
3204418919fSjohnjiang .dst_reg = EBPF_REG_3,
3214418919fSjohnjiang .imm = (uint32_t)TEST_IMM_2,
3224418919fSjohnjiang },
3234418919fSjohnjiang {
3244418919fSjohnjiang .imm = TEST_IMM_2 >> 32,
3254418919fSjohnjiang },
3264418919fSjohnjiang {
3274418919fSjohnjiang .code = (BPF_LD | BPF_IMM | EBPF_DW),
3284418919fSjohnjiang .dst_reg = EBPF_REG_5,
3294418919fSjohnjiang .imm = (uint32_t)TEST_IMM_3,
3304418919fSjohnjiang },
3314418919fSjohnjiang {
3324418919fSjohnjiang .imm = TEST_IMM_3 >> 32,
3334418919fSjohnjiang },
3344418919fSjohnjiang {
3354418919fSjohnjiang .code = (BPF_LD | BPF_IMM | EBPF_DW),
3364418919fSjohnjiang .dst_reg = EBPF_REG_7,
3374418919fSjohnjiang .imm = (uint32_t)TEST_IMM_4,
3384418919fSjohnjiang },
3394418919fSjohnjiang {
3404418919fSjohnjiang .imm = TEST_IMM_4 >> 32,
3414418919fSjohnjiang },
3424418919fSjohnjiang {
3434418919fSjohnjiang .code = (BPF_LD | BPF_IMM | EBPF_DW),
3444418919fSjohnjiang .dst_reg = EBPF_REG_9,
3454418919fSjohnjiang .imm = (uint32_t)TEST_IMM_5,
3464418919fSjohnjiang },
3474418919fSjohnjiang {
3484418919fSjohnjiang .imm = TEST_IMM_5 >> 32,
3494418919fSjohnjiang },
3504418919fSjohnjiang /* return sum */
3514418919fSjohnjiang {
3524418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
3534418919fSjohnjiang .dst_reg = EBPF_REG_0,
3544418919fSjohnjiang .src_reg = EBPF_REG_3,
3554418919fSjohnjiang },
3564418919fSjohnjiang {
3574418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
3584418919fSjohnjiang .dst_reg = EBPF_REG_0,
3594418919fSjohnjiang .src_reg = EBPF_REG_5,
3604418919fSjohnjiang },
3614418919fSjohnjiang {
3624418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
3634418919fSjohnjiang .dst_reg = EBPF_REG_0,
3644418919fSjohnjiang .src_reg = EBPF_REG_7,
3654418919fSjohnjiang },
3664418919fSjohnjiang {
3674418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
3684418919fSjohnjiang .dst_reg = EBPF_REG_0,
3694418919fSjohnjiang .src_reg = EBPF_REG_9,
3704418919fSjohnjiang },
3714418919fSjohnjiang {
3724418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
3734418919fSjohnjiang },
3744418919fSjohnjiang };
3754418919fSjohnjiang
3764418919fSjohnjiang static int
test_ldimm1_check(uint64_t rc,const void * arg)3774418919fSjohnjiang test_ldimm1_check(uint64_t rc, const void *arg)
3784418919fSjohnjiang {
3794418919fSjohnjiang uint64_t v1, v2;
3804418919fSjohnjiang
3814418919fSjohnjiang v1 = TEST_IMM_1;
3824418919fSjohnjiang v2 = TEST_IMM_2;
3834418919fSjohnjiang v1 += v2;
3844418919fSjohnjiang v2 = TEST_IMM_3;
3854418919fSjohnjiang v1 += v2;
3864418919fSjohnjiang v2 = TEST_IMM_4;
3874418919fSjohnjiang v1 += v2;
3884418919fSjohnjiang v2 = TEST_IMM_5;
3894418919fSjohnjiang v1 += v2;
3904418919fSjohnjiang
3914418919fSjohnjiang return cmp_res(__func__, v1, rc, arg, arg, 0);
3924418919fSjohnjiang }
3934418919fSjohnjiang
3944418919fSjohnjiang
3954418919fSjohnjiang /* alu mul test-cases */
3964418919fSjohnjiang static const struct ebpf_insn test_mul1_prog[] = {
3974418919fSjohnjiang
3984418919fSjohnjiang {
3994418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
4004418919fSjohnjiang .dst_reg = EBPF_REG_2,
4014418919fSjohnjiang .src_reg = EBPF_REG_1,
4024418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u32),
4034418919fSjohnjiang },
4044418919fSjohnjiang {
4054418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
4064418919fSjohnjiang .dst_reg = EBPF_REG_3,
4074418919fSjohnjiang .src_reg = EBPF_REG_1,
4084418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[1].u64),
4094418919fSjohnjiang },
4104418919fSjohnjiang {
4114418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
4124418919fSjohnjiang .dst_reg = EBPF_REG_4,
4134418919fSjohnjiang .src_reg = EBPF_REG_1,
4144418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[2].u32),
4154418919fSjohnjiang },
4164418919fSjohnjiang {
4174418919fSjohnjiang .code = (BPF_ALU | BPF_MUL | BPF_K),
4184418919fSjohnjiang .dst_reg = EBPF_REG_2,
4194418919fSjohnjiang .imm = TEST_MUL_1,
4204418919fSjohnjiang },
4214418919fSjohnjiang {
4224418919fSjohnjiang .code = (EBPF_ALU64 | BPF_MUL | BPF_K),
4234418919fSjohnjiang .dst_reg = EBPF_REG_3,
4244418919fSjohnjiang .imm = TEST_MUL_2,
4254418919fSjohnjiang },
4264418919fSjohnjiang {
4274418919fSjohnjiang .code = (BPF_ALU | BPF_MUL | BPF_X),
4284418919fSjohnjiang .dst_reg = EBPF_REG_4,
4294418919fSjohnjiang .src_reg = EBPF_REG_2,
4304418919fSjohnjiang },
4314418919fSjohnjiang {
4324418919fSjohnjiang .code = (EBPF_ALU64 | BPF_MUL | BPF_X),
4334418919fSjohnjiang .dst_reg = EBPF_REG_4,
4344418919fSjohnjiang .src_reg = EBPF_REG_3,
4354418919fSjohnjiang },
4364418919fSjohnjiang {
4374418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
4384418919fSjohnjiang .dst_reg = EBPF_REG_1,
4394418919fSjohnjiang .src_reg = EBPF_REG_2,
4404418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[0].u64),
4414418919fSjohnjiang },
4424418919fSjohnjiang {
4434418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
4444418919fSjohnjiang .dst_reg = EBPF_REG_1,
4454418919fSjohnjiang .src_reg = EBPF_REG_3,
4464418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[1].u64),
4474418919fSjohnjiang },
4484418919fSjohnjiang {
4494418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
4504418919fSjohnjiang .dst_reg = EBPF_REG_1,
4514418919fSjohnjiang .src_reg = EBPF_REG_4,
4524418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[2].u64),
4534418919fSjohnjiang },
4544418919fSjohnjiang /* return 1 */
4554418919fSjohnjiang {
4564418919fSjohnjiang .code = (BPF_ALU | EBPF_MOV | BPF_K),
4574418919fSjohnjiang .dst_reg = EBPF_REG_0,
4584418919fSjohnjiang .imm = 1,
4594418919fSjohnjiang },
4604418919fSjohnjiang {
4614418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
4624418919fSjohnjiang },
4634418919fSjohnjiang };
4644418919fSjohnjiang
4654418919fSjohnjiang static void
test_mul1_prepare(void * arg)4664418919fSjohnjiang test_mul1_prepare(void *arg)
4674418919fSjohnjiang {
4684418919fSjohnjiang struct dummy_vect8 *dv;
4694418919fSjohnjiang uint64_t v;
4704418919fSjohnjiang
4714418919fSjohnjiang dv = arg;
4724418919fSjohnjiang
4734418919fSjohnjiang v = rte_rand();
4744418919fSjohnjiang
4754418919fSjohnjiang memset(dv, 0, sizeof(*dv));
4764418919fSjohnjiang dv->in[0].u32 = v;
4774418919fSjohnjiang dv->in[1].u64 = v << 12 | v >> 6;
4784418919fSjohnjiang dv->in[2].u32 = -v;
4794418919fSjohnjiang }
4804418919fSjohnjiang
4814418919fSjohnjiang static int
test_mul1_check(uint64_t rc,const void * arg)4824418919fSjohnjiang test_mul1_check(uint64_t rc, const void *arg)
4834418919fSjohnjiang {
4844418919fSjohnjiang uint64_t r2, r3, r4;
4854418919fSjohnjiang const struct dummy_vect8 *dvt;
4864418919fSjohnjiang struct dummy_vect8 dve;
4874418919fSjohnjiang
4884418919fSjohnjiang dvt = arg;
4894418919fSjohnjiang memset(&dve, 0, sizeof(dve));
4904418919fSjohnjiang
4914418919fSjohnjiang r2 = dvt->in[0].u32;
4924418919fSjohnjiang r3 = dvt->in[1].u64;
4934418919fSjohnjiang r4 = dvt->in[2].u32;
4944418919fSjohnjiang
4954418919fSjohnjiang r2 = (uint32_t)r2 * TEST_MUL_1;
4964418919fSjohnjiang r3 *= TEST_MUL_2;
4974418919fSjohnjiang r4 = (uint32_t)(r4 * r2);
4984418919fSjohnjiang r4 *= r3;
4994418919fSjohnjiang
5004418919fSjohnjiang dve.out[0].u64 = r2;
5014418919fSjohnjiang dve.out[1].u64 = r3;
5024418919fSjohnjiang dve.out[2].u64 = r4;
5034418919fSjohnjiang
5044418919fSjohnjiang return cmp_res(__func__, 1, rc, dve.out, dvt->out, sizeof(dve.out));
5054418919fSjohnjiang }
5064418919fSjohnjiang
5074418919fSjohnjiang /* alu shift test-cases */
5084418919fSjohnjiang static const struct ebpf_insn test_shift1_prog[] = {
5094418919fSjohnjiang
5104418919fSjohnjiang {
5114418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
5124418919fSjohnjiang .dst_reg = EBPF_REG_2,
5134418919fSjohnjiang .src_reg = EBPF_REG_1,
5144418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u32),
5154418919fSjohnjiang },
5164418919fSjohnjiang {
5174418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
5184418919fSjohnjiang .dst_reg = EBPF_REG_3,
5194418919fSjohnjiang .src_reg = EBPF_REG_1,
5204418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[1].u64),
5214418919fSjohnjiang },
5224418919fSjohnjiang {
5234418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
5244418919fSjohnjiang .dst_reg = EBPF_REG_4,
5254418919fSjohnjiang .src_reg = EBPF_REG_1,
5264418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[2].u32),
5274418919fSjohnjiang },
5284418919fSjohnjiang {
5294418919fSjohnjiang .code = (BPF_ALU | BPF_LSH | BPF_K),
5304418919fSjohnjiang .dst_reg = EBPF_REG_2,
5314418919fSjohnjiang .imm = TEST_SHIFT_1,
5324418919fSjohnjiang },
5334418919fSjohnjiang {
5344418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_ARSH | BPF_K),
5354418919fSjohnjiang .dst_reg = EBPF_REG_3,
5364418919fSjohnjiang .imm = TEST_SHIFT_2,
5374418919fSjohnjiang },
5384418919fSjohnjiang {
5394418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
5404418919fSjohnjiang .dst_reg = EBPF_REG_1,
5414418919fSjohnjiang .src_reg = EBPF_REG_2,
5424418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[0].u64),
5434418919fSjohnjiang },
5444418919fSjohnjiang {
5454418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
5464418919fSjohnjiang .dst_reg = EBPF_REG_1,
5474418919fSjohnjiang .src_reg = EBPF_REG_3,
5484418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[1].u64),
5494418919fSjohnjiang },
5504418919fSjohnjiang {
5514418919fSjohnjiang .code = (BPF_ALU | BPF_RSH | BPF_X),
5524418919fSjohnjiang .dst_reg = EBPF_REG_2,
5534418919fSjohnjiang .src_reg = EBPF_REG_4,
5544418919fSjohnjiang },
5554418919fSjohnjiang {
5564418919fSjohnjiang .code = (EBPF_ALU64 | BPF_LSH | BPF_X),
5574418919fSjohnjiang .dst_reg = EBPF_REG_3,
5584418919fSjohnjiang .src_reg = EBPF_REG_4,
5594418919fSjohnjiang },
5604418919fSjohnjiang {
5614418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
5624418919fSjohnjiang .dst_reg = EBPF_REG_1,
5634418919fSjohnjiang .src_reg = EBPF_REG_2,
5644418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[2].u64),
5654418919fSjohnjiang },
5664418919fSjohnjiang {
5674418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
5684418919fSjohnjiang .dst_reg = EBPF_REG_1,
5694418919fSjohnjiang .src_reg = EBPF_REG_3,
5704418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[3].u64),
5714418919fSjohnjiang },
5724418919fSjohnjiang {
5734418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
5744418919fSjohnjiang .dst_reg = EBPF_REG_2,
5754418919fSjohnjiang .src_reg = EBPF_REG_1,
5764418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u32),
5774418919fSjohnjiang },
5784418919fSjohnjiang {
5794418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
5804418919fSjohnjiang .dst_reg = EBPF_REG_3,
5814418919fSjohnjiang .src_reg = EBPF_REG_1,
5824418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[1].u64),
5834418919fSjohnjiang },
5844418919fSjohnjiang {
5854418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
5864418919fSjohnjiang .dst_reg = EBPF_REG_4,
5874418919fSjohnjiang .src_reg = EBPF_REG_1,
5884418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[2].u32),
5894418919fSjohnjiang },
5904418919fSjohnjiang {
5914418919fSjohnjiang .code = (BPF_ALU | BPF_AND | BPF_K),
5924418919fSjohnjiang .dst_reg = EBPF_REG_2,
5934418919fSjohnjiang .imm = sizeof(uint64_t) * CHAR_BIT - 1,
5944418919fSjohnjiang },
5954418919fSjohnjiang {
5964418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_ARSH | BPF_X),
5974418919fSjohnjiang .dst_reg = EBPF_REG_3,
5984418919fSjohnjiang .src_reg = EBPF_REG_2,
5994418919fSjohnjiang },
6004418919fSjohnjiang {
6014418919fSjohnjiang .code = (BPF_ALU | BPF_AND | BPF_K),
6024418919fSjohnjiang .dst_reg = EBPF_REG_2,
6034418919fSjohnjiang .imm = sizeof(uint32_t) * CHAR_BIT - 1,
6044418919fSjohnjiang },
6054418919fSjohnjiang {
6064418919fSjohnjiang .code = (BPF_ALU | BPF_LSH | BPF_X),
6074418919fSjohnjiang .dst_reg = EBPF_REG_4,
6084418919fSjohnjiang .src_reg = EBPF_REG_2,
6094418919fSjohnjiang },
6104418919fSjohnjiang {
6114418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
6124418919fSjohnjiang .dst_reg = EBPF_REG_1,
6134418919fSjohnjiang .src_reg = EBPF_REG_4,
6144418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[4].u64),
6154418919fSjohnjiang },
6164418919fSjohnjiang {
6174418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
6184418919fSjohnjiang .dst_reg = EBPF_REG_1,
6194418919fSjohnjiang .src_reg = EBPF_REG_3,
6204418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[5].u64),
6214418919fSjohnjiang },
6224418919fSjohnjiang /* return 1 */
6234418919fSjohnjiang {
6244418919fSjohnjiang .code = (BPF_ALU | EBPF_MOV | BPF_K),
6254418919fSjohnjiang .dst_reg = EBPF_REG_0,
6264418919fSjohnjiang .imm = 1,
6274418919fSjohnjiang },
6284418919fSjohnjiang {
6294418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
6304418919fSjohnjiang },
6314418919fSjohnjiang };
6324418919fSjohnjiang
6334418919fSjohnjiang static void
test_shift1_prepare(void * arg)6344418919fSjohnjiang test_shift1_prepare(void *arg)
6354418919fSjohnjiang {
6364418919fSjohnjiang struct dummy_vect8 *dv;
6374418919fSjohnjiang uint64_t v;
6384418919fSjohnjiang
6394418919fSjohnjiang dv = arg;
6404418919fSjohnjiang
6414418919fSjohnjiang v = rte_rand();
6424418919fSjohnjiang
6434418919fSjohnjiang memset(dv, 0, sizeof(*dv));
6444418919fSjohnjiang dv->in[0].u32 = v;
6454418919fSjohnjiang dv->in[1].u64 = v << 12 | v >> 6;
6464418919fSjohnjiang dv->in[2].u32 = (-v ^ 5);
6474418919fSjohnjiang }
6484418919fSjohnjiang
6494418919fSjohnjiang static int
test_shift1_check(uint64_t rc,const void * arg)6504418919fSjohnjiang test_shift1_check(uint64_t rc, const void *arg)
6514418919fSjohnjiang {
6524418919fSjohnjiang uint64_t r2, r3, r4;
6534418919fSjohnjiang const struct dummy_vect8 *dvt;
6544418919fSjohnjiang struct dummy_vect8 dve;
6554418919fSjohnjiang
6564418919fSjohnjiang dvt = arg;
6574418919fSjohnjiang memset(&dve, 0, sizeof(dve));
6584418919fSjohnjiang
6594418919fSjohnjiang r2 = dvt->in[0].u32;
6604418919fSjohnjiang r3 = dvt->in[1].u64;
6614418919fSjohnjiang r4 = dvt->in[2].u32;
6624418919fSjohnjiang
6634418919fSjohnjiang r2 = (uint32_t)r2 << TEST_SHIFT_1;
6644418919fSjohnjiang r3 = (int64_t)r3 >> TEST_SHIFT_2;
6654418919fSjohnjiang
6664418919fSjohnjiang dve.out[0].u64 = r2;
6674418919fSjohnjiang dve.out[1].u64 = r3;
6684418919fSjohnjiang
6694418919fSjohnjiang r2 = (uint32_t)r2 >> r4;
6704418919fSjohnjiang r3 <<= r4;
6714418919fSjohnjiang
6724418919fSjohnjiang dve.out[2].u64 = r2;
6734418919fSjohnjiang dve.out[3].u64 = r3;
6744418919fSjohnjiang
6754418919fSjohnjiang r2 = dvt->in[0].u32;
6764418919fSjohnjiang r3 = dvt->in[1].u64;
6774418919fSjohnjiang r4 = dvt->in[2].u32;
6784418919fSjohnjiang
6794418919fSjohnjiang r2 &= sizeof(uint64_t) * CHAR_BIT - 1;
6804418919fSjohnjiang r3 = (int64_t)r3 >> r2;
6814418919fSjohnjiang r2 &= sizeof(uint32_t) * CHAR_BIT - 1;
6824418919fSjohnjiang r4 = (uint32_t)r4 << r2;
6834418919fSjohnjiang
6844418919fSjohnjiang dve.out[4].u64 = r4;
6854418919fSjohnjiang dve.out[5].u64 = r3;
6864418919fSjohnjiang
6874418919fSjohnjiang return cmp_res(__func__, 1, rc, dve.out, dvt->out, sizeof(dve.out));
6884418919fSjohnjiang }
6894418919fSjohnjiang
6904418919fSjohnjiang /* jmp test-cases */
6914418919fSjohnjiang static const struct ebpf_insn test_jump1_prog[] = {
6924418919fSjohnjiang
6934418919fSjohnjiang [0] = {
6944418919fSjohnjiang .code = (BPF_ALU | EBPF_MOV | BPF_K),
6954418919fSjohnjiang .dst_reg = EBPF_REG_0,
6964418919fSjohnjiang .imm = 0,
6974418919fSjohnjiang },
6984418919fSjohnjiang [1] = {
6994418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
7004418919fSjohnjiang .dst_reg = EBPF_REG_2,
7014418919fSjohnjiang .src_reg = EBPF_REG_1,
7024418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u32),
7034418919fSjohnjiang },
7044418919fSjohnjiang [2] = {
7054418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
7064418919fSjohnjiang .dst_reg = EBPF_REG_3,
7074418919fSjohnjiang .src_reg = EBPF_REG_1,
7084418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u64),
7094418919fSjohnjiang },
7104418919fSjohnjiang [3] = {
7114418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
7124418919fSjohnjiang .dst_reg = EBPF_REG_4,
7134418919fSjohnjiang .src_reg = EBPF_REG_1,
7144418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[1].u32),
7154418919fSjohnjiang },
7164418919fSjohnjiang [4] = {
7174418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
7184418919fSjohnjiang .dst_reg = EBPF_REG_5,
7194418919fSjohnjiang .src_reg = EBPF_REG_1,
7204418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[1].u64),
7214418919fSjohnjiang },
7224418919fSjohnjiang [5] = {
7234418919fSjohnjiang .code = (BPF_JMP | BPF_JEQ | BPF_K),
7244418919fSjohnjiang .dst_reg = EBPF_REG_2,
7254418919fSjohnjiang .imm = TEST_JCC_1,
7264418919fSjohnjiang .off = 8,
7274418919fSjohnjiang },
7284418919fSjohnjiang [6] = {
7294418919fSjohnjiang .code = (BPF_JMP | EBPF_JSLE | BPF_K),
7304418919fSjohnjiang .dst_reg = EBPF_REG_3,
7314418919fSjohnjiang .imm = TEST_JCC_2,
7324418919fSjohnjiang .off = 9,
7334418919fSjohnjiang },
7344418919fSjohnjiang [7] = {
7354418919fSjohnjiang .code = (BPF_JMP | BPF_JGT | BPF_K),
7364418919fSjohnjiang .dst_reg = EBPF_REG_4,
7374418919fSjohnjiang .imm = TEST_JCC_3,
7384418919fSjohnjiang .off = 10,
7394418919fSjohnjiang },
7404418919fSjohnjiang [8] = {
7414418919fSjohnjiang .code = (BPF_JMP | BPF_JSET | BPF_K),
7424418919fSjohnjiang .dst_reg = EBPF_REG_5,
7434418919fSjohnjiang .imm = TEST_JCC_4,
7444418919fSjohnjiang .off = 11,
7454418919fSjohnjiang },
7464418919fSjohnjiang [9] = {
7474418919fSjohnjiang .code = (BPF_JMP | EBPF_JNE | BPF_X),
7484418919fSjohnjiang .dst_reg = EBPF_REG_2,
7494418919fSjohnjiang .src_reg = EBPF_REG_3,
7504418919fSjohnjiang .off = 12,
7514418919fSjohnjiang },
7524418919fSjohnjiang [10] = {
7534418919fSjohnjiang .code = (BPF_JMP | EBPF_JSGT | BPF_X),
7544418919fSjohnjiang .dst_reg = EBPF_REG_2,
7554418919fSjohnjiang .src_reg = EBPF_REG_4,
7564418919fSjohnjiang .off = 13,
7574418919fSjohnjiang },
7584418919fSjohnjiang [11] = {
7594418919fSjohnjiang .code = (BPF_JMP | EBPF_JLE | BPF_X),
7604418919fSjohnjiang .dst_reg = EBPF_REG_2,
7614418919fSjohnjiang .src_reg = EBPF_REG_5,
7624418919fSjohnjiang .off = 14,
7634418919fSjohnjiang },
7644418919fSjohnjiang [12] = {
7654418919fSjohnjiang .code = (BPF_JMP | BPF_JSET | BPF_X),
7664418919fSjohnjiang .dst_reg = EBPF_REG_3,
7674418919fSjohnjiang .src_reg = EBPF_REG_5,
7684418919fSjohnjiang .off = 15,
7694418919fSjohnjiang },
7704418919fSjohnjiang [13] = {
7714418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
7724418919fSjohnjiang },
7734418919fSjohnjiang [14] = {
7744418919fSjohnjiang .code = (EBPF_ALU64 | BPF_OR | BPF_K),
7754418919fSjohnjiang .dst_reg = EBPF_REG_0,
7764418919fSjohnjiang .imm = 0x1,
7774418919fSjohnjiang },
7784418919fSjohnjiang [15] = {
7794418919fSjohnjiang .code = (BPF_JMP | BPF_JA),
7804418919fSjohnjiang .off = -10,
7814418919fSjohnjiang },
7824418919fSjohnjiang [16] = {
7834418919fSjohnjiang .code = (EBPF_ALU64 | BPF_OR | BPF_K),
7844418919fSjohnjiang .dst_reg = EBPF_REG_0,
7854418919fSjohnjiang .imm = 0x2,
7864418919fSjohnjiang },
7874418919fSjohnjiang [17] = {
7884418919fSjohnjiang .code = (BPF_JMP | BPF_JA),
7894418919fSjohnjiang .off = -11,
7904418919fSjohnjiang },
7914418919fSjohnjiang [18] = {
7924418919fSjohnjiang .code = (EBPF_ALU64 | BPF_OR | BPF_K),
7934418919fSjohnjiang .dst_reg = EBPF_REG_0,
7944418919fSjohnjiang .imm = 0x4,
7954418919fSjohnjiang },
7964418919fSjohnjiang [19] = {
7974418919fSjohnjiang .code = (BPF_JMP | BPF_JA),
7984418919fSjohnjiang .off = -12,
7994418919fSjohnjiang },
8004418919fSjohnjiang [20] = {
8014418919fSjohnjiang .code = (EBPF_ALU64 | BPF_OR | BPF_K),
8024418919fSjohnjiang .dst_reg = EBPF_REG_0,
8034418919fSjohnjiang .imm = 0x8,
8044418919fSjohnjiang },
8054418919fSjohnjiang [21] = {
8064418919fSjohnjiang .code = (BPF_JMP | BPF_JA),
8074418919fSjohnjiang .off = -13,
8084418919fSjohnjiang },
8094418919fSjohnjiang [22] = {
8104418919fSjohnjiang .code = (EBPF_ALU64 | BPF_OR | BPF_K),
8114418919fSjohnjiang .dst_reg = EBPF_REG_0,
8124418919fSjohnjiang .imm = 0x10,
8134418919fSjohnjiang },
8144418919fSjohnjiang [23] = {
8154418919fSjohnjiang .code = (BPF_JMP | BPF_JA),
8164418919fSjohnjiang .off = -14,
8174418919fSjohnjiang },
8184418919fSjohnjiang [24] = {
8194418919fSjohnjiang .code = (EBPF_ALU64 | BPF_OR | BPF_K),
8204418919fSjohnjiang .dst_reg = EBPF_REG_0,
8214418919fSjohnjiang .imm = 0x20,
8224418919fSjohnjiang },
8234418919fSjohnjiang [25] = {
8244418919fSjohnjiang .code = (BPF_JMP | BPF_JA),
8254418919fSjohnjiang .off = -15,
8264418919fSjohnjiang },
8274418919fSjohnjiang [26] = {
8284418919fSjohnjiang .code = (EBPF_ALU64 | BPF_OR | BPF_K),
8294418919fSjohnjiang .dst_reg = EBPF_REG_0,
8304418919fSjohnjiang .imm = 0x40,
8314418919fSjohnjiang },
8324418919fSjohnjiang [27] = {
8334418919fSjohnjiang .code = (BPF_JMP | BPF_JA),
8344418919fSjohnjiang .off = -16,
8354418919fSjohnjiang },
8364418919fSjohnjiang [28] = {
8374418919fSjohnjiang .code = (EBPF_ALU64 | BPF_OR | BPF_K),
8384418919fSjohnjiang .dst_reg = EBPF_REG_0,
8394418919fSjohnjiang .imm = 0x80,
8404418919fSjohnjiang },
8414418919fSjohnjiang [29] = {
8424418919fSjohnjiang .code = (BPF_JMP | BPF_JA),
8434418919fSjohnjiang .off = -17,
8444418919fSjohnjiang },
8454418919fSjohnjiang };
8464418919fSjohnjiang
8474418919fSjohnjiang static void
test_jump1_prepare(void * arg)8484418919fSjohnjiang test_jump1_prepare(void *arg)
8494418919fSjohnjiang {
8504418919fSjohnjiang struct dummy_vect8 *dv;
8514418919fSjohnjiang uint64_t v1, v2;
8524418919fSjohnjiang
8534418919fSjohnjiang dv = arg;
8544418919fSjohnjiang
8554418919fSjohnjiang v1 = rte_rand();
8564418919fSjohnjiang v2 = rte_rand();
8574418919fSjohnjiang
8584418919fSjohnjiang memset(dv, 0, sizeof(*dv));
8594418919fSjohnjiang dv->in[0].u64 = v1;
8604418919fSjohnjiang dv->in[1].u64 = v2;
8614418919fSjohnjiang dv->in[0].u32 = (v1 << 12) + (v2 >> 6);
8624418919fSjohnjiang dv->in[1].u32 = (v2 << 12) - (v1 >> 6);
8634418919fSjohnjiang }
8644418919fSjohnjiang
8654418919fSjohnjiang static int
test_jump1_check(uint64_t rc,const void * arg)8664418919fSjohnjiang test_jump1_check(uint64_t rc, const void *arg)
8674418919fSjohnjiang {
8684418919fSjohnjiang uint64_t r2, r3, r4, r5, rv;
8694418919fSjohnjiang const struct dummy_vect8 *dvt;
8704418919fSjohnjiang
8714418919fSjohnjiang dvt = arg;
8724418919fSjohnjiang
8734418919fSjohnjiang rv = 0;
8744418919fSjohnjiang r2 = dvt->in[0].u32;
8754418919fSjohnjiang r3 = dvt->in[0].u64;
8764418919fSjohnjiang r4 = dvt->in[1].u32;
8774418919fSjohnjiang r5 = dvt->in[1].u64;
8784418919fSjohnjiang
8794418919fSjohnjiang if (r2 == TEST_JCC_1)
8804418919fSjohnjiang rv |= 0x1;
8814418919fSjohnjiang if ((int64_t)r3 <= TEST_JCC_2)
8824418919fSjohnjiang rv |= 0x2;
8834418919fSjohnjiang if (r4 > TEST_JCC_3)
8844418919fSjohnjiang rv |= 0x4;
8854418919fSjohnjiang if (r5 & TEST_JCC_4)
8864418919fSjohnjiang rv |= 0x8;
8874418919fSjohnjiang if (r2 != r3)
8884418919fSjohnjiang rv |= 0x10;
8894418919fSjohnjiang if ((int64_t)r2 > (int64_t)r4)
8904418919fSjohnjiang rv |= 0x20;
8914418919fSjohnjiang if (r2 <= r5)
8924418919fSjohnjiang rv |= 0x40;
8934418919fSjohnjiang if (r3 & r5)
8944418919fSjohnjiang rv |= 0x80;
8954418919fSjohnjiang
8964418919fSjohnjiang return cmp_res(__func__, rv, rc, &rv, &rc, sizeof(rv));
8974418919fSjohnjiang }
8984418919fSjohnjiang
8994418919fSjohnjiang /* Jump test case - check ip4_dest in particular subnet */
9004418919fSjohnjiang static const struct ebpf_insn test_jump2_prog[] = {
9014418919fSjohnjiang
9024418919fSjohnjiang [0] = {
9034418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
9044418919fSjohnjiang .dst_reg = EBPF_REG_2,
9054418919fSjohnjiang .imm = 0xe,
9064418919fSjohnjiang },
9074418919fSjohnjiang [1] = {
9084418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_H),
9094418919fSjohnjiang .dst_reg = EBPF_REG_3,
9104418919fSjohnjiang .src_reg = EBPF_REG_1,
9114418919fSjohnjiang .off = 12,
9124418919fSjohnjiang },
9134418919fSjohnjiang [2] = {
9144418919fSjohnjiang .code = (BPF_JMP | EBPF_JNE | BPF_K),
9154418919fSjohnjiang .dst_reg = EBPF_REG_3,
9164418919fSjohnjiang .off = 2,
9174418919fSjohnjiang .imm = 0x81,
9184418919fSjohnjiang },
9194418919fSjohnjiang [3] = {
9204418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
9214418919fSjohnjiang .dst_reg = EBPF_REG_2,
9224418919fSjohnjiang .imm = 0x12,
9234418919fSjohnjiang },
9244418919fSjohnjiang [4] = {
9254418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_H),
9264418919fSjohnjiang .dst_reg = EBPF_REG_3,
9274418919fSjohnjiang .src_reg = EBPF_REG_1,
9284418919fSjohnjiang .off = 16,
9294418919fSjohnjiang },
9304418919fSjohnjiang [5] = {
9314418919fSjohnjiang .code = (EBPF_ALU64 | BPF_AND | BPF_K),
9324418919fSjohnjiang .dst_reg = EBPF_REG_3,
9334418919fSjohnjiang .imm = 0xffff,
9344418919fSjohnjiang },
9354418919fSjohnjiang [6] = {
9364418919fSjohnjiang .code = (BPF_JMP | EBPF_JNE | BPF_K),
9374418919fSjohnjiang .dst_reg = EBPF_REG_3,
9384418919fSjohnjiang .off = 9,
9394418919fSjohnjiang .imm = 0x8,
9404418919fSjohnjiang },
9414418919fSjohnjiang [7] = {
9424418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
9434418919fSjohnjiang .dst_reg = EBPF_REG_1,
9444418919fSjohnjiang .src_reg = EBPF_REG_2,
9454418919fSjohnjiang },
9464418919fSjohnjiang [8] = {
9474418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
9484418919fSjohnjiang .dst_reg = EBPF_REG_0,
9494418919fSjohnjiang .imm = 0,
9504418919fSjohnjiang },
9514418919fSjohnjiang [9] = {
9524418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
9534418919fSjohnjiang .dst_reg = EBPF_REG_1,
9544418919fSjohnjiang .src_reg = EBPF_REG_1,
9554418919fSjohnjiang .off = 16,
9564418919fSjohnjiang },
9574418919fSjohnjiang [10] = {
9584418919fSjohnjiang .code = (BPF_ALU | EBPF_MOV | BPF_K),
9594418919fSjohnjiang .dst_reg = EBPF_REG_3,
9604418919fSjohnjiang .imm = TEST_NETMASK,
9614418919fSjohnjiang },
9624418919fSjohnjiang [11] = {
9634418919fSjohnjiang .code = (BPF_ALU | EBPF_END | EBPF_TO_BE),
9644418919fSjohnjiang .dst_reg = EBPF_REG_3,
9654418919fSjohnjiang .imm = sizeof(uint32_t) * CHAR_BIT,
9664418919fSjohnjiang },
9674418919fSjohnjiang [12] = {
9684418919fSjohnjiang .code = (BPF_ALU | BPF_AND | BPF_X),
9694418919fSjohnjiang .dst_reg = EBPF_REG_1,
9704418919fSjohnjiang .src_reg = EBPF_REG_3,
9714418919fSjohnjiang },
9724418919fSjohnjiang [13] = {
9734418919fSjohnjiang .code = (BPF_ALU | EBPF_MOV | BPF_K),
9744418919fSjohnjiang .dst_reg = EBPF_REG_3,
9754418919fSjohnjiang .imm = TEST_SUBNET,
9764418919fSjohnjiang },
9774418919fSjohnjiang [14] = {
9784418919fSjohnjiang .code = (BPF_ALU | EBPF_END | EBPF_TO_BE),
9794418919fSjohnjiang .dst_reg = EBPF_REG_3,
9804418919fSjohnjiang .imm = sizeof(uint32_t) * CHAR_BIT,
9814418919fSjohnjiang },
9824418919fSjohnjiang [15] = {
9834418919fSjohnjiang .code = (BPF_JMP | BPF_JEQ | BPF_X),
9844418919fSjohnjiang .dst_reg = EBPF_REG_1,
9854418919fSjohnjiang .src_reg = EBPF_REG_3,
9864418919fSjohnjiang .off = 1,
9874418919fSjohnjiang },
9884418919fSjohnjiang [16] = {
9894418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
9904418919fSjohnjiang .dst_reg = EBPF_REG_0,
9914418919fSjohnjiang .imm = -1,
9924418919fSjohnjiang },
9934418919fSjohnjiang [17] = {
9944418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
9954418919fSjohnjiang },
9964418919fSjohnjiang };
9974418919fSjohnjiang
9984418919fSjohnjiang /* Preparing a vlan packet */
9994418919fSjohnjiang static void
test_jump2_prepare(void * arg)10004418919fSjohnjiang test_jump2_prepare(void *arg)
10014418919fSjohnjiang {
10024418919fSjohnjiang struct dummy_net *dn;
10034418919fSjohnjiang
10044418919fSjohnjiang dn = arg;
10054418919fSjohnjiang memset(dn, 0, sizeof(*dn));
10064418919fSjohnjiang
10074418919fSjohnjiang /*
10084418919fSjohnjiang * Initialize ether header.
10094418919fSjohnjiang */
10104418919fSjohnjiang rte_ether_addr_copy((struct rte_ether_addr *)dst_mac,
10114418919fSjohnjiang &dn->eth_hdr.d_addr);
10124418919fSjohnjiang rte_ether_addr_copy((struct rte_ether_addr *)src_mac,
10134418919fSjohnjiang &dn->eth_hdr.s_addr);
10144418919fSjohnjiang dn->eth_hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);
10154418919fSjohnjiang
10164418919fSjohnjiang /*
10174418919fSjohnjiang * Initialize vlan header.
10184418919fSjohnjiang */
10194418919fSjohnjiang dn->vlan_hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
10204418919fSjohnjiang dn->vlan_hdr.vlan_tci = 32;
10214418919fSjohnjiang
10224418919fSjohnjiang /*
10234418919fSjohnjiang * Initialize IP header.
10244418919fSjohnjiang */
10254418919fSjohnjiang dn->ip_hdr.version_ihl = 0x45; /*IP_VERSION | IP_HDRLEN*/
10264418919fSjohnjiang dn->ip_hdr.time_to_live = 64; /* IP_DEFTTL */
10274418919fSjohnjiang dn->ip_hdr.next_proto_id = IPPROTO_TCP;
10284418919fSjohnjiang dn->ip_hdr.packet_id = rte_cpu_to_be_16(0x463c);
10294418919fSjohnjiang dn->ip_hdr.total_length = rte_cpu_to_be_16(60);
10304418919fSjohnjiang dn->ip_hdr.src_addr = rte_cpu_to_be_32(ip_src_addr);
10314418919fSjohnjiang dn->ip_hdr.dst_addr = rte_cpu_to_be_32(ip_dst_addr);
10324418919fSjohnjiang }
10334418919fSjohnjiang
10344418919fSjohnjiang static int
test_jump2_check(uint64_t rc,const void * arg)10354418919fSjohnjiang test_jump2_check(uint64_t rc, const void *arg)
10364418919fSjohnjiang {
10374418919fSjohnjiang const struct rte_ether_hdr *eth_hdr = arg;
10384418919fSjohnjiang const struct rte_ipv4_hdr *ipv4_hdr;
10394418919fSjohnjiang const void *next = eth_hdr;
10404418919fSjohnjiang uint16_t eth_type;
10414418919fSjohnjiang uint64_t v = -1;
10424418919fSjohnjiang
10434418919fSjohnjiang if (eth_hdr->ether_type == htons(0x8100)) {
10444418919fSjohnjiang const struct rte_vlan_hdr *vlan_hdr =
10454418919fSjohnjiang (const void *)(eth_hdr + 1);
10464418919fSjohnjiang eth_type = vlan_hdr->eth_proto;
10474418919fSjohnjiang next = vlan_hdr + 1;
10484418919fSjohnjiang } else {
10494418919fSjohnjiang eth_type = eth_hdr->ether_type;
10504418919fSjohnjiang next = eth_hdr + 1;
10514418919fSjohnjiang }
10524418919fSjohnjiang
10534418919fSjohnjiang if (eth_type == htons(0x0800)) {
10544418919fSjohnjiang ipv4_hdr = next;
10554418919fSjohnjiang if ((ipv4_hdr->dst_addr & rte_cpu_to_be_32(TEST_NETMASK)) ==
10564418919fSjohnjiang rte_cpu_to_be_32(TEST_SUBNET)) {
10574418919fSjohnjiang v = 0;
10584418919fSjohnjiang }
10594418919fSjohnjiang }
10604418919fSjohnjiang
10614418919fSjohnjiang return cmp_res(__func__, v, rc, arg, arg, sizeof(arg));
10624418919fSjohnjiang }
10634418919fSjohnjiang
10644418919fSjohnjiang /* alu (add, sub, and, or, xor, neg) test-cases */
10654418919fSjohnjiang static const struct ebpf_insn test_alu1_prog[] = {
10664418919fSjohnjiang
10674418919fSjohnjiang {
10684418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
10694418919fSjohnjiang .dst_reg = EBPF_REG_2,
10704418919fSjohnjiang .src_reg = EBPF_REG_1,
10714418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u32),
10724418919fSjohnjiang },
10734418919fSjohnjiang {
10744418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
10754418919fSjohnjiang .dst_reg = EBPF_REG_3,
10764418919fSjohnjiang .src_reg = EBPF_REG_1,
10774418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u64),
10784418919fSjohnjiang },
10794418919fSjohnjiang {
10804418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
10814418919fSjohnjiang .dst_reg = EBPF_REG_4,
10824418919fSjohnjiang .src_reg = EBPF_REG_1,
10834418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[1].u32),
10844418919fSjohnjiang },
10854418919fSjohnjiang {
10864418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
10874418919fSjohnjiang .dst_reg = EBPF_REG_5,
10884418919fSjohnjiang .src_reg = EBPF_REG_1,
10894418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[1].u64),
10904418919fSjohnjiang },
10914418919fSjohnjiang {
10924418919fSjohnjiang .code = (BPF_ALU | BPF_AND | BPF_K),
10934418919fSjohnjiang .dst_reg = EBPF_REG_2,
10944418919fSjohnjiang .imm = TEST_FILL_1,
10954418919fSjohnjiang },
10964418919fSjohnjiang {
10974418919fSjohnjiang .code = (EBPF_ALU64 | BPF_OR | BPF_K),
10984418919fSjohnjiang .dst_reg = EBPF_REG_3,
10994418919fSjohnjiang .imm = TEST_FILL_1,
11004418919fSjohnjiang },
11014418919fSjohnjiang {
11024418919fSjohnjiang .code = (BPF_ALU | BPF_XOR | BPF_K),
11034418919fSjohnjiang .dst_reg = EBPF_REG_4,
11044418919fSjohnjiang .imm = TEST_FILL_1,
11054418919fSjohnjiang },
11064418919fSjohnjiang {
11074418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_K),
11084418919fSjohnjiang .dst_reg = EBPF_REG_5,
11094418919fSjohnjiang .imm = TEST_FILL_1,
11104418919fSjohnjiang },
11114418919fSjohnjiang {
11124418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
11134418919fSjohnjiang .dst_reg = EBPF_REG_1,
11144418919fSjohnjiang .src_reg = EBPF_REG_2,
11154418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[0].u64),
11164418919fSjohnjiang },
11174418919fSjohnjiang {
11184418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
11194418919fSjohnjiang .dst_reg = EBPF_REG_1,
11204418919fSjohnjiang .src_reg = EBPF_REG_3,
11214418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[1].u64),
11224418919fSjohnjiang },
11234418919fSjohnjiang {
11244418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
11254418919fSjohnjiang .dst_reg = EBPF_REG_1,
11264418919fSjohnjiang .src_reg = EBPF_REG_4,
11274418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[2].u64),
11284418919fSjohnjiang },
11294418919fSjohnjiang {
11304418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
11314418919fSjohnjiang .dst_reg = EBPF_REG_1,
11324418919fSjohnjiang .src_reg = EBPF_REG_5,
11334418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[3].u64),
11344418919fSjohnjiang },
11354418919fSjohnjiang {
11364418919fSjohnjiang .code = (BPF_ALU | BPF_OR | BPF_X),
11374418919fSjohnjiang .dst_reg = EBPF_REG_2,
11384418919fSjohnjiang .src_reg = EBPF_REG_3,
11394418919fSjohnjiang },
11404418919fSjohnjiang {
11414418919fSjohnjiang .code = (EBPF_ALU64 | BPF_XOR | BPF_X),
11424418919fSjohnjiang .dst_reg = EBPF_REG_3,
11434418919fSjohnjiang .src_reg = EBPF_REG_4,
11444418919fSjohnjiang },
11454418919fSjohnjiang {
11464418919fSjohnjiang .code = (BPF_ALU | BPF_SUB | BPF_X),
11474418919fSjohnjiang .dst_reg = EBPF_REG_4,
11484418919fSjohnjiang .src_reg = EBPF_REG_5,
11494418919fSjohnjiang },
11504418919fSjohnjiang {
11514418919fSjohnjiang .code = (EBPF_ALU64 | BPF_AND | BPF_X),
11524418919fSjohnjiang .dst_reg = EBPF_REG_5,
11534418919fSjohnjiang .src_reg = EBPF_REG_2,
11544418919fSjohnjiang },
11554418919fSjohnjiang {
11564418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
11574418919fSjohnjiang .dst_reg = EBPF_REG_1,
11584418919fSjohnjiang .src_reg = EBPF_REG_2,
11594418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[4].u64),
11604418919fSjohnjiang },
11614418919fSjohnjiang {
11624418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
11634418919fSjohnjiang .dst_reg = EBPF_REG_1,
11644418919fSjohnjiang .src_reg = EBPF_REG_3,
11654418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[5].u64),
11664418919fSjohnjiang },
11674418919fSjohnjiang {
11684418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
11694418919fSjohnjiang .dst_reg = EBPF_REG_1,
11704418919fSjohnjiang .src_reg = EBPF_REG_4,
11714418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[6].u64),
11724418919fSjohnjiang },
11734418919fSjohnjiang {
11744418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
11754418919fSjohnjiang .dst_reg = EBPF_REG_1,
11764418919fSjohnjiang .src_reg = EBPF_REG_5,
11774418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[7].u64),
11784418919fSjohnjiang },
11794418919fSjohnjiang /* return (-r2 + (-r3)) */
11804418919fSjohnjiang {
11814418919fSjohnjiang .code = (BPF_ALU | BPF_NEG),
11824418919fSjohnjiang .dst_reg = EBPF_REG_2,
11834418919fSjohnjiang },
11844418919fSjohnjiang {
11854418919fSjohnjiang .code = (EBPF_ALU64 | BPF_NEG),
11864418919fSjohnjiang .dst_reg = EBPF_REG_3,
11874418919fSjohnjiang },
11884418919fSjohnjiang {
11894418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
11904418919fSjohnjiang .dst_reg = EBPF_REG_2,
11914418919fSjohnjiang .src_reg = EBPF_REG_3,
11924418919fSjohnjiang },
11934418919fSjohnjiang {
11944418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
11954418919fSjohnjiang .dst_reg = EBPF_REG_0,
11964418919fSjohnjiang .src_reg = EBPF_REG_2,
11974418919fSjohnjiang },
11984418919fSjohnjiang {
11994418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
12004418919fSjohnjiang },
12014418919fSjohnjiang };
12024418919fSjohnjiang
12034418919fSjohnjiang static int
test_alu1_check(uint64_t rc,const void * arg)12044418919fSjohnjiang test_alu1_check(uint64_t rc, const void *arg)
12054418919fSjohnjiang {
12064418919fSjohnjiang uint64_t r2, r3, r4, r5, rv;
12074418919fSjohnjiang const struct dummy_vect8 *dvt;
12084418919fSjohnjiang struct dummy_vect8 dve;
12094418919fSjohnjiang
12104418919fSjohnjiang dvt = arg;
12114418919fSjohnjiang memset(&dve, 0, sizeof(dve));
12124418919fSjohnjiang
12134418919fSjohnjiang r2 = dvt->in[0].u32;
12144418919fSjohnjiang r3 = dvt->in[0].u64;
12154418919fSjohnjiang r4 = dvt->in[1].u32;
12164418919fSjohnjiang r5 = dvt->in[1].u64;
12174418919fSjohnjiang
12184418919fSjohnjiang r2 = (uint32_t)r2 & TEST_FILL_1;
12194418919fSjohnjiang r3 |= (int32_t) TEST_FILL_1;
12204418919fSjohnjiang r4 = (uint32_t)r4 ^ TEST_FILL_1;
12214418919fSjohnjiang r5 += (int32_t)TEST_FILL_1;
12224418919fSjohnjiang
12234418919fSjohnjiang dve.out[0].u64 = r2;
12244418919fSjohnjiang dve.out[1].u64 = r3;
12254418919fSjohnjiang dve.out[2].u64 = r4;
12264418919fSjohnjiang dve.out[3].u64 = r5;
12274418919fSjohnjiang
12284418919fSjohnjiang r2 = (uint32_t)r2 | (uint32_t)r3;
12294418919fSjohnjiang r3 ^= r4;
12304418919fSjohnjiang r4 = (uint32_t)r4 - (uint32_t)r5;
12314418919fSjohnjiang r5 &= r2;
12324418919fSjohnjiang
12334418919fSjohnjiang dve.out[4].u64 = r2;
12344418919fSjohnjiang dve.out[5].u64 = r3;
12354418919fSjohnjiang dve.out[6].u64 = r4;
12364418919fSjohnjiang dve.out[7].u64 = r5;
12374418919fSjohnjiang
12384418919fSjohnjiang r2 = -(int32_t)r2;
12394418919fSjohnjiang rv = (uint32_t)r2;
12404418919fSjohnjiang r3 = -r3;
12414418919fSjohnjiang rv += r3;
12424418919fSjohnjiang
12434418919fSjohnjiang return cmp_res(__func__, rv, rc, dve.out, dvt->out, sizeof(dve.out));
12444418919fSjohnjiang }
12454418919fSjohnjiang
12464418919fSjohnjiang /* endianness conversions (BE->LE/LE->BE) test-cases */
12474418919fSjohnjiang static const struct ebpf_insn test_bele1_prog[] = {
12484418919fSjohnjiang
12494418919fSjohnjiang {
12504418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_H),
12514418919fSjohnjiang .dst_reg = EBPF_REG_2,
12524418919fSjohnjiang .src_reg = EBPF_REG_1,
12534418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u16),
12544418919fSjohnjiang },
12554418919fSjohnjiang {
12564418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
12574418919fSjohnjiang .dst_reg = EBPF_REG_3,
12584418919fSjohnjiang .src_reg = EBPF_REG_1,
12594418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u32),
12604418919fSjohnjiang },
12614418919fSjohnjiang {
12624418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
12634418919fSjohnjiang .dst_reg = EBPF_REG_4,
12644418919fSjohnjiang .src_reg = EBPF_REG_1,
12654418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u64),
12664418919fSjohnjiang },
12674418919fSjohnjiang {
12684418919fSjohnjiang .code = (BPF_ALU | EBPF_END | EBPF_TO_BE),
12694418919fSjohnjiang .dst_reg = EBPF_REG_2,
12704418919fSjohnjiang .imm = sizeof(uint16_t) * CHAR_BIT,
12714418919fSjohnjiang },
12724418919fSjohnjiang {
12734418919fSjohnjiang .code = (BPF_ALU | EBPF_END | EBPF_TO_BE),
12744418919fSjohnjiang .dst_reg = EBPF_REG_3,
12754418919fSjohnjiang .imm = sizeof(uint32_t) * CHAR_BIT,
12764418919fSjohnjiang },
12774418919fSjohnjiang {
12784418919fSjohnjiang .code = (BPF_ALU | EBPF_END | EBPF_TO_BE),
12794418919fSjohnjiang .dst_reg = EBPF_REG_4,
12804418919fSjohnjiang .imm = sizeof(uint64_t) * CHAR_BIT,
12814418919fSjohnjiang },
12824418919fSjohnjiang {
12834418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
12844418919fSjohnjiang .dst_reg = EBPF_REG_1,
12854418919fSjohnjiang .src_reg = EBPF_REG_2,
12864418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[0].u64),
12874418919fSjohnjiang },
12884418919fSjohnjiang {
12894418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
12904418919fSjohnjiang .dst_reg = EBPF_REG_1,
12914418919fSjohnjiang .src_reg = EBPF_REG_3,
12924418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[1].u64),
12934418919fSjohnjiang },
12944418919fSjohnjiang {
12954418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
12964418919fSjohnjiang .dst_reg = EBPF_REG_1,
12974418919fSjohnjiang .src_reg = EBPF_REG_4,
12984418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[2].u64),
12994418919fSjohnjiang },
13004418919fSjohnjiang {
13014418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_H),
13024418919fSjohnjiang .dst_reg = EBPF_REG_2,
13034418919fSjohnjiang .src_reg = EBPF_REG_1,
13044418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u16),
13054418919fSjohnjiang },
13064418919fSjohnjiang {
13074418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
13084418919fSjohnjiang .dst_reg = EBPF_REG_3,
13094418919fSjohnjiang .src_reg = EBPF_REG_1,
13104418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u32),
13114418919fSjohnjiang },
13124418919fSjohnjiang {
13134418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
13144418919fSjohnjiang .dst_reg = EBPF_REG_4,
13154418919fSjohnjiang .src_reg = EBPF_REG_1,
13164418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u64),
13174418919fSjohnjiang },
13184418919fSjohnjiang {
13194418919fSjohnjiang .code = (BPF_ALU | EBPF_END | EBPF_TO_LE),
13204418919fSjohnjiang .dst_reg = EBPF_REG_2,
13214418919fSjohnjiang .imm = sizeof(uint16_t) * CHAR_BIT,
13224418919fSjohnjiang },
13234418919fSjohnjiang {
13244418919fSjohnjiang .code = (BPF_ALU | EBPF_END | EBPF_TO_LE),
13254418919fSjohnjiang .dst_reg = EBPF_REG_3,
13264418919fSjohnjiang .imm = sizeof(uint32_t) * CHAR_BIT,
13274418919fSjohnjiang },
13284418919fSjohnjiang {
13294418919fSjohnjiang .code = (BPF_ALU | EBPF_END | EBPF_TO_LE),
13304418919fSjohnjiang .dst_reg = EBPF_REG_4,
13314418919fSjohnjiang .imm = sizeof(uint64_t) * CHAR_BIT,
13324418919fSjohnjiang },
13334418919fSjohnjiang {
13344418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
13354418919fSjohnjiang .dst_reg = EBPF_REG_1,
13364418919fSjohnjiang .src_reg = EBPF_REG_2,
13374418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[3].u64),
13384418919fSjohnjiang },
13394418919fSjohnjiang {
13404418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
13414418919fSjohnjiang .dst_reg = EBPF_REG_1,
13424418919fSjohnjiang .src_reg = EBPF_REG_3,
13434418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[4].u64),
13444418919fSjohnjiang },
13454418919fSjohnjiang {
13464418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
13474418919fSjohnjiang .dst_reg = EBPF_REG_1,
13484418919fSjohnjiang .src_reg = EBPF_REG_4,
13494418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[5].u64),
13504418919fSjohnjiang },
13514418919fSjohnjiang /* return 1 */
13524418919fSjohnjiang {
13534418919fSjohnjiang .code = (BPF_ALU | EBPF_MOV | BPF_K),
13544418919fSjohnjiang .dst_reg = EBPF_REG_0,
13554418919fSjohnjiang .imm = 1,
13564418919fSjohnjiang },
13574418919fSjohnjiang {
13584418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
13594418919fSjohnjiang },
13604418919fSjohnjiang };
13614418919fSjohnjiang
13624418919fSjohnjiang static void
test_bele1_prepare(void * arg)13634418919fSjohnjiang test_bele1_prepare(void *arg)
13644418919fSjohnjiang {
13654418919fSjohnjiang struct dummy_vect8 *dv;
13664418919fSjohnjiang
13674418919fSjohnjiang dv = arg;
13684418919fSjohnjiang
13694418919fSjohnjiang memset(dv, 0, sizeof(*dv));
13704418919fSjohnjiang dv->in[0].u64 = rte_rand();
13714418919fSjohnjiang dv->in[0].u32 = dv->in[0].u64;
13724418919fSjohnjiang dv->in[0].u16 = dv->in[0].u64;
13734418919fSjohnjiang }
13744418919fSjohnjiang
13754418919fSjohnjiang static int
test_bele1_check(uint64_t rc,const void * arg)13764418919fSjohnjiang test_bele1_check(uint64_t rc, const void *arg)
13774418919fSjohnjiang {
13784418919fSjohnjiang uint64_t r2, r3, r4;
13794418919fSjohnjiang const struct dummy_vect8 *dvt;
13804418919fSjohnjiang struct dummy_vect8 dve;
13814418919fSjohnjiang
13824418919fSjohnjiang dvt = arg;
13834418919fSjohnjiang memset(&dve, 0, sizeof(dve));
13844418919fSjohnjiang
13854418919fSjohnjiang r2 = dvt->in[0].u16;
13864418919fSjohnjiang r3 = dvt->in[0].u32;
13874418919fSjohnjiang r4 = dvt->in[0].u64;
13884418919fSjohnjiang
13894418919fSjohnjiang r2 = rte_cpu_to_be_16(r2);
13904418919fSjohnjiang r3 = rte_cpu_to_be_32(r3);
13914418919fSjohnjiang r4 = rte_cpu_to_be_64(r4);
13924418919fSjohnjiang
13934418919fSjohnjiang dve.out[0].u64 = r2;
13944418919fSjohnjiang dve.out[1].u64 = r3;
13954418919fSjohnjiang dve.out[2].u64 = r4;
13964418919fSjohnjiang
13974418919fSjohnjiang r2 = dvt->in[0].u16;
13984418919fSjohnjiang r3 = dvt->in[0].u32;
13994418919fSjohnjiang r4 = dvt->in[0].u64;
14004418919fSjohnjiang
14014418919fSjohnjiang r2 = rte_cpu_to_le_16(r2);
14024418919fSjohnjiang r3 = rte_cpu_to_le_32(r3);
14034418919fSjohnjiang r4 = rte_cpu_to_le_64(r4);
14044418919fSjohnjiang
14054418919fSjohnjiang dve.out[3].u64 = r2;
14064418919fSjohnjiang dve.out[4].u64 = r3;
14074418919fSjohnjiang dve.out[5].u64 = r4;
14084418919fSjohnjiang
14094418919fSjohnjiang return cmp_res(__func__, 1, rc, dve.out, dvt->out, sizeof(dve.out));
14104418919fSjohnjiang }
14114418919fSjohnjiang
14124418919fSjohnjiang /* atomic add test-cases */
14134418919fSjohnjiang static const struct ebpf_insn test_xadd1_prog[] = {
14144418919fSjohnjiang
14154418919fSjohnjiang {
14164418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
14174418919fSjohnjiang .dst_reg = EBPF_REG_2,
14184418919fSjohnjiang .imm = 1,
14194418919fSjohnjiang },
14204418919fSjohnjiang {
14214418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | BPF_W),
14224418919fSjohnjiang .dst_reg = EBPF_REG_1,
14234418919fSjohnjiang .src_reg = EBPF_REG_2,
14244418919fSjohnjiang .off = offsetof(struct dummy_offset, u32),
14254418919fSjohnjiang },
14264418919fSjohnjiang {
14274418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | EBPF_DW),
14284418919fSjohnjiang .dst_reg = EBPF_REG_1,
14294418919fSjohnjiang .src_reg = EBPF_REG_2,
14304418919fSjohnjiang .off = offsetof(struct dummy_offset, u64),
14314418919fSjohnjiang },
14324418919fSjohnjiang {
14334418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
14344418919fSjohnjiang .dst_reg = EBPF_REG_3,
14354418919fSjohnjiang .imm = -1,
14364418919fSjohnjiang },
14374418919fSjohnjiang {
14384418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | BPF_W),
14394418919fSjohnjiang .dst_reg = EBPF_REG_1,
14404418919fSjohnjiang .src_reg = EBPF_REG_3,
14414418919fSjohnjiang .off = offsetof(struct dummy_offset, u32),
14424418919fSjohnjiang },
14434418919fSjohnjiang {
14444418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | EBPF_DW),
14454418919fSjohnjiang .dst_reg = EBPF_REG_1,
14464418919fSjohnjiang .src_reg = EBPF_REG_3,
14474418919fSjohnjiang .off = offsetof(struct dummy_offset, u64),
14484418919fSjohnjiang },
14494418919fSjohnjiang {
14504418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
14514418919fSjohnjiang .dst_reg = EBPF_REG_4,
14524418919fSjohnjiang .imm = TEST_FILL_1,
14534418919fSjohnjiang },
14544418919fSjohnjiang {
14554418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | BPF_W),
14564418919fSjohnjiang .dst_reg = EBPF_REG_1,
14574418919fSjohnjiang .src_reg = EBPF_REG_4,
14584418919fSjohnjiang .off = offsetof(struct dummy_offset, u32),
14594418919fSjohnjiang },
14604418919fSjohnjiang {
14614418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | EBPF_DW),
14624418919fSjohnjiang .dst_reg = EBPF_REG_1,
14634418919fSjohnjiang .src_reg = EBPF_REG_4,
14644418919fSjohnjiang .off = offsetof(struct dummy_offset, u64),
14654418919fSjohnjiang },
14664418919fSjohnjiang {
14674418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
14684418919fSjohnjiang .dst_reg = EBPF_REG_5,
14694418919fSjohnjiang .imm = TEST_MUL_1,
14704418919fSjohnjiang },
14714418919fSjohnjiang {
14724418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | BPF_W),
14734418919fSjohnjiang .dst_reg = EBPF_REG_1,
14744418919fSjohnjiang .src_reg = EBPF_REG_5,
14754418919fSjohnjiang .off = offsetof(struct dummy_offset, u32),
14764418919fSjohnjiang },
14774418919fSjohnjiang {
14784418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | EBPF_DW),
14794418919fSjohnjiang .dst_reg = EBPF_REG_1,
14804418919fSjohnjiang .src_reg = EBPF_REG_5,
14814418919fSjohnjiang .off = offsetof(struct dummy_offset, u64),
14824418919fSjohnjiang },
14834418919fSjohnjiang {
14844418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
14854418919fSjohnjiang .dst_reg = EBPF_REG_6,
14864418919fSjohnjiang .imm = TEST_MUL_2,
14874418919fSjohnjiang },
14884418919fSjohnjiang {
14894418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | BPF_W),
14904418919fSjohnjiang .dst_reg = EBPF_REG_1,
14914418919fSjohnjiang .src_reg = EBPF_REG_6,
14924418919fSjohnjiang .off = offsetof(struct dummy_offset, u32),
14934418919fSjohnjiang },
14944418919fSjohnjiang {
14954418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | EBPF_DW),
14964418919fSjohnjiang .dst_reg = EBPF_REG_1,
14974418919fSjohnjiang .src_reg = EBPF_REG_6,
14984418919fSjohnjiang .off = offsetof(struct dummy_offset, u64),
14994418919fSjohnjiang },
15004418919fSjohnjiang {
15014418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
15024418919fSjohnjiang .dst_reg = EBPF_REG_7,
15034418919fSjohnjiang .imm = TEST_JCC_2,
15044418919fSjohnjiang },
15054418919fSjohnjiang {
15064418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | BPF_W),
15074418919fSjohnjiang .dst_reg = EBPF_REG_1,
15084418919fSjohnjiang .src_reg = EBPF_REG_7,
15094418919fSjohnjiang .off = offsetof(struct dummy_offset, u32),
15104418919fSjohnjiang },
15114418919fSjohnjiang {
15124418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | EBPF_DW),
15134418919fSjohnjiang .dst_reg = EBPF_REG_1,
15144418919fSjohnjiang .src_reg = EBPF_REG_7,
15154418919fSjohnjiang .off = offsetof(struct dummy_offset, u64),
15164418919fSjohnjiang },
15174418919fSjohnjiang {
15184418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
15194418919fSjohnjiang .dst_reg = EBPF_REG_8,
15204418919fSjohnjiang .imm = TEST_JCC_3,
15214418919fSjohnjiang },
15224418919fSjohnjiang {
15234418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | BPF_W),
15244418919fSjohnjiang .dst_reg = EBPF_REG_1,
15254418919fSjohnjiang .src_reg = EBPF_REG_8,
15264418919fSjohnjiang .off = offsetof(struct dummy_offset, u32),
15274418919fSjohnjiang },
15284418919fSjohnjiang {
15294418919fSjohnjiang .code = (BPF_STX | EBPF_XADD | EBPF_DW),
15304418919fSjohnjiang .dst_reg = EBPF_REG_1,
15314418919fSjohnjiang .src_reg = EBPF_REG_8,
15324418919fSjohnjiang .off = offsetof(struct dummy_offset, u64),
15334418919fSjohnjiang },
15344418919fSjohnjiang /* return 1 */
15354418919fSjohnjiang {
15364418919fSjohnjiang .code = (BPF_ALU | EBPF_MOV | BPF_K),
15374418919fSjohnjiang .dst_reg = EBPF_REG_0,
15384418919fSjohnjiang .imm = 1,
15394418919fSjohnjiang },
15404418919fSjohnjiang {
15414418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
15424418919fSjohnjiang },
15434418919fSjohnjiang };
15444418919fSjohnjiang
15454418919fSjohnjiang static int
test_xadd1_check(uint64_t rc,const void * arg)15464418919fSjohnjiang test_xadd1_check(uint64_t rc, const void *arg)
15474418919fSjohnjiang {
15484418919fSjohnjiang uint64_t rv;
15494418919fSjohnjiang const struct dummy_offset *dft;
15504418919fSjohnjiang struct dummy_offset dfe;
15514418919fSjohnjiang
15524418919fSjohnjiang dft = arg;
15534418919fSjohnjiang memset(&dfe, 0, sizeof(dfe));
15544418919fSjohnjiang
15554418919fSjohnjiang rv = 1;
15564418919fSjohnjiang rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv);
15574418919fSjohnjiang rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv);
15584418919fSjohnjiang
15594418919fSjohnjiang rv = -1;
15604418919fSjohnjiang rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv);
15614418919fSjohnjiang rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv);
15624418919fSjohnjiang
15634418919fSjohnjiang rv = (int32_t)TEST_FILL_1;
15644418919fSjohnjiang rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv);
15654418919fSjohnjiang rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv);
15664418919fSjohnjiang
15674418919fSjohnjiang rv = TEST_MUL_1;
15684418919fSjohnjiang rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv);
15694418919fSjohnjiang rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv);
15704418919fSjohnjiang
15714418919fSjohnjiang rv = TEST_MUL_2;
15724418919fSjohnjiang rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv);
15734418919fSjohnjiang rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv);
15744418919fSjohnjiang
15754418919fSjohnjiang rv = TEST_JCC_2;
15764418919fSjohnjiang rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv);
15774418919fSjohnjiang rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv);
15784418919fSjohnjiang
15794418919fSjohnjiang rv = TEST_JCC_3;
15804418919fSjohnjiang rte_atomic32_add((rte_atomic32_t *)&dfe.u32, rv);
15814418919fSjohnjiang rte_atomic64_add((rte_atomic64_t *)&dfe.u64, rv);
15824418919fSjohnjiang
15834418919fSjohnjiang return cmp_res(__func__, 1, rc, &dfe, dft, sizeof(dfe));
15844418919fSjohnjiang }
15854418919fSjohnjiang
15864418919fSjohnjiang /* alu div test-cases */
15874418919fSjohnjiang static const struct ebpf_insn test_div1_prog[] = {
15884418919fSjohnjiang
15894418919fSjohnjiang {
15904418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
15914418919fSjohnjiang .dst_reg = EBPF_REG_2,
15924418919fSjohnjiang .src_reg = EBPF_REG_1,
15934418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[0].u32),
15944418919fSjohnjiang },
15954418919fSjohnjiang {
15964418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
15974418919fSjohnjiang .dst_reg = EBPF_REG_3,
15984418919fSjohnjiang .src_reg = EBPF_REG_1,
15994418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[1].u64),
16004418919fSjohnjiang },
16014418919fSjohnjiang {
16024418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
16034418919fSjohnjiang .dst_reg = EBPF_REG_4,
16044418919fSjohnjiang .src_reg = EBPF_REG_1,
16054418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[2].u32),
16064418919fSjohnjiang },
16074418919fSjohnjiang {
16084418919fSjohnjiang .code = (BPF_ALU | BPF_DIV | BPF_K),
16094418919fSjohnjiang .dst_reg = EBPF_REG_2,
16104418919fSjohnjiang .imm = TEST_MUL_1,
16114418919fSjohnjiang },
16124418919fSjohnjiang {
16134418919fSjohnjiang .code = (EBPF_ALU64 | BPF_MOD | BPF_K),
16144418919fSjohnjiang .dst_reg = EBPF_REG_3,
16154418919fSjohnjiang .imm = TEST_MUL_2,
16164418919fSjohnjiang },
16174418919fSjohnjiang {
16184418919fSjohnjiang .code = (EBPF_ALU64 | BPF_OR | BPF_K),
16194418919fSjohnjiang .dst_reg = EBPF_REG_2,
16204418919fSjohnjiang .imm = 1,
16214418919fSjohnjiang },
16224418919fSjohnjiang {
16234418919fSjohnjiang .code = (EBPF_ALU64 | BPF_OR | BPF_K),
16244418919fSjohnjiang .dst_reg = EBPF_REG_3,
16254418919fSjohnjiang .imm = 1,
16264418919fSjohnjiang },
16274418919fSjohnjiang {
16284418919fSjohnjiang .code = (BPF_ALU | BPF_MOD | BPF_X),
16294418919fSjohnjiang .dst_reg = EBPF_REG_4,
16304418919fSjohnjiang .src_reg = EBPF_REG_2,
16314418919fSjohnjiang },
16324418919fSjohnjiang {
16334418919fSjohnjiang .code = (EBPF_ALU64 | BPF_DIV | BPF_X),
16344418919fSjohnjiang .dst_reg = EBPF_REG_4,
16354418919fSjohnjiang .src_reg = EBPF_REG_3,
16364418919fSjohnjiang },
16374418919fSjohnjiang {
16384418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
16394418919fSjohnjiang .dst_reg = EBPF_REG_1,
16404418919fSjohnjiang .src_reg = EBPF_REG_2,
16414418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[0].u64),
16424418919fSjohnjiang },
16434418919fSjohnjiang {
16444418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
16454418919fSjohnjiang .dst_reg = EBPF_REG_1,
16464418919fSjohnjiang .src_reg = EBPF_REG_3,
16474418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[1].u64),
16484418919fSjohnjiang },
16494418919fSjohnjiang {
16504418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
16514418919fSjohnjiang .dst_reg = EBPF_REG_1,
16524418919fSjohnjiang .src_reg = EBPF_REG_4,
16534418919fSjohnjiang .off = offsetof(struct dummy_vect8, out[2].u64),
16544418919fSjohnjiang },
16554418919fSjohnjiang /* check that we can handle division by zero gracefully. */
16564418919fSjohnjiang {
16574418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
16584418919fSjohnjiang .dst_reg = EBPF_REG_2,
16594418919fSjohnjiang .src_reg = EBPF_REG_1,
16604418919fSjohnjiang .off = offsetof(struct dummy_vect8, in[3].u32),
16614418919fSjohnjiang },
16624418919fSjohnjiang {
16634418919fSjohnjiang .code = (BPF_ALU | BPF_DIV | BPF_X),
16644418919fSjohnjiang .dst_reg = EBPF_REG_4,
16654418919fSjohnjiang .src_reg = EBPF_REG_2,
16664418919fSjohnjiang },
16674418919fSjohnjiang /* return 1 */
16684418919fSjohnjiang {
16694418919fSjohnjiang .code = (BPF_ALU | EBPF_MOV | BPF_K),
16704418919fSjohnjiang .dst_reg = EBPF_REG_0,
16714418919fSjohnjiang .imm = 1,
16724418919fSjohnjiang },
16734418919fSjohnjiang {
16744418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
16754418919fSjohnjiang },
16764418919fSjohnjiang };
16774418919fSjohnjiang
16784418919fSjohnjiang static int
test_div1_check(uint64_t rc,const void * arg)16794418919fSjohnjiang test_div1_check(uint64_t rc, const void *arg)
16804418919fSjohnjiang {
16814418919fSjohnjiang uint64_t r2, r3, r4;
16824418919fSjohnjiang const struct dummy_vect8 *dvt;
16834418919fSjohnjiang struct dummy_vect8 dve;
16844418919fSjohnjiang
16854418919fSjohnjiang dvt = arg;
16864418919fSjohnjiang memset(&dve, 0, sizeof(dve));
16874418919fSjohnjiang
16884418919fSjohnjiang r2 = dvt->in[0].u32;
16894418919fSjohnjiang r3 = dvt->in[1].u64;
16904418919fSjohnjiang r4 = dvt->in[2].u32;
16914418919fSjohnjiang
16924418919fSjohnjiang r2 = (uint32_t)r2 / TEST_MUL_1;
16934418919fSjohnjiang r3 %= TEST_MUL_2;
16944418919fSjohnjiang r2 |= 1;
16954418919fSjohnjiang r3 |= 1;
16964418919fSjohnjiang r4 = (uint32_t)(r4 % r2);
16974418919fSjohnjiang r4 /= r3;
16984418919fSjohnjiang
16994418919fSjohnjiang dve.out[0].u64 = r2;
17004418919fSjohnjiang dve.out[1].u64 = r3;
17014418919fSjohnjiang dve.out[2].u64 = r4;
17024418919fSjohnjiang
17034418919fSjohnjiang /*
17044418919fSjohnjiang * in the test prog we attempted to divide by zero.
17054418919fSjohnjiang * so return value should return 0.
17064418919fSjohnjiang */
17074418919fSjohnjiang return cmp_res(__func__, 0, rc, dve.out, dvt->out, sizeof(dve.out));
17084418919fSjohnjiang }
17094418919fSjohnjiang
17104418919fSjohnjiang /* call test-cases */
17114418919fSjohnjiang static const struct ebpf_insn test_call1_prog[] = {
17124418919fSjohnjiang
17134418919fSjohnjiang {
17144418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
17154418919fSjohnjiang .dst_reg = EBPF_REG_2,
17164418919fSjohnjiang .src_reg = EBPF_REG_1,
17174418919fSjohnjiang .off = offsetof(struct dummy_offset, u32),
17184418919fSjohnjiang },
17194418919fSjohnjiang {
17204418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
17214418919fSjohnjiang .dst_reg = EBPF_REG_3,
17224418919fSjohnjiang .src_reg = EBPF_REG_1,
17234418919fSjohnjiang .off = offsetof(struct dummy_offset, u64),
17244418919fSjohnjiang },
17254418919fSjohnjiang {
17264418919fSjohnjiang .code = (BPF_STX | BPF_MEM | BPF_W),
17274418919fSjohnjiang .dst_reg = EBPF_REG_10,
17284418919fSjohnjiang .src_reg = EBPF_REG_2,
17294418919fSjohnjiang .off = -4,
17304418919fSjohnjiang },
17314418919fSjohnjiang {
17324418919fSjohnjiang .code = (BPF_STX | BPF_MEM | EBPF_DW),
17334418919fSjohnjiang .dst_reg = EBPF_REG_10,
17344418919fSjohnjiang .src_reg = EBPF_REG_3,
17354418919fSjohnjiang .off = -16,
17364418919fSjohnjiang },
17374418919fSjohnjiang {
17384418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
17394418919fSjohnjiang .dst_reg = EBPF_REG_2,
17404418919fSjohnjiang .src_reg = EBPF_REG_10,
17414418919fSjohnjiang },
17424418919fSjohnjiang {
17434418919fSjohnjiang .code = (EBPF_ALU64 | BPF_SUB | BPF_K),
17444418919fSjohnjiang .dst_reg = EBPF_REG_2,
17454418919fSjohnjiang .imm = 4,
17464418919fSjohnjiang },
17474418919fSjohnjiang {
17484418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
17494418919fSjohnjiang .dst_reg = EBPF_REG_3,
17504418919fSjohnjiang .src_reg = EBPF_REG_10,
17514418919fSjohnjiang },
17524418919fSjohnjiang {
17534418919fSjohnjiang .code = (EBPF_ALU64 | BPF_SUB | BPF_K),
17544418919fSjohnjiang .dst_reg = EBPF_REG_3,
17554418919fSjohnjiang .imm = 16,
17564418919fSjohnjiang },
17574418919fSjohnjiang {
17584418919fSjohnjiang .code = (BPF_JMP | EBPF_CALL),
17594418919fSjohnjiang .imm = 0,
17604418919fSjohnjiang },
17614418919fSjohnjiang {
17624418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
17634418919fSjohnjiang .dst_reg = EBPF_REG_2,
17644418919fSjohnjiang .src_reg = EBPF_REG_10,
17654418919fSjohnjiang .off = -4,
17664418919fSjohnjiang },
17674418919fSjohnjiang {
17684418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
17694418919fSjohnjiang .dst_reg = EBPF_REG_0,
17704418919fSjohnjiang .src_reg = EBPF_REG_10,
17714418919fSjohnjiang .off = -16
17724418919fSjohnjiang },
17734418919fSjohnjiang {
17744418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
17754418919fSjohnjiang .dst_reg = EBPF_REG_0,
17764418919fSjohnjiang .src_reg = EBPF_REG_2,
17774418919fSjohnjiang },
17784418919fSjohnjiang {
17794418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
17804418919fSjohnjiang },
17814418919fSjohnjiang };
17824418919fSjohnjiang
17834418919fSjohnjiang static void
dummy_func1(const void * p,uint32_t * v32,uint64_t * v64)17844418919fSjohnjiang dummy_func1(const void *p, uint32_t *v32, uint64_t *v64)
17854418919fSjohnjiang {
17864418919fSjohnjiang const struct dummy_offset *dv;
17874418919fSjohnjiang
17884418919fSjohnjiang dv = p;
17894418919fSjohnjiang
17904418919fSjohnjiang v32[0] += dv->u16;
17914418919fSjohnjiang v64[0] += dv->u8;
17924418919fSjohnjiang }
17934418919fSjohnjiang
17944418919fSjohnjiang static int
test_call1_check(uint64_t rc,const void * arg)17954418919fSjohnjiang test_call1_check(uint64_t rc, const void *arg)
17964418919fSjohnjiang {
17974418919fSjohnjiang uint32_t v32;
17984418919fSjohnjiang uint64_t v64;
17994418919fSjohnjiang const struct dummy_offset *dv;
18004418919fSjohnjiang
18014418919fSjohnjiang dv = arg;
18024418919fSjohnjiang
18034418919fSjohnjiang v32 = dv->u32;
18044418919fSjohnjiang v64 = dv->u64;
18054418919fSjohnjiang dummy_func1(arg, &v32, &v64);
18064418919fSjohnjiang v64 += v32;
18074418919fSjohnjiang
18084418919fSjohnjiang return cmp_res(__func__, v64, rc, dv, dv, sizeof(*dv));
18094418919fSjohnjiang }
18104418919fSjohnjiang
18114418919fSjohnjiang static const struct rte_bpf_xsym test_call1_xsym[] = {
18124418919fSjohnjiang {
18134418919fSjohnjiang .name = RTE_STR(dummy_func1),
18144418919fSjohnjiang .type = RTE_BPF_XTYPE_FUNC,
18154418919fSjohnjiang .func = {
18164418919fSjohnjiang .val = (void *)dummy_func1,
18174418919fSjohnjiang .nb_args = 3,
18184418919fSjohnjiang .args = {
18194418919fSjohnjiang [0] = {
18204418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
18214418919fSjohnjiang .size = sizeof(struct dummy_offset),
18224418919fSjohnjiang },
18234418919fSjohnjiang [1] = {
18244418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
18254418919fSjohnjiang .size = sizeof(uint32_t),
18264418919fSjohnjiang },
18274418919fSjohnjiang [2] = {
18284418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
18294418919fSjohnjiang .size = sizeof(uint64_t),
18304418919fSjohnjiang },
18314418919fSjohnjiang },
18324418919fSjohnjiang },
18334418919fSjohnjiang },
18344418919fSjohnjiang };
18354418919fSjohnjiang
18364418919fSjohnjiang static const struct ebpf_insn test_call2_prog[] = {
18374418919fSjohnjiang
18384418919fSjohnjiang {
18394418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
18404418919fSjohnjiang .dst_reg = EBPF_REG_1,
18414418919fSjohnjiang .src_reg = EBPF_REG_10,
18424418919fSjohnjiang },
18434418919fSjohnjiang {
18444418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_K),
18454418919fSjohnjiang .dst_reg = EBPF_REG_1,
18464418919fSjohnjiang .imm = -(int32_t)sizeof(struct dummy_offset),
18474418919fSjohnjiang },
18484418919fSjohnjiang {
18494418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
18504418919fSjohnjiang .dst_reg = EBPF_REG_2,
18514418919fSjohnjiang .src_reg = EBPF_REG_10,
18524418919fSjohnjiang },
18534418919fSjohnjiang {
18544418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_K),
18554418919fSjohnjiang .dst_reg = EBPF_REG_2,
18564418919fSjohnjiang .imm = -2 * (int32_t)sizeof(struct dummy_offset),
18574418919fSjohnjiang },
18584418919fSjohnjiang {
18594418919fSjohnjiang .code = (BPF_JMP | EBPF_CALL),
18604418919fSjohnjiang .imm = 0,
18614418919fSjohnjiang },
18624418919fSjohnjiang {
18634418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
18644418919fSjohnjiang .dst_reg = EBPF_REG_1,
18654418919fSjohnjiang .src_reg = EBPF_REG_10,
18664418919fSjohnjiang .off = -(int32_t)(sizeof(struct dummy_offset) -
18674418919fSjohnjiang offsetof(struct dummy_offset, u64)),
18684418919fSjohnjiang },
18694418919fSjohnjiang {
18704418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
18714418919fSjohnjiang .dst_reg = EBPF_REG_0,
18724418919fSjohnjiang .src_reg = EBPF_REG_10,
18734418919fSjohnjiang .off = -(int32_t)(sizeof(struct dummy_offset) -
18744418919fSjohnjiang offsetof(struct dummy_offset, u32)),
18754418919fSjohnjiang },
18764418919fSjohnjiang {
18774418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
18784418919fSjohnjiang .dst_reg = EBPF_REG_0,
18794418919fSjohnjiang .src_reg = EBPF_REG_1,
18804418919fSjohnjiang },
18814418919fSjohnjiang {
18824418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_H),
18834418919fSjohnjiang .dst_reg = EBPF_REG_1,
18844418919fSjohnjiang .src_reg = EBPF_REG_10,
18854418919fSjohnjiang .off = -(int32_t)(2 * sizeof(struct dummy_offset) -
18864418919fSjohnjiang offsetof(struct dummy_offset, u16)),
18874418919fSjohnjiang },
18884418919fSjohnjiang {
18894418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
18904418919fSjohnjiang .dst_reg = EBPF_REG_0,
18914418919fSjohnjiang .src_reg = EBPF_REG_1,
18924418919fSjohnjiang },
18934418919fSjohnjiang {
18944418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_B),
18954418919fSjohnjiang .dst_reg = EBPF_REG_1,
18964418919fSjohnjiang .src_reg = EBPF_REG_10,
18974418919fSjohnjiang .off = -(int32_t)(2 * sizeof(struct dummy_offset) -
18984418919fSjohnjiang offsetof(struct dummy_offset, u8)),
18994418919fSjohnjiang },
19004418919fSjohnjiang {
19014418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
19024418919fSjohnjiang .dst_reg = EBPF_REG_0,
19034418919fSjohnjiang .src_reg = EBPF_REG_1,
19044418919fSjohnjiang },
19054418919fSjohnjiang {
19064418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
19074418919fSjohnjiang },
19084418919fSjohnjiang
19094418919fSjohnjiang };
19104418919fSjohnjiang
19114418919fSjohnjiang static void
dummy_func2(struct dummy_offset * a,struct dummy_offset * b)19124418919fSjohnjiang dummy_func2(struct dummy_offset *a, struct dummy_offset *b)
19134418919fSjohnjiang {
19144418919fSjohnjiang uint64_t v;
19154418919fSjohnjiang
19164418919fSjohnjiang v = 0;
19174418919fSjohnjiang a->u64 = v++;
19184418919fSjohnjiang a->u32 = v++;
19194418919fSjohnjiang a->u16 = v++;
19204418919fSjohnjiang a->u8 = v++;
19214418919fSjohnjiang b->u64 = v++;
19224418919fSjohnjiang b->u32 = v++;
19234418919fSjohnjiang b->u16 = v++;
19244418919fSjohnjiang b->u8 = v++;
19254418919fSjohnjiang }
19264418919fSjohnjiang
19274418919fSjohnjiang static int
test_call2_check(uint64_t rc,const void * arg)19284418919fSjohnjiang test_call2_check(uint64_t rc, const void *arg)
19294418919fSjohnjiang {
19304418919fSjohnjiang uint64_t v;
19314418919fSjohnjiang struct dummy_offset a, b;
19324418919fSjohnjiang
19334418919fSjohnjiang RTE_SET_USED(arg);
19344418919fSjohnjiang
19354418919fSjohnjiang dummy_func2(&a, &b);
19364418919fSjohnjiang v = a.u64 + a.u32 + b.u16 + b.u8;
19374418919fSjohnjiang
19380c6bd470Sfengbojiang return cmp_res(__func__, v, rc, arg, arg, 0);
19394418919fSjohnjiang }
19404418919fSjohnjiang
19414418919fSjohnjiang static const struct rte_bpf_xsym test_call2_xsym[] = {
19424418919fSjohnjiang {
19434418919fSjohnjiang .name = RTE_STR(dummy_func2),
19444418919fSjohnjiang .type = RTE_BPF_XTYPE_FUNC,
19454418919fSjohnjiang .func = {
19464418919fSjohnjiang .val = (void *)dummy_func2,
19474418919fSjohnjiang .nb_args = 2,
19484418919fSjohnjiang .args = {
19494418919fSjohnjiang [0] = {
19504418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
19514418919fSjohnjiang .size = sizeof(struct dummy_offset),
19524418919fSjohnjiang },
19534418919fSjohnjiang [1] = {
19544418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
19554418919fSjohnjiang .size = sizeof(struct dummy_offset),
19564418919fSjohnjiang },
19574418919fSjohnjiang },
19584418919fSjohnjiang },
19594418919fSjohnjiang },
19604418919fSjohnjiang };
19614418919fSjohnjiang
19624418919fSjohnjiang static const struct ebpf_insn test_call3_prog[] = {
19634418919fSjohnjiang
19644418919fSjohnjiang {
19654418919fSjohnjiang .code = (BPF_JMP | EBPF_CALL),
19664418919fSjohnjiang .imm = 0,
19674418919fSjohnjiang },
19684418919fSjohnjiang {
19694418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_B),
19704418919fSjohnjiang .dst_reg = EBPF_REG_2,
19714418919fSjohnjiang .src_reg = EBPF_REG_0,
19724418919fSjohnjiang .off = offsetof(struct dummy_offset, u8),
19734418919fSjohnjiang },
19744418919fSjohnjiang {
19754418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_H),
19764418919fSjohnjiang .dst_reg = EBPF_REG_3,
19774418919fSjohnjiang .src_reg = EBPF_REG_0,
19784418919fSjohnjiang .off = offsetof(struct dummy_offset, u16),
19794418919fSjohnjiang },
19804418919fSjohnjiang {
19814418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_W),
19824418919fSjohnjiang .dst_reg = EBPF_REG_4,
19834418919fSjohnjiang .src_reg = EBPF_REG_0,
19844418919fSjohnjiang .off = offsetof(struct dummy_offset, u32),
19854418919fSjohnjiang },
19864418919fSjohnjiang {
19874418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | EBPF_DW),
19884418919fSjohnjiang .dst_reg = EBPF_REG_0,
19894418919fSjohnjiang .src_reg = EBPF_REG_0,
19904418919fSjohnjiang .off = offsetof(struct dummy_offset, u64),
19914418919fSjohnjiang },
19924418919fSjohnjiang /* return sum */
19934418919fSjohnjiang {
19944418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
19954418919fSjohnjiang .dst_reg = EBPF_REG_0,
19964418919fSjohnjiang .src_reg = EBPF_REG_4,
19974418919fSjohnjiang },
19984418919fSjohnjiang {
19994418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
20004418919fSjohnjiang .dst_reg = EBPF_REG_0,
20014418919fSjohnjiang .src_reg = EBPF_REG_3,
20024418919fSjohnjiang },
20034418919fSjohnjiang {
20044418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
20054418919fSjohnjiang .dst_reg = EBPF_REG_0,
20064418919fSjohnjiang .src_reg = EBPF_REG_2,
20074418919fSjohnjiang },
20084418919fSjohnjiang {
20094418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
20104418919fSjohnjiang },
20114418919fSjohnjiang };
20124418919fSjohnjiang
20134418919fSjohnjiang static const struct dummy_offset *
dummy_func3(const struct dummy_vect8 * p)20144418919fSjohnjiang dummy_func3(const struct dummy_vect8 *p)
20154418919fSjohnjiang {
20164418919fSjohnjiang return &p->in[RTE_DIM(p->in) - 1];
20174418919fSjohnjiang }
20184418919fSjohnjiang
20194418919fSjohnjiang static void
test_call3_prepare(void * arg)20204418919fSjohnjiang test_call3_prepare(void *arg)
20214418919fSjohnjiang {
20224418919fSjohnjiang struct dummy_vect8 *pv;
20234418919fSjohnjiang struct dummy_offset *df;
20244418919fSjohnjiang
20254418919fSjohnjiang pv = arg;
20264418919fSjohnjiang df = (struct dummy_offset *)(uintptr_t)dummy_func3(pv);
20274418919fSjohnjiang
20284418919fSjohnjiang memset(pv, 0, sizeof(*pv));
20294418919fSjohnjiang df->u64 = (int32_t)TEST_FILL_1;
20304418919fSjohnjiang df->u32 = df->u64;
20314418919fSjohnjiang df->u16 = df->u64;
20324418919fSjohnjiang df->u8 = df->u64;
20334418919fSjohnjiang }
20344418919fSjohnjiang
20354418919fSjohnjiang static int
test_call3_check(uint64_t rc,const void * arg)20364418919fSjohnjiang test_call3_check(uint64_t rc, const void *arg)
20374418919fSjohnjiang {
20384418919fSjohnjiang uint64_t v;
20394418919fSjohnjiang const struct dummy_vect8 *pv;
20404418919fSjohnjiang const struct dummy_offset *dft;
20414418919fSjohnjiang
20424418919fSjohnjiang pv = arg;
20434418919fSjohnjiang dft = dummy_func3(pv);
20444418919fSjohnjiang
20454418919fSjohnjiang v = dft->u64;
20464418919fSjohnjiang v += dft->u32;
20474418919fSjohnjiang v += dft->u16;
20484418919fSjohnjiang v += dft->u8;
20494418919fSjohnjiang
20504418919fSjohnjiang return cmp_res(__func__, v, rc, pv, pv, sizeof(*pv));
20514418919fSjohnjiang }
20524418919fSjohnjiang
20534418919fSjohnjiang static const struct rte_bpf_xsym test_call3_xsym[] = {
20544418919fSjohnjiang {
20554418919fSjohnjiang .name = RTE_STR(dummy_func3),
20564418919fSjohnjiang .type = RTE_BPF_XTYPE_FUNC,
20574418919fSjohnjiang .func = {
20584418919fSjohnjiang .val = (void *)dummy_func3,
20594418919fSjohnjiang .nb_args = 1,
20604418919fSjohnjiang .args = {
20614418919fSjohnjiang [0] = {
20624418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
20634418919fSjohnjiang .size = sizeof(struct dummy_vect8),
20644418919fSjohnjiang },
20654418919fSjohnjiang },
20664418919fSjohnjiang .ret = {
20674418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
20684418919fSjohnjiang .size = sizeof(struct dummy_offset),
20694418919fSjohnjiang },
20704418919fSjohnjiang },
20714418919fSjohnjiang },
20724418919fSjohnjiang };
20734418919fSjohnjiang
20744418919fSjohnjiang /* Test for stack corruption in multiple function calls */
20754418919fSjohnjiang static const struct ebpf_insn test_call4_prog[] = {
20764418919fSjohnjiang {
20774418919fSjohnjiang .code = (BPF_ST | BPF_MEM | BPF_B),
20784418919fSjohnjiang .dst_reg = EBPF_REG_10,
20794418919fSjohnjiang .off = -4,
20804418919fSjohnjiang .imm = 1,
20814418919fSjohnjiang },
20824418919fSjohnjiang {
20834418919fSjohnjiang .code = (BPF_ST | BPF_MEM | BPF_B),
20844418919fSjohnjiang .dst_reg = EBPF_REG_10,
20854418919fSjohnjiang .off = -3,
20864418919fSjohnjiang .imm = 2,
20874418919fSjohnjiang },
20884418919fSjohnjiang {
20894418919fSjohnjiang .code = (BPF_ST | BPF_MEM | BPF_B),
20904418919fSjohnjiang .dst_reg = EBPF_REG_10,
20914418919fSjohnjiang .off = -2,
20924418919fSjohnjiang .imm = 3,
20934418919fSjohnjiang },
20944418919fSjohnjiang {
20954418919fSjohnjiang .code = (BPF_ST | BPF_MEM | BPF_B),
20964418919fSjohnjiang .dst_reg = EBPF_REG_10,
20974418919fSjohnjiang .off = -1,
20984418919fSjohnjiang .imm = 4,
20994418919fSjohnjiang },
21004418919fSjohnjiang {
21014418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
21024418919fSjohnjiang .dst_reg = EBPF_REG_1,
21034418919fSjohnjiang .src_reg = EBPF_REG_10,
21044418919fSjohnjiang },
21054418919fSjohnjiang {
21064418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
21074418919fSjohnjiang .dst_reg = EBPF_REG_2,
21084418919fSjohnjiang .imm = 4,
21094418919fSjohnjiang },
21104418919fSjohnjiang {
21114418919fSjohnjiang .code = (EBPF_ALU64 | BPF_SUB | BPF_X),
21124418919fSjohnjiang .dst_reg = EBPF_REG_1,
21134418919fSjohnjiang .src_reg = EBPF_REG_2,
21144418919fSjohnjiang },
21154418919fSjohnjiang {
21164418919fSjohnjiang .code = (BPF_JMP | EBPF_CALL),
21174418919fSjohnjiang .imm = 0,
21184418919fSjohnjiang },
21194418919fSjohnjiang {
21204418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_B),
21214418919fSjohnjiang .dst_reg = EBPF_REG_1,
21224418919fSjohnjiang .src_reg = EBPF_REG_10,
21234418919fSjohnjiang .off = -4,
21244418919fSjohnjiang },
21254418919fSjohnjiang {
21264418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_B),
21274418919fSjohnjiang .dst_reg = EBPF_REG_2,
21284418919fSjohnjiang .src_reg = EBPF_REG_10,
21294418919fSjohnjiang .off = -3,
21304418919fSjohnjiang },
21314418919fSjohnjiang {
21324418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_B),
21334418919fSjohnjiang .dst_reg = EBPF_REG_3,
21344418919fSjohnjiang .src_reg = EBPF_REG_10,
21354418919fSjohnjiang .off = -2,
21364418919fSjohnjiang },
21374418919fSjohnjiang {
21384418919fSjohnjiang .code = (BPF_LDX | BPF_MEM | BPF_B),
21394418919fSjohnjiang .dst_reg = EBPF_REG_4,
21404418919fSjohnjiang .src_reg = EBPF_REG_10,
21414418919fSjohnjiang .off = -1,
21424418919fSjohnjiang },
21434418919fSjohnjiang {
21444418919fSjohnjiang .code = (BPF_JMP | EBPF_CALL),
21454418919fSjohnjiang .imm = 1,
21464418919fSjohnjiang },
21474418919fSjohnjiang {
21484418919fSjohnjiang .code = (EBPF_ALU64 | BPF_XOR | BPF_K),
21494418919fSjohnjiang .dst_reg = EBPF_REG_0,
21504418919fSjohnjiang .imm = TEST_MEMFROB,
21514418919fSjohnjiang },
21524418919fSjohnjiang {
21534418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
21544418919fSjohnjiang },
21554418919fSjohnjiang };
21564418919fSjohnjiang
21574418919fSjohnjiang /* Gathering the bytes together */
21584418919fSjohnjiang static uint32_t
dummy_func4_1(uint8_t a,uint8_t b,uint8_t c,uint8_t d)21594418919fSjohnjiang dummy_func4_1(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
21604418919fSjohnjiang {
21614418919fSjohnjiang return (a << 24) | (b << 16) | (c << 8) | (d << 0);
21624418919fSjohnjiang }
21634418919fSjohnjiang
21644418919fSjohnjiang /* Implementation of memfrob */
21654418919fSjohnjiang static uint32_t
dummy_func4_0(uint32_t * s,uint8_t n)21664418919fSjohnjiang dummy_func4_0(uint32_t *s, uint8_t n)
21674418919fSjohnjiang {
21684418919fSjohnjiang char *p = (char *) s;
21694418919fSjohnjiang while (n-- > 0)
21704418919fSjohnjiang *p++ ^= 42;
21714418919fSjohnjiang return *s;
21724418919fSjohnjiang }
21734418919fSjohnjiang
21744418919fSjohnjiang
21754418919fSjohnjiang static int
test_call4_check(uint64_t rc,const void * arg)21764418919fSjohnjiang test_call4_check(uint64_t rc, const void *arg)
21774418919fSjohnjiang {
21784418919fSjohnjiang uint8_t a[4] = {1, 2, 3, 4};
21794418919fSjohnjiang uint32_t s, v = 0;
21804418919fSjohnjiang
21814418919fSjohnjiang RTE_SET_USED(arg);
21824418919fSjohnjiang
21834418919fSjohnjiang s = dummy_func4_0((uint32_t *)a, 4);
21844418919fSjohnjiang
21854418919fSjohnjiang s = dummy_func4_1(a[0], a[1], a[2], a[3]);
21864418919fSjohnjiang
21874418919fSjohnjiang v = s ^ TEST_MEMFROB;
21884418919fSjohnjiang
21894418919fSjohnjiang return cmp_res(__func__, v, rc, &v, &rc, sizeof(v));
21904418919fSjohnjiang }
21914418919fSjohnjiang
21924418919fSjohnjiang static const struct rte_bpf_xsym test_call4_xsym[] = {
21934418919fSjohnjiang [0] = {
21944418919fSjohnjiang .name = RTE_STR(dummy_func4_0),
21954418919fSjohnjiang .type = RTE_BPF_XTYPE_FUNC,
21964418919fSjohnjiang .func = {
21974418919fSjohnjiang .val = (void *)dummy_func4_0,
21984418919fSjohnjiang .nb_args = 2,
21994418919fSjohnjiang .args = {
22004418919fSjohnjiang [0] = {
22014418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
22024418919fSjohnjiang .size = 4 * sizeof(uint8_t),
22034418919fSjohnjiang },
22044418919fSjohnjiang [1] = {
22054418919fSjohnjiang .type = RTE_BPF_ARG_RAW,
22064418919fSjohnjiang .size = sizeof(uint8_t),
22074418919fSjohnjiang },
22084418919fSjohnjiang },
22094418919fSjohnjiang .ret = {
22104418919fSjohnjiang .type = RTE_BPF_ARG_RAW,
22114418919fSjohnjiang .size = sizeof(uint32_t),
22124418919fSjohnjiang },
22134418919fSjohnjiang },
22144418919fSjohnjiang },
22154418919fSjohnjiang [1] = {
22164418919fSjohnjiang .name = RTE_STR(dummy_func4_1),
22174418919fSjohnjiang .type = RTE_BPF_XTYPE_FUNC,
22184418919fSjohnjiang .func = {
22194418919fSjohnjiang .val = (void *)dummy_func4_1,
22204418919fSjohnjiang .nb_args = 4,
22214418919fSjohnjiang .args = {
22224418919fSjohnjiang [0] = {
22234418919fSjohnjiang .type = RTE_BPF_ARG_RAW,
22244418919fSjohnjiang .size = sizeof(uint8_t),
22254418919fSjohnjiang },
22264418919fSjohnjiang [1] = {
22274418919fSjohnjiang .type = RTE_BPF_ARG_RAW,
22284418919fSjohnjiang .size = sizeof(uint8_t),
22294418919fSjohnjiang },
22304418919fSjohnjiang [2] = {
22314418919fSjohnjiang .type = RTE_BPF_ARG_RAW,
22324418919fSjohnjiang .size = sizeof(uint8_t),
22334418919fSjohnjiang },
22344418919fSjohnjiang [3] = {
22354418919fSjohnjiang .type = RTE_BPF_ARG_RAW,
22364418919fSjohnjiang .size = sizeof(uint8_t),
22374418919fSjohnjiang },
22384418919fSjohnjiang },
22394418919fSjohnjiang .ret = {
22404418919fSjohnjiang .type = RTE_BPF_ARG_RAW,
22414418919fSjohnjiang .size = sizeof(uint32_t),
22424418919fSjohnjiang },
22434418919fSjohnjiang },
22444418919fSjohnjiang },
22454418919fSjohnjiang };
22464418919fSjohnjiang
22474418919fSjohnjiang /* string compare test case */
22484418919fSjohnjiang static const struct ebpf_insn test_call5_prog[] = {
22494418919fSjohnjiang
22504418919fSjohnjiang [0] = {
22514418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
22524418919fSjohnjiang .dst_reg = EBPF_REG_1,
22534418919fSjohnjiang .imm = STRING_GEEK,
22544418919fSjohnjiang },
22554418919fSjohnjiang [1] = {
22564418919fSjohnjiang .code = (BPF_STX | BPF_MEM | BPF_W),
22574418919fSjohnjiang .dst_reg = EBPF_REG_10,
22584418919fSjohnjiang .src_reg = EBPF_REG_1,
22594418919fSjohnjiang .off = -8,
22604418919fSjohnjiang },
22614418919fSjohnjiang [2] = {
22624418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
22634418919fSjohnjiang .dst_reg = EBPF_REG_6,
22644418919fSjohnjiang .imm = 0,
22654418919fSjohnjiang },
22664418919fSjohnjiang [3] = {
22674418919fSjohnjiang .code = (BPF_STX | BPF_MEM | BPF_B),
22684418919fSjohnjiang .dst_reg = EBPF_REG_10,
22694418919fSjohnjiang .src_reg = EBPF_REG_6,
22704418919fSjohnjiang .off = -4,
22714418919fSjohnjiang },
22724418919fSjohnjiang [4] = {
22734418919fSjohnjiang .code = (BPF_STX | BPF_MEM | BPF_W),
22744418919fSjohnjiang .dst_reg = EBPF_REG_10,
22754418919fSjohnjiang .src_reg = EBPF_REG_6,
22764418919fSjohnjiang .off = -12,
22774418919fSjohnjiang },
22784418919fSjohnjiang [5] = {
22794418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
22804418919fSjohnjiang .dst_reg = EBPF_REG_1,
22814418919fSjohnjiang .imm = STRING_WEEK,
22824418919fSjohnjiang },
22834418919fSjohnjiang [6] = {
22844418919fSjohnjiang .code = (BPF_STX | BPF_MEM | BPF_W),
22854418919fSjohnjiang .dst_reg = EBPF_REG_10,
22864418919fSjohnjiang .src_reg = EBPF_REG_1,
22874418919fSjohnjiang .off = -16,
22884418919fSjohnjiang },
22894418919fSjohnjiang [7] = {
22904418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
22914418919fSjohnjiang .dst_reg = EBPF_REG_1,
22924418919fSjohnjiang .src_reg = EBPF_REG_10,
22934418919fSjohnjiang },
22944418919fSjohnjiang [8] = {
22954418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_K),
22964418919fSjohnjiang .dst_reg = EBPF_REG_1,
22974418919fSjohnjiang .imm = -8,
22984418919fSjohnjiang },
22994418919fSjohnjiang [9] = {
23004418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
23014418919fSjohnjiang .dst_reg = EBPF_REG_2,
23024418919fSjohnjiang .src_reg = EBPF_REG_1,
23034418919fSjohnjiang },
23044418919fSjohnjiang [10] = {
23054418919fSjohnjiang .code = (BPF_JMP | EBPF_CALL),
23064418919fSjohnjiang .imm = 0,
23074418919fSjohnjiang },
23084418919fSjohnjiang [11] = {
23094418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
23104418919fSjohnjiang .dst_reg = EBPF_REG_1,
23114418919fSjohnjiang .src_reg = EBPF_REG_0,
23124418919fSjohnjiang },
23134418919fSjohnjiang [12] = {
23144418919fSjohnjiang .code = (BPF_ALU | EBPF_MOV | BPF_K),
23154418919fSjohnjiang .dst_reg = EBPF_REG_0,
23164418919fSjohnjiang .imm = -1,
23174418919fSjohnjiang },
23184418919fSjohnjiang [13] = {
23194418919fSjohnjiang .code = (EBPF_ALU64 | BPF_LSH | BPF_K),
23204418919fSjohnjiang .dst_reg = EBPF_REG_1,
23214418919fSjohnjiang .imm = 0x20,
23224418919fSjohnjiang },
23234418919fSjohnjiang [14] = {
23244418919fSjohnjiang .code = (EBPF_ALU64 | BPF_RSH | BPF_K),
23254418919fSjohnjiang .dst_reg = EBPF_REG_1,
23264418919fSjohnjiang .imm = 0x20,
23274418919fSjohnjiang },
23284418919fSjohnjiang [15] = {
23294418919fSjohnjiang .code = (BPF_JMP | EBPF_JNE | BPF_K),
23304418919fSjohnjiang .dst_reg = EBPF_REG_1,
23314418919fSjohnjiang .off = 11,
23324418919fSjohnjiang .imm = 0,
23334418919fSjohnjiang },
23344418919fSjohnjiang [16] = {
23354418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
23364418919fSjohnjiang .dst_reg = EBPF_REG_1,
23374418919fSjohnjiang .src_reg = EBPF_REG_10,
23384418919fSjohnjiang },
23394418919fSjohnjiang [17] = {
23404418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_K),
23414418919fSjohnjiang .dst_reg = EBPF_REG_1,
23424418919fSjohnjiang .imm = -8,
23434418919fSjohnjiang },
23444418919fSjohnjiang [18] = {
23454418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
23464418919fSjohnjiang .dst_reg = EBPF_REG_2,
23474418919fSjohnjiang .src_reg = EBPF_REG_10,
23484418919fSjohnjiang },
23494418919fSjohnjiang [19] = {
23504418919fSjohnjiang .code = (EBPF_ALU64 | BPF_ADD | BPF_K),
23514418919fSjohnjiang .dst_reg = EBPF_REG_2,
23524418919fSjohnjiang .imm = -16,
23534418919fSjohnjiang },
23544418919fSjohnjiang [20] = {
23554418919fSjohnjiang .code = (BPF_JMP | EBPF_CALL),
23564418919fSjohnjiang .imm = 0,
23574418919fSjohnjiang },
23584418919fSjohnjiang [21] = {
23594418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
23604418919fSjohnjiang .dst_reg = EBPF_REG_1,
23614418919fSjohnjiang .src_reg = EBPF_REG_0,
23624418919fSjohnjiang },
23634418919fSjohnjiang [22] = {
23644418919fSjohnjiang .code = (EBPF_ALU64 | BPF_LSH | BPF_K),
23654418919fSjohnjiang .dst_reg = EBPF_REG_1,
23664418919fSjohnjiang .imm = 0x20,
23674418919fSjohnjiang },
23684418919fSjohnjiang [23] = {
23694418919fSjohnjiang .code = (EBPF_ALU64 | BPF_RSH | BPF_K),
23704418919fSjohnjiang .dst_reg = EBPF_REG_1,
23714418919fSjohnjiang .imm = 0x20,
23724418919fSjohnjiang },
23734418919fSjohnjiang [24] = {
23744418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
23754418919fSjohnjiang .dst_reg = EBPF_REG_0,
23764418919fSjohnjiang .src_reg = EBPF_REG_1,
23774418919fSjohnjiang },
23784418919fSjohnjiang [25] = {
23794418919fSjohnjiang .code = (BPF_JMP | BPF_JEQ | BPF_X),
23804418919fSjohnjiang .dst_reg = EBPF_REG_1,
23814418919fSjohnjiang .src_reg = EBPF_REG_6,
23824418919fSjohnjiang .off = 1,
23834418919fSjohnjiang },
23844418919fSjohnjiang [26] = {
23854418919fSjohnjiang .code = (EBPF_ALU64 | EBPF_MOV | BPF_K),
23864418919fSjohnjiang .dst_reg = EBPF_REG_0,
23874418919fSjohnjiang .imm = 0,
23884418919fSjohnjiang },
23894418919fSjohnjiang [27] = {
23904418919fSjohnjiang .code = (BPF_JMP | EBPF_EXIT),
23914418919fSjohnjiang },
23924418919fSjohnjiang };
23934418919fSjohnjiang
23944418919fSjohnjiang /* String comparision impelementation, return 0 if equal else difference */
23954418919fSjohnjiang static uint32_t
dummy_func5(const char * s1,const char * s2)23964418919fSjohnjiang dummy_func5(const char *s1, const char *s2)
23974418919fSjohnjiang {
23984418919fSjohnjiang while (*s1 && (*s1 == *s2)) {
23994418919fSjohnjiang s1++;
24004418919fSjohnjiang s2++;
24014418919fSjohnjiang }
24024418919fSjohnjiang return *(const unsigned char *)s1 - *(const unsigned char *)s2;
24034418919fSjohnjiang }
24044418919fSjohnjiang
24054418919fSjohnjiang static int
test_call5_check(uint64_t rc,const void * arg)24064418919fSjohnjiang test_call5_check(uint64_t rc, const void *arg)
24074418919fSjohnjiang {
24084418919fSjohnjiang char a[] = "geek";
24094418919fSjohnjiang char b[] = "week";
24104418919fSjohnjiang uint32_t v;
24114418919fSjohnjiang
24124418919fSjohnjiang RTE_SET_USED(arg);
24134418919fSjohnjiang
24144418919fSjohnjiang v = dummy_func5(a, a);
24154418919fSjohnjiang if (v != 0) {
24164418919fSjohnjiang v = -1;
24174418919fSjohnjiang goto fail;
24184418919fSjohnjiang }
24194418919fSjohnjiang
24204418919fSjohnjiang v = dummy_func5(a, b);
24214418919fSjohnjiang if (v == 0)
24224418919fSjohnjiang goto fail;
24234418919fSjohnjiang
24244418919fSjohnjiang v = 0;
24254418919fSjohnjiang
24264418919fSjohnjiang fail:
24274418919fSjohnjiang return cmp_res(__func__, v, rc, &v, &rc, sizeof(v));
24284418919fSjohnjiang }
24294418919fSjohnjiang
24304418919fSjohnjiang static const struct rte_bpf_xsym test_call5_xsym[] = {
24314418919fSjohnjiang [0] = {
24324418919fSjohnjiang .name = RTE_STR(dummy_func5),
24334418919fSjohnjiang .type = RTE_BPF_XTYPE_FUNC,
24344418919fSjohnjiang .func = {
24354418919fSjohnjiang .val = (void *)dummy_func5,
24364418919fSjohnjiang .nb_args = 2,
24374418919fSjohnjiang .args = {
24384418919fSjohnjiang [0] = {
24394418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
24404418919fSjohnjiang .size = sizeof(char),
24414418919fSjohnjiang },
24424418919fSjohnjiang [1] = {
24434418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
24444418919fSjohnjiang .size = sizeof(char),
24454418919fSjohnjiang },
24464418919fSjohnjiang },
24474418919fSjohnjiang .ret = {
24484418919fSjohnjiang .type = RTE_BPF_ARG_RAW,
24494418919fSjohnjiang .size = sizeof(uint32_t),
24504418919fSjohnjiang },
24514418919fSjohnjiang },
24524418919fSjohnjiang },
24534418919fSjohnjiang };
24544418919fSjohnjiang
2455*2d9fd380Sjfb8856606 /* load mbuf (BPF_ABS/BPF_IND) test-cases */
2456*2d9fd380Sjfb8856606 static const struct ebpf_insn test_ld_mbuf1_prog[] = {
2457*2d9fd380Sjfb8856606
2458*2d9fd380Sjfb8856606 /* BPF_ABS/BPF_IND implicitly expect mbuf ptr in R6 */
2459*2d9fd380Sjfb8856606 {
2460*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
2461*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_6,
2462*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_1,
2463*2d9fd380Sjfb8856606 },
2464*2d9fd380Sjfb8856606 /* load IPv4 version and IHL */
2465*2d9fd380Sjfb8856606 {
2466*2d9fd380Sjfb8856606 .code = (BPF_LD | BPF_ABS | BPF_B),
2467*2d9fd380Sjfb8856606 .imm = offsetof(struct rte_ipv4_hdr, version_ihl),
2468*2d9fd380Sjfb8856606 },
2469*2d9fd380Sjfb8856606 /* check IP version */
2470*2d9fd380Sjfb8856606 {
2471*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
2472*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_2,
2473*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2474*2d9fd380Sjfb8856606 },
2475*2d9fd380Sjfb8856606 {
2476*2d9fd380Sjfb8856606 .code = (BPF_ALU | BPF_AND | BPF_K),
2477*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_2,
2478*2d9fd380Sjfb8856606 .imm = 0xf0,
2479*2d9fd380Sjfb8856606 },
2480*2d9fd380Sjfb8856606 {
2481*2d9fd380Sjfb8856606 .code = (BPF_JMP | BPF_JEQ | BPF_K),
2482*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_2,
2483*2d9fd380Sjfb8856606 .imm = IPVERSION << 4,
2484*2d9fd380Sjfb8856606 .off = 2,
2485*2d9fd380Sjfb8856606 },
2486*2d9fd380Sjfb8856606 /* invalid IP version, return 0 */
2487*2d9fd380Sjfb8856606 {
2488*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | BPF_XOR | BPF_X),
2489*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_0,
2490*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2491*2d9fd380Sjfb8856606 },
2492*2d9fd380Sjfb8856606 {
2493*2d9fd380Sjfb8856606 .code = (BPF_JMP | EBPF_EXIT),
2494*2d9fd380Sjfb8856606 },
2495*2d9fd380Sjfb8856606 /* load 3-rd byte of IP data */
2496*2d9fd380Sjfb8856606 {
2497*2d9fd380Sjfb8856606 .code = (BPF_ALU | BPF_AND | BPF_K),
2498*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_0,
2499*2d9fd380Sjfb8856606 .imm = RTE_IPV4_HDR_IHL_MASK,
2500*2d9fd380Sjfb8856606 },
2501*2d9fd380Sjfb8856606 {
2502*2d9fd380Sjfb8856606 .code = (BPF_ALU | BPF_LSH | BPF_K),
2503*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_0,
2504*2d9fd380Sjfb8856606 .imm = 2,
2505*2d9fd380Sjfb8856606 },
2506*2d9fd380Sjfb8856606 {
2507*2d9fd380Sjfb8856606 .code = (BPF_LD | BPF_IND | BPF_B),
2508*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2509*2d9fd380Sjfb8856606 .imm = 3,
2510*2d9fd380Sjfb8856606 },
2511*2d9fd380Sjfb8856606 {
2512*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
2513*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_7,
2514*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2515*2d9fd380Sjfb8856606 },
2516*2d9fd380Sjfb8856606 /* load IPv4 src addr */
2517*2d9fd380Sjfb8856606 {
2518*2d9fd380Sjfb8856606 .code = (BPF_LD | BPF_ABS | BPF_W),
2519*2d9fd380Sjfb8856606 .imm = offsetof(struct rte_ipv4_hdr, src_addr),
2520*2d9fd380Sjfb8856606 },
2521*2d9fd380Sjfb8856606 {
2522*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
2523*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_7,
2524*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2525*2d9fd380Sjfb8856606 },
2526*2d9fd380Sjfb8856606 /* load IPv4 total length */
2527*2d9fd380Sjfb8856606 {
2528*2d9fd380Sjfb8856606 .code = (BPF_LD | BPF_ABS | BPF_H),
2529*2d9fd380Sjfb8856606 .imm = offsetof(struct rte_ipv4_hdr, total_length),
2530*2d9fd380Sjfb8856606 },
2531*2d9fd380Sjfb8856606 {
2532*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
2533*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_8,
2534*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2535*2d9fd380Sjfb8856606 },
2536*2d9fd380Sjfb8856606 /* load last 4 bytes of IP data */
2537*2d9fd380Sjfb8856606 {
2538*2d9fd380Sjfb8856606 .code = (BPF_LD | BPF_IND | BPF_W),
2539*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_8,
2540*2d9fd380Sjfb8856606 .imm = -(int32_t)sizeof(uint32_t),
2541*2d9fd380Sjfb8856606 },
2542*2d9fd380Sjfb8856606 {
2543*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
2544*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_7,
2545*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2546*2d9fd380Sjfb8856606 },
2547*2d9fd380Sjfb8856606 /* load 2 bytes from the middle of IP data */
2548*2d9fd380Sjfb8856606 {
2549*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | BPF_RSH | BPF_K),
2550*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_8,
2551*2d9fd380Sjfb8856606 .imm = 1,
2552*2d9fd380Sjfb8856606 },
2553*2d9fd380Sjfb8856606 {
2554*2d9fd380Sjfb8856606 .code = (BPF_LD | BPF_IND | BPF_H),
2555*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_8,
2556*2d9fd380Sjfb8856606 },
2557*2d9fd380Sjfb8856606 {
2558*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
2559*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_0,
2560*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_7,
2561*2d9fd380Sjfb8856606 },
2562*2d9fd380Sjfb8856606 {
2563*2d9fd380Sjfb8856606 .code = (BPF_JMP | EBPF_EXIT),
2564*2d9fd380Sjfb8856606 },
2565*2d9fd380Sjfb8856606 };
2566*2d9fd380Sjfb8856606
2567*2d9fd380Sjfb8856606 static void
dummy_mbuf_prep(struct rte_mbuf * mb,uint8_t buf[],uint32_t buf_len,uint32_t data_len)2568*2d9fd380Sjfb8856606 dummy_mbuf_prep(struct rte_mbuf *mb, uint8_t buf[], uint32_t buf_len,
2569*2d9fd380Sjfb8856606 uint32_t data_len)
2570*2d9fd380Sjfb8856606 {
2571*2d9fd380Sjfb8856606 uint32_t i;
2572*2d9fd380Sjfb8856606 uint8_t *db;
2573*2d9fd380Sjfb8856606
2574*2d9fd380Sjfb8856606 mb->buf_addr = buf;
2575*2d9fd380Sjfb8856606 mb->buf_iova = (uintptr_t)buf;
2576*2d9fd380Sjfb8856606 mb->buf_len = buf_len;
2577*2d9fd380Sjfb8856606 rte_mbuf_refcnt_set(mb, 1);
2578*2d9fd380Sjfb8856606
2579*2d9fd380Sjfb8856606 /* set pool pointer to dummy value, test doesn't use it */
2580*2d9fd380Sjfb8856606 mb->pool = (void *)buf;
2581*2d9fd380Sjfb8856606
2582*2d9fd380Sjfb8856606 rte_pktmbuf_reset(mb);
2583*2d9fd380Sjfb8856606 db = (uint8_t *)rte_pktmbuf_append(mb, data_len);
2584*2d9fd380Sjfb8856606
2585*2d9fd380Sjfb8856606 for (i = 0; i != data_len; i++)
2586*2d9fd380Sjfb8856606 db[i] = i;
2587*2d9fd380Sjfb8856606 }
2588*2d9fd380Sjfb8856606
2589*2d9fd380Sjfb8856606 static void
test_ld_mbuf1_prepare(void * arg)2590*2d9fd380Sjfb8856606 test_ld_mbuf1_prepare(void *arg)
2591*2d9fd380Sjfb8856606 {
2592*2d9fd380Sjfb8856606 struct dummy_mbuf *dm;
2593*2d9fd380Sjfb8856606 struct rte_ipv4_hdr *ph;
2594*2d9fd380Sjfb8856606
2595*2d9fd380Sjfb8856606 const uint32_t plen = 400;
2596*2d9fd380Sjfb8856606 const struct rte_ipv4_hdr iph = {
2597*2d9fd380Sjfb8856606 .version_ihl = RTE_IPV4_VHL_DEF,
2598*2d9fd380Sjfb8856606 .total_length = rte_cpu_to_be_16(plen),
2599*2d9fd380Sjfb8856606 .time_to_live = IPDEFTTL,
2600*2d9fd380Sjfb8856606 .next_proto_id = IPPROTO_RAW,
2601*2d9fd380Sjfb8856606 .src_addr = rte_cpu_to_be_32(RTE_IPV4_LOOPBACK),
2602*2d9fd380Sjfb8856606 .dst_addr = rte_cpu_to_be_32(RTE_IPV4_BROADCAST),
2603*2d9fd380Sjfb8856606 };
2604*2d9fd380Sjfb8856606
2605*2d9fd380Sjfb8856606 dm = arg;
2606*2d9fd380Sjfb8856606 memset(dm, 0, sizeof(*dm));
2607*2d9fd380Sjfb8856606
2608*2d9fd380Sjfb8856606 dummy_mbuf_prep(&dm->mb[0], dm->buf[0], sizeof(dm->buf[0]),
2609*2d9fd380Sjfb8856606 plen / 2 + 1);
2610*2d9fd380Sjfb8856606 dummy_mbuf_prep(&dm->mb[1], dm->buf[1], sizeof(dm->buf[0]),
2611*2d9fd380Sjfb8856606 plen / 2 - 1);
2612*2d9fd380Sjfb8856606
2613*2d9fd380Sjfb8856606 rte_pktmbuf_chain(&dm->mb[0], &dm->mb[1]);
2614*2d9fd380Sjfb8856606
2615*2d9fd380Sjfb8856606 ph = rte_pktmbuf_mtod(dm->mb, typeof(ph));
2616*2d9fd380Sjfb8856606 memcpy(ph, &iph, sizeof(iph));
2617*2d9fd380Sjfb8856606 }
2618*2d9fd380Sjfb8856606
2619*2d9fd380Sjfb8856606 static uint64_t
test_ld_mbuf1(const struct rte_mbuf * pkt)2620*2d9fd380Sjfb8856606 test_ld_mbuf1(const struct rte_mbuf *pkt)
2621*2d9fd380Sjfb8856606 {
2622*2d9fd380Sjfb8856606 uint64_t n, v;
2623*2d9fd380Sjfb8856606 const uint8_t *p8;
2624*2d9fd380Sjfb8856606 const uint16_t *p16;
2625*2d9fd380Sjfb8856606 const uint32_t *p32;
2626*2d9fd380Sjfb8856606 struct dummy_offset dof;
2627*2d9fd380Sjfb8856606
2628*2d9fd380Sjfb8856606 /* load IPv4 version and IHL */
2629*2d9fd380Sjfb8856606 p8 = rte_pktmbuf_read(pkt,
2630*2d9fd380Sjfb8856606 offsetof(struct rte_ipv4_hdr, version_ihl), sizeof(*p8),
2631*2d9fd380Sjfb8856606 &dof);
2632*2d9fd380Sjfb8856606 if (p8 == NULL)
2633*2d9fd380Sjfb8856606 return 0;
2634*2d9fd380Sjfb8856606
2635*2d9fd380Sjfb8856606 /* check IP version */
2636*2d9fd380Sjfb8856606 if ((p8[0] & 0xf0) != IPVERSION << 4)
2637*2d9fd380Sjfb8856606 return 0;
2638*2d9fd380Sjfb8856606
2639*2d9fd380Sjfb8856606 n = (p8[0] & RTE_IPV4_HDR_IHL_MASK) * RTE_IPV4_IHL_MULTIPLIER;
2640*2d9fd380Sjfb8856606
2641*2d9fd380Sjfb8856606 /* load 3-rd byte of IP data */
2642*2d9fd380Sjfb8856606 p8 = rte_pktmbuf_read(pkt, n + 3, sizeof(*p8), &dof);
2643*2d9fd380Sjfb8856606 if (p8 == NULL)
2644*2d9fd380Sjfb8856606 return 0;
2645*2d9fd380Sjfb8856606
2646*2d9fd380Sjfb8856606 v = p8[0];
2647*2d9fd380Sjfb8856606
2648*2d9fd380Sjfb8856606 /* load IPv4 src addr */
2649*2d9fd380Sjfb8856606 p32 = rte_pktmbuf_read(pkt,
2650*2d9fd380Sjfb8856606 offsetof(struct rte_ipv4_hdr, src_addr), sizeof(*p32),
2651*2d9fd380Sjfb8856606 &dof);
2652*2d9fd380Sjfb8856606 if (p32 == NULL)
2653*2d9fd380Sjfb8856606 return 0;
2654*2d9fd380Sjfb8856606
2655*2d9fd380Sjfb8856606 v += rte_be_to_cpu_32(p32[0]);
2656*2d9fd380Sjfb8856606
2657*2d9fd380Sjfb8856606 /* load IPv4 total length */
2658*2d9fd380Sjfb8856606 p16 = rte_pktmbuf_read(pkt,
2659*2d9fd380Sjfb8856606 offsetof(struct rte_ipv4_hdr, total_length), sizeof(*p16),
2660*2d9fd380Sjfb8856606 &dof);
2661*2d9fd380Sjfb8856606 if (p16 == NULL)
2662*2d9fd380Sjfb8856606 return 0;
2663*2d9fd380Sjfb8856606
2664*2d9fd380Sjfb8856606 n = rte_be_to_cpu_16(p16[0]);
2665*2d9fd380Sjfb8856606
2666*2d9fd380Sjfb8856606 /* load last 4 bytes of IP data */
2667*2d9fd380Sjfb8856606 p32 = rte_pktmbuf_read(pkt, n - sizeof(*p32), sizeof(*p32), &dof);
2668*2d9fd380Sjfb8856606 if (p32 == NULL)
2669*2d9fd380Sjfb8856606 return 0;
2670*2d9fd380Sjfb8856606
2671*2d9fd380Sjfb8856606 v += rte_be_to_cpu_32(p32[0]);
2672*2d9fd380Sjfb8856606
2673*2d9fd380Sjfb8856606 /* load 2 bytes from the middle of IP data */
2674*2d9fd380Sjfb8856606 p16 = rte_pktmbuf_read(pkt, n / 2, sizeof(*p16), &dof);
2675*2d9fd380Sjfb8856606 if (p16 == NULL)
2676*2d9fd380Sjfb8856606 return 0;
2677*2d9fd380Sjfb8856606
2678*2d9fd380Sjfb8856606 v += rte_be_to_cpu_16(p16[0]);
2679*2d9fd380Sjfb8856606 return v;
2680*2d9fd380Sjfb8856606 }
2681*2d9fd380Sjfb8856606
2682*2d9fd380Sjfb8856606 static int
test_ld_mbuf1_check(uint64_t rc,const void * arg)2683*2d9fd380Sjfb8856606 test_ld_mbuf1_check(uint64_t rc, const void *arg)
2684*2d9fd380Sjfb8856606 {
2685*2d9fd380Sjfb8856606 const struct dummy_mbuf *dm;
2686*2d9fd380Sjfb8856606 uint64_t v;
2687*2d9fd380Sjfb8856606
2688*2d9fd380Sjfb8856606 dm = arg;
2689*2d9fd380Sjfb8856606 v = test_ld_mbuf1(dm->mb);
2690*2d9fd380Sjfb8856606 return cmp_res(__func__, v, rc, arg, arg, 0);
2691*2d9fd380Sjfb8856606 }
2692*2d9fd380Sjfb8856606
2693*2d9fd380Sjfb8856606 /*
2694*2d9fd380Sjfb8856606 * same as ld_mbuf1, but then trancate the mbuf by 1B,
2695*2d9fd380Sjfb8856606 * so load of last 4B fail.
2696*2d9fd380Sjfb8856606 */
2697*2d9fd380Sjfb8856606 static void
test_ld_mbuf2_prepare(void * arg)2698*2d9fd380Sjfb8856606 test_ld_mbuf2_prepare(void *arg)
2699*2d9fd380Sjfb8856606 {
2700*2d9fd380Sjfb8856606 struct dummy_mbuf *dm;
2701*2d9fd380Sjfb8856606
2702*2d9fd380Sjfb8856606 test_ld_mbuf1_prepare(arg);
2703*2d9fd380Sjfb8856606 dm = arg;
2704*2d9fd380Sjfb8856606 rte_pktmbuf_trim(dm->mb, 1);
2705*2d9fd380Sjfb8856606 }
2706*2d9fd380Sjfb8856606
2707*2d9fd380Sjfb8856606 static int
test_ld_mbuf2_check(uint64_t rc,const void * arg)2708*2d9fd380Sjfb8856606 test_ld_mbuf2_check(uint64_t rc, const void *arg)
2709*2d9fd380Sjfb8856606 {
2710*2d9fd380Sjfb8856606 return cmp_res(__func__, 0, rc, arg, arg, 0);
2711*2d9fd380Sjfb8856606 }
2712*2d9fd380Sjfb8856606
2713*2d9fd380Sjfb8856606 /* same as test_ld_mbuf1, but now store intermediate results on the stack */
2714*2d9fd380Sjfb8856606 static const struct ebpf_insn test_ld_mbuf3_prog[] = {
2715*2d9fd380Sjfb8856606
2716*2d9fd380Sjfb8856606 /* BPF_ABS/BPF_IND implicitly expect mbuf ptr in R6 */
2717*2d9fd380Sjfb8856606 {
2718*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
2719*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_6,
2720*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_1,
2721*2d9fd380Sjfb8856606 },
2722*2d9fd380Sjfb8856606 /* load IPv4 version and IHL */
2723*2d9fd380Sjfb8856606 {
2724*2d9fd380Sjfb8856606 .code = (BPF_LD | BPF_ABS | BPF_B),
2725*2d9fd380Sjfb8856606 .imm = offsetof(struct rte_ipv4_hdr, version_ihl),
2726*2d9fd380Sjfb8856606 },
2727*2d9fd380Sjfb8856606 /* check IP version */
2728*2d9fd380Sjfb8856606 {
2729*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
2730*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_2,
2731*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2732*2d9fd380Sjfb8856606 },
2733*2d9fd380Sjfb8856606 {
2734*2d9fd380Sjfb8856606 .code = (BPF_ALU | BPF_AND | BPF_K),
2735*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_2,
2736*2d9fd380Sjfb8856606 .imm = 0xf0,
2737*2d9fd380Sjfb8856606 },
2738*2d9fd380Sjfb8856606 {
2739*2d9fd380Sjfb8856606 .code = (BPF_JMP | BPF_JEQ | BPF_K),
2740*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_2,
2741*2d9fd380Sjfb8856606 .imm = IPVERSION << 4,
2742*2d9fd380Sjfb8856606 .off = 2,
2743*2d9fd380Sjfb8856606 },
2744*2d9fd380Sjfb8856606 /* invalid IP version, return 0 */
2745*2d9fd380Sjfb8856606 {
2746*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | BPF_XOR | BPF_X),
2747*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_0,
2748*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2749*2d9fd380Sjfb8856606 },
2750*2d9fd380Sjfb8856606 {
2751*2d9fd380Sjfb8856606 .code = (BPF_JMP | EBPF_EXIT),
2752*2d9fd380Sjfb8856606 },
2753*2d9fd380Sjfb8856606 /* load 3-rd byte of IP data */
2754*2d9fd380Sjfb8856606 {
2755*2d9fd380Sjfb8856606 .code = (BPF_ALU | BPF_AND | BPF_K),
2756*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_0,
2757*2d9fd380Sjfb8856606 .imm = RTE_IPV4_HDR_IHL_MASK,
2758*2d9fd380Sjfb8856606 },
2759*2d9fd380Sjfb8856606 {
2760*2d9fd380Sjfb8856606 .code = (BPF_ALU | BPF_LSH | BPF_K),
2761*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_0,
2762*2d9fd380Sjfb8856606 .imm = 2,
2763*2d9fd380Sjfb8856606 },
2764*2d9fd380Sjfb8856606 {
2765*2d9fd380Sjfb8856606 .code = (BPF_LD | BPF_IND | BPF_B),
2766*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2767*2d9fd380Sjfb8856606 .imm = 3,
2768*2d9fd380Sjfb8856606 },
2769*2d9fd380Sjfb8856606 {
2770*2d9fd380Sjfb8856606 .code = (BPF_STX | BPF_MEM | BPF_B),
2771*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_10,
2772*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2773*2d9fd380Sjfb8856606 .off = (int16_t)(offsetof(struct dummy_offset, u8) -
2774*2d9fd380Sjfb8856606 sizeof(struct dummy_offset)),
2775*2d9fd380Sjfb8856606 },
2776*2d9fd380Sjfb8856606 /* load IPv4 src addr */
2777*2d9fd380Sjfb8856606 {
2778*2d9fd380Sjfb8856606 .code = (BPF_LD | BPF_ABS | BPF_W),
2779*2d9fd380Sjfb8856606 .imm = offsetof(struct rte_ipv4_hdr, src_addr),
2780*2d9fd380Sjfb8856606 },
2781*2d9fd380Sjfb8856606 {
2782*2d9fd380Sjfb8856606 .code = (BPF_STX | BPF_MEM | BPF_W),
2783*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_10,
2784*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2785*2d9fd380Sjfb8856606 .off = (int16_t)(offsetof(struct dummy_offset, u32) -
2786*2d9fd380Sjfb8856606 sizeof(struct dummy_offset)),
2787*2d9fd380Sjfb8856606 },
2788*2d9fd380Sjfb8856606 /* load IPv4 total length */
2789*2d9fd380Sjfb8856606 {
2790*2d9fd380Sjfb8856606 .code = (BPF_LD | BPF_ABS | BPF_H),
2791*2d9fd380Sjfb8856606 .imm = offsetof(struct rte_ipv4_hdr, total_length),
2792*2d9fd380Sjfb8856606 },
2793*2d9fd380Sjfb8856606 {
2794*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | EBPF_MOV | BPF_X),
2795*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_8,
2796*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2797*2d9fd380Sjfb8856606 },
2798*2d9fd380Sjfb8856606 /* load last 4 bytes of IP data */
2799*2d9fd380Sjfb8856606 {
2800*2d9fd380Sjfb8856606 .code = (BPF_LD | BPF_IND | BPF_W),
2801*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_8,
2802*2d9fd380Sjfb8856606 .imm = -(int32_t)sizeof(uint32_t),
2803*2d9fd380Sjfb8856606 },
2804*2d9fd380Sjfb8856606 {
2805*2d9fd380Sjfb8856606 .code = (BPF_STX | BPF_MEM | EBPF_DW),
2806*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_10,
2807*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_0,
2808*2d9fd380Sjfb8856606 .off = (int16_t)(offsetof(struct dummy_offset, u64) -
2809*2d9fd380Sjfb8856606 sizeof(struct dummy_offset)),
2810*2d9fd380Sjfb8856606 },
2811*2d9fd380Sjfb8856606 /* load 2 bytes from the middle of IP data */
2812*2d9fd380Sjfb8856606 {
2813*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | BPF_RSH | BPF_K),
2814*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_8,
2815*2d9fd380Sjfb8856606 .imm = 1,
2816*2d9fd380Sjfb8856606 },
2817*2d9fd380Sjfb8856606 {
2818*2d9fd380Sjfb8856606 .code = (BPF_LD | BPF_IND | BPF_H),
2819*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_8,
2820*2d9fd380Sjfb8856606 },
2821*2d9fd380Sjfb8856606 {
2822*2d9fd380Sjfb8856606 .code = (BPF_LDX | BPF_MEM | EBPF_DW),
2823*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_1,
2824*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_10,
2825*2d9fd380Sjfb8856606 .off = (int16_t)(offsetof(struct dummy_offset, u64) -
2826*2d9fd380Sjfb8856606 sizeof(struct dummy_offset)),
2827*2d9fd380Sjfb8856606 },
2828*2d9fd380Sjfb8856606 {
2829*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
2830*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_0,
2831*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_1,
2832*2d9fd380Sjfb8856606 },
2833*2d9fd380Sjfb8856606 {
2834*2d9fd380Sjfb8856606 .code = (BPF_LDX | BPF_MEM | BPF_W),
2835*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_1,
2836*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_10,
2837*2d9fd380Sjfb8856606 .off = (int16_t)(offsetof(struct dummy_offset, u32) -
2838*2d9fd380Sjfb8856606 sizeof(struct dummy_offset)),
2839*2d9fd380Sjfb8856606 },
2840*2d9fd380Sjfb8856606 {
2841*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
2842*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_0,
2843*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_1,
2844*2d9fd380Sjfb8856606 },
2845*2d9fd380Sjfb8856606 {
2846*2d9fd380Sjfb8856606 .code = (BPF_LDX | BPF_MEM | BPF_B),
2847*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_1,
2848*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_10,
2849*2d9fd380Sjfb8856606 .off = (int16_t)(offsetof(struct dummy_offset, u8) -
2850*2d9fd380Sjfb8856606 sizeof(struct dummy_offset)),
2851*2d9fd380Sjfb8856606 },
2852*2d9fd380Sjfb8856606 {
2853*2d9fd380Sjfb8856606 .code = (EBPF_ALU64 | BPF_ADD | BPF_X),
2854*2d9fd380Sjfb8856606 .dst_reg = EBPF_REG_0,
2855*2d9fd380Sjfb8856606 .src_reg = EBPF_REG_1,
2856*2d9fd380Sjfb8856606 },
2857*2d9fd380Sjfb8856606 {
2858*2d9fd380Sjfb8856606 .code = (BPF_JMP | EBPF_EXIT),
2859*2d9fd380Sjfb8856606 },
2860*2d9fd380Sjfb8856606 };
2861*2d9fd380Sjfb8856606
28620c6bd470Sfengbojiang /* all bpf test cases */
28634418919fSjohnjiang static const struct bpf_test tests[] = {
28644418919fSjohnjiang {
28654418919fSjohnjiang .name = "test_store1",
28664418919fSjohnjiang .arg_sz = sizeof(struct dummy_offset),
28674418919fSjohnjiang .prm = {
28684418919fSjohnjiang .ins = test_store1_prog,
28694418919fSjohnjiang .nb_ins = RTE_DIM(test_store1_prog),
28704418919fSjohnjiang .prog_arg = {
28714418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
28724418919fSjohnjiang .size = sizeof(struct dummy_offset),
28734418919fSjohnjiang },
28744418919fSjohnjiang },
28754418919fSjohnjiang .prepare = test_store1_prepare,
28764418919fSjohnjiang .check_result = test_store1_check,
28774418919fSjohnjiang },
28784418919fSjohnjiang {
28794418919fSjohnjiang .name = "test_store2",
28804418919fSjohnjiang .arg_sz = sizeof(struct dummy_offset),
28814418919fSjohnjiang .prm = {
28824418919fSjohnjiang .ins = test_store2_prog,
28834418919fSjohnjiang .nb_ins = RTE_DIM(test_store2_prog),
28844418919fSjohnjiang .prog_arg = {
28854418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
28864418919fSjohnjiang .size = sizeof(struct dummy_offset),
28874418919fSjohnjiang },
28884418919fSjohnjiang },
28894418919fSjohnjiang .prepare = test_store1_prepare,
28904418919fSjohnjiang .check_result = test_store1_check,
28914418919fSjohnjiang },
28924418919fSjohnjiang {
28934418919fSjohnjiang .name = "test_load1",
28944418919fSjohnjiang .arg_sz = sizeof(struct dummy_offset),
28954418919fSjohnjiang .prm = {
28964418919fSjohnjiang .ins = test_load1_prog,
28974418919fSjohnjiang .nb_ins = RTE_DIM(test_load1_prog),
28984418919fSjohnjiang .prog_arg = {
28994418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
29004418919fSjohnjiang .size = sizeof(struct dummy_offset),
29014418919fSjohnjiang },
29024418919fSjohnjiang },
29034418919fSjohnjiang .prepare = test_load1_prepare,
29044418919fSjohnjiang .check_result = test_load1_check,
29054418919fSjohnjiang },
29064418919fSjohnjiang {
29074418919fSjohnjiang .name = "test_ldimm1",
29084418919fSjohnjiang .arg_sz = sizeof(struct dummy_offset),
29094418919fSjohnjiang .prm = {
29104418919fSjohnjiang .ins = test_ldimm1_prog,
29114418919fSjohnjiang .nb_ins = RTE_DIM(test_ldimm1_prog),
29124418919fSjohnjiang .prog_arg = {
29134418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
29144418919fSjohnjiang .size = sizeof(struct dummy_offset),
29154418919fSjohnjiang },
29164418919fSjohnjiang },
29174418919fSjohnjiang .prepare = test_store1_prepare,
29184418919fSjohnjiang .check_result = test_ldimm1_check,
29194418919fSjohnjiang },
29204418919fSjohnjiang {
29214418919fSjohnjiang .name = "test_mul1",
29224418919fSjohnjiang .arg_sz = sizeof(struct dummy_vect8),
29234418919fSjohnjiang .prm = {
29244418919fSjohnjiang .ins = test_mul1_prog,
29254418919fSjohnjiang .nb_ins = RTE_DIM(test_mul1_prog),
29264418919fSjohnjiang .prog_arg = {
29274418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
29284418919fSjohnjiang .size = sizeof(struct dummy_vect8),
29294418919fSjohnjiang },
29304418919fSjohnjiang },
29314418919fSjohnjiang .prepare = test_mul1_prepare,
29324418919fSjohnjiang .check_result = test_mul1_check,
29334418919fSjohnjiang },
29344418919fSjohnjiang {
29354418919fSjohnjiang .name = "test_shift1",
29364418919fSjohnjiang .arg_sz = sizeof(struct dummy_vect8),
29374418919fSjohnjiang .prm = {
29384418919fSjohnjiang .ins = test_shift1_prog,
29394418919fSjohnjiang .nb_ins = RTE_DIM(test_shift1_prog),
29404418919fSjohnjiang .prog_arg = {
29414418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
29424418919fSjohnjiang .size = sizeof(struct dummy_vect8),
29434418919fSjohnjiang },
29444418919fSjohnjiang },
29454418919fSjohnjiang .prepare = test_shift1_prepare,
29464418919fSjohnjiang .check_result = test_shift1_check,
29474418919fSjohnjiang },
29484418919fSjohnjiang {
29494418919fSjohnjiang .name = "test_jump1",
29504418919fSjohnjiang .arg_sz = sizeof(struct dummy_vect8),
29514418919fSjohnjiang .prm = {
29524418919fSjohnjiang .ins = test_jump1_prog,
29534418919fSjohnjiang .nb_ins = RTE_DIM(test_jump1_prog),
29544418919fSjohnjiang .prog_arg = {
29554418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
29564418919fSjohnjiang .size = sizeof(struct dummy_vect8),
29574418919fSjohnjiang },
29584418919fSjohnjiang },
29594418919fSjohnjiang .prepare = test_jump1_prepare,
29604418919fSjohnjiang .check_result = test_jump1_check,
29614418919fSjohnjiang },
29624418919fSjohnjiang {
29634418919fSjohnjiang .name = "test_jump2",
29644418919fSjohnjiang .arg_sz = sizeof(struct dummy_net),
29654418919fSjohnjiang .prm = {
29664418919fSjohnjiang .ins = test_jump2_prog,
29674418919fSjohnjiang .nb_ins = RTE_DIM(test_jump2_prog),
29684418919fSjohnjiang .prog_arg = {
29694418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
29704418919fSjohnjiang .size = sizeof(struct dummy_net),
29714418919fSjohnjiang },
29724418919fSjohnjiang },
29734418919fSjohnjiang .prepare = test_jump2_prepare,
29744418919fSjohnjiang .check_result = test_jump2_check,
29754418919fSjohnjiang },
29764418919fSjohnjiang {
29774418919fSjohnjiang .name = "test_alu1",
29784418919fSjohnjiang .arg_sz = sizeof(struct dummy_vect8),
29794418919fSjohnjiang .prm = {
29804418919fSjohnjiang .ins = test_alu1_prog,
29814418919fSjohnjiang .nb_ins = RTE_DIM(test_alu1_prog),
29824418919fSjohnjiang .prog_arg = {
29834418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
29844418919fSjohnjiang .size = sizeof(struct dummy_vect8),
29854418919fSjohnjiang },
29864418919fSjohnjiang },
29874418919fSjohnjiang .prepare = test_jump1_prepare,
29884418919fSjohnjiang .check_result = test_alu1_check,
29894418919fSjohnjiang },
29904418919fSjohnjiang {
29914418919fSjohnjiang .name = "test_bele1",
29924418919fSjohnjiang .arg_sz = sizeof(struct dummy_vect8),
29934418919fSjohnjiang .prm = {
29944418919fSjohnjiang .ins = test_bele1_prog,
29954418919fSjohnjiang .nb_ins = RTE_DIM(test_bele1_prog),
29964418919fSjohnjiang .prog_arg = {
29974418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
29984418919fSjohnjiang .size = sizeof(struct dummy_vect8),
29994418919fSjohnjiang },
30004418919fSjohnjiang },
30014418919fSjohnjiang .prepare = test_bele1_prepare,
30024418919fSjohnjiang .check_result = test_bele1_check,
30034418919fSjohnjiang },
30044418919fSjohnjiang {
30054418919fSjohnjiang .name = "test_xadd1",
30064418919fSjohnjiang .arg_sz = sizeof(struct dummy_offset),
30074418919fSjohnjiang .prm = {
30084418919fSjohnjiang .ins = test_xadd1_prog,
30094418919fSjohnjiang .nb_ins = RTE_DIM(test_xadd1_prog),
30104418919fSjohnjiang .prog_arg = {
30114418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
30124418919fSjohnjiang .size = sizeof(struct dummy_offset),
30134418919fSjohnjiang },
30144418919fSjohnjiang },
30154418919fSjohnjiang .prepare = test_store1_prepare,
30164418919fSjohnjiang .check_result = test_xadd1_check,
30174418919fSjohnjiang },
30184418919fSjohnjiang {
30194418919fSjohnjiang .name = "test_div1",
30204418919fSjohnjiang .arg_sz = sizeof(struct dummy_vect8),
30214418919fSjohnjiang .prm = {
30224418919fSjohnjiang .ins = test_div1_prog,
30234418919fSjohnjiang .nb_ins = RTE_DIM(test_div1_prog),
30244418919fSjohnjiang .prog_arg = {
30254418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
30264418919fSjohnjiang .size = sizeof(struct dummy_vect8),
30274418919fSjohnjiang },
30284418919fSjohnjiang },
30294418919fSjohnjiang .prepare = test_mul1_prepare,
30304418919fSjohnjiang .check_result = test_div1_check,
30314418919fSjohnjiang },
30324418919fSjohnjiang {
30334418919fSjohnjiang .name = "test_call1",
30344418919fSjohnjiang .arg_sz = sizeof(struct dummy_offset),
30354418919fSjohnjiang .prm = {
30364418919fSjohnjiang .ins = test_call1_prog,
30374418919fSjohnjiang .nb_ins = RTE_DIM(test_call1_prog),
30384418919fSjohnjiang .prog_arg = {
30394418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
30404418919fSjohnjiang .size = sizeof(struct dummy_offset),
30414418919fSjohnjiang },
30424418919fSjohnjiang .xsym = test_call1_xsym,
30434418919fSjohnjiang .nb_xsym = RTE_DIM(test_call1_xsym),
30444418919fSjohnjiang },
30454418919fSjohnjiang .prepare = test_load1_prepare,
30464418919fSjohnjiang .check_result = test_call1_check,
30474418919fSjohnjiang /* for now don't support function calls on 32 bit platform */
30484418919fSjohnjiang .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)),
30494418919fSjohnjiang },
30504418919fSjohnjiang {
30514418919fSjohnjiang .name = "test_call2",
30524418919fSjohnjiang .arg_sz = sizeof(struct dummy_offset),
30534418919fSjohnjiang .prm = {
30544418919fSjohnjiang .ins = test_call2_prog,
30554418919fSjohnjiang .nb_ins = RTE_DIM(test_call2_prog),
30564418919fSjohnjiang .prog_arg = {
30574418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
30584418919fSjohnjiang .size = sizeof(struct dummy_offset),
30594418919fSjohnjiang },
30604418919fSjohnjiang .xsym = test_call2_xsym,
30614418919fSjohnjiang .nb_xsym = RTE_DIM(test_call2_xsym),
30624418919fSjohnjiang },
30634418919fSjohnjiang .prepare = test_store1_prepare,
30644418919fSjohnjiang .check_result = test_call2_check,
30654418919fSjohnjiang /* for now don't support function calls on 32 bit platform */
30664418919fSjohnjiang .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)),
30674418919fSjohnjiang },
30684418919fSjohnjiang {
30694418919fSjohnjiang .name = "test_call3",
30704418919fSjohnjiang .arg_sz = sizeof(struct dummy_vect8),
30714418919fSjohnjiang .prm = {
30724418919fSjohnjiang .ins = test_call3_prog,
30734418919fSjohnjiang .nb_ins = RTE_DIM(test_call3_prog),
30744418919fSjohnjiang .prog_arg = {
30754418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
30764418919fSjohnjiang .size = sizeof(struct dummy_vect8),
30774418919fSjohnjiang },
30784418919fSjohnjiang .xsym = test_call3_xsym,
30794418919fSjohnjiang .nb_xsym = RTE_DIM(test_call3_xsym),
30804418919fSjohnjiang },
30814418919fSjohnjiang .prepare = test_call3_prepare,
30824418919fSjohnjiang .check_result = test_call3_check,
30834418919fSjohnjiang /* for now don't support function calls on 32 bit platform */
30844418919fSjohnjiang .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)),
30854418919fSjohnjiang },
30864418919fSjohnjiang {
30874418919fSjohnjiang .name = "test_call4",
30884418919fSjohnjiang .arg_sz = sizeof(struct dummy_offset),
30894418919fSjohnjiang .prm = {
30904418919fSjohnjiang .ins = test_call4_prog,
30914418919fSjohnjiang .nb_ins = RTE_DIM(test_call4_prog),
30924418919fSjohnjiang .prog_arg = {
30934418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
30944418919fSjohnjiang .size = 2 * sizeof(struct dummy_offset),
30954418919fSjohnjiang },
30964418919fSjohnjiang .xsym = test_call4_xsym,
30974418919fSjohnjiang .nb_xsym = RTE_DIM(test_call4_xsym),
30984418919fSjohnjiang },
30994418919fSjohnjiang .prepare = test_store1_prepare,
31004418919fSjohnjiang .check_result = test_call4_check,
31014418919fSjohnjiang /* for now don't support function calls on 32 bit platform */
31024418919fSjohnjiang .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)),
31034418919fSjohnjiang },
31044418919fSjohnjiang {
31054418919fSjohnjiang .name = "test_call5",
31064418919fSjohnjiang .arg_sz = sizeof(struct dummy_offset),
31074418919fSjohnjiang .prm = {
31084418919fSjohnjiang .ins = test_call5_prog,
31094418919fSjohnjiang .nb_ins = RTE_DIM(test_call5_prog),
31104418919fSjohnjiang .prog_arg = {
31114418919fSjohnjiang .type = RTE_BPF_ARG_PTR,
31124418919fSjohnjiang .size = sizeof(struct dummy_offset),
31134418919fSjohnjiang },
31144418919fSjohnjiang .xsym = test_call5_xsym,
31154418919fSjohnjiang .nb_xsym = RTE_DIM(test_call5_xsym),
31164418919fSjohnjiang },
31174418919fSjohnjiang .prepare = test_store1_prepare,
31184418919fSjohnjiang .check_result = test_call5_check,
31194418919fSjohnjiang /* for now don't support function calls on 32 bit platform */
31204418919fSjohnjiang .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)),
31214418919fSjohnjiang },
3122*2d9fd380Sjfb8856606 {
3123*2d9fd380Sjfb8856606 .name = "test_ld_mbuf1",
3124*2d9fd380Sjfb8856606 .arg_sz = sizeof(struct dummy_mbuf),
3125*2d9fd380Sjfb8856606 .prm = {
3126*2d9fd380Sjfb8856606 .ins = test_ld_mbuf1_prog,
3127*2d9fd380Sjfb8856606 .nb_ins = RTE_DIM(test_ld_mbuf1_prog),
3128*2d9fd380Sjfb8856606 .prog_arg = {
3129*2d9fd380Sjfb8856606 .type = RTE_BPF_ARG_PTR_MBUF,
3130*2d9fd380Sjfb8856606 .buf_size = sizeof(struct dummy_mbuf),
3131*2d9fd380Sjfb8856606 },
3132*2d9fd380Sjfb8856606 },
3133*2d9fd380Sjfb8856606 .prepare = test_ld_mbuf1_prepare,
3134*2d9fd380Sjfb8856606 .check_result = test_ld_mbuf1_check,
3135*2d9fd380Sjfb8856606 /* mbuf as input argument is not supported on 32 bit platform */
3136*2d9fd380Sjfb8856606 .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)),
3137*2d9fd380Sjfb8856606 },
3138*2d9fd380Sjfb8856606 {
3139*2d9fd380Sjfb8856606 .name = "test_ld_mbuf2",
3140*2d9fd380Sjfb8856606 .arg_sz = sizeof(struct dummy_mbuf),
3141*2d9fd380Sjfb8856606 .prm = {
3142*2d9fd380Sjfb8856606 .ins = test_ld_mbuf1_prog,
3143*2d9fd380Sjfb8856606 .nb_ins = RTE_DIM(test_ld_mbuf1_prog),
3144*2d9fd380Sjfb8856606 .prog_arg = {
3145*2d9fd380Sjfb8856606 .type = RTE_BPF_ARG_PTR_MBUF,
3146*2d9fd380Sjfb8856606 .buf_size = sizeof(struct dummy_mbuf),
3147*2d9fd380Sjfb8856606 },
3148*2d9fd380Sjfb8856606 },
3149*2d9fd380Sjfb8856606 .prepare = test_ld_mbuf2_prepare,
3150*2d9fd380Sjfb8856606 .check_result = test_ld_mbuf2_check,
3151*2d9fd380Sjfb8856606 /* mbuf as input argument is not supported on 32 bit platform */
3152*2d9fd380Sjfb8856606 .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)),
3153*2d9fd380Sjfb8856606 },
3154*2d9fd380Sjfb8856606 {
3155*2d9fd380Sjfb8856606 .name = "test_ld_mbuf3",
3156*2d9fd380Sjfb8856606 .arg_sz = sizeof(struct dummy_mbuf),
3157*2d9fd380Sjfb8856606 .prm = {
3158*2d9fd380Sjfb8856606 .ins = test_ld_mbuf3_prog,
3159*2d9fd380Sjfb8856606 .nb_ins = RTE_DIM(test_ld_mbuf3_prog),
3160*2d9fd380Sjfb8856606 .prog_arg = {
3161*2d9fd380Sjfb8856606 .type = RTE_BPF_ARG_PTR_MBUF,
3162*2d9fd380Sjfb8856606 .buf_size = sizeof(struct dummy_mbuf),
3163*2d9fd380Sjfb8856606 },
3164*2d9fd380Sjfb8856606 },
3165*2d9fd380Sjfb8856606 .prepare = test_ld_mbuf1_prepare,
3166*2d9fd380Sjfb8856606 .check_result = test_ld_mbuf1_check,
3167*2d9fd380Sjfb8856606 /* mbuf as input argument is not supported on 32 bit platform */
3168*2d9fd380Sjfb8856606 .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)),
3169*2d9fd380Sjfb8856606 },
31704418919fSjohnjiang };
31714418919fSjohnjiang
31724418919fSjohnjiang static int
run_test(const struct bpf_test * tst)31734418919fSjohnjiang run_test(const struct bpf_test *tst)
31744418919fSjohnjiang {
31754418919fSjohnjiang int32_t ret, rv;
31764418919fSjohnjiang int64_t rc;
31774418919fSjohnjiang struct rte_bpf *bpf;
31784418919fSjohnjiang struct rte_bpf_jit jit;
31794418919fSjohnjiang uint8_t tbuf[tst->arg_sz];
31804418919fSjohnjiang
31814418919fSjohnjiang printf("%s(%s) start\n", __func__, tst->name);
31824418919fSjohnjiang
31834418919fSjohnjiang bpf = rte_bpf_load(&tst->prm);
31844418919fSjohnjiang if (bpf == NULL) {
31854418919fSjohnjiang printf("%s@%d: failed to load bpf code, error=%d(%s);\n",
31864418919fSjohnjiang __func__, __LINE__, rte_errno, strerror(rte_errno));
31874418919fSjohnjiang return -1;
31884418919fSjohnjiang }
31894418919fSjohnjiang
31904418919fSjohnjiang tst->prepare(tbuf);
31914418919fSjohnjiang rc = rte_bpf_exec(bpf, tbuf);
31924418919fSjohnjiang ret = tst->check_result(rc, tbuf);
31934418919fSjohnjiang if (ret != 0) {
31944418919fSjohnjiang printf("%s@%d: check_result(%s) failed, error: %d(%s);\n",
31954418919fSjohnjiang __func__, __LINE__, tst->name, ret, strerror(ret));
31964418919fSjohnjiang }
31974418919fSjohnjiang
31980c6bd470Sfengbojiang /* repeat the same test with jit, when possible */
31994418919fSjohnjiang rte_bpf_get_jit(bpf, &jit);
32000c6bd470Sfengbojiang if (jit.func != NULL) {
32014418919fSjohnjiang
32024418919fSjohnjiang tst->prepare(tbuf);
32034418919fSjohnjiang rc = jit.func(tbuf);
32044418919fSjohnjiang rv = tst->check_result(rc, tbuf);
32054418919fSjohnjiang ret |= rv;
32064418919fSjohnjiang if (rv != 0) {
32070c6bd470Sfengbojiang printf("%s@%d: check_result(%s) failed, "
32080c6bd470Sfengbojiang "error: %d(%s);\n",
32090c6bd470Sfengbojiang __func__, __LINE__, tst->name,
32100c6bd470Sfengbojiang rv, strerror(ret));
32110c6bd470Sfengbojiang }
32124418919fSjohnjiang }
32134418919fSjohnjiang
32144418919fSjohnjiang rte_bpf_destroy(bpf);
32154418919fSjohnjiang return ret;
32164418919fSjohnjiang
32174418919fSjohnjiang }
32184418919fSjohnjiang
32194418919fSjohnjiang static int
test_bpf(void)32204418919fSjohnjiang test_bpf(void)
32214418919fSjohnjiang {
32224418919fSjohnjiang int32_t rc, rv;
32234418919fSjohnjiang uint32_t i;
32244418919fSjohnjiang
32254418919fSjohnjiang rc = 0;
32264418919fSjohnjiang for (i = 0; i != RTE_DIM(tests); i++) {
32274418919fSjohnjiang rv = run_test(tests + i);
32284418919fSjohnjiang if (tests[i].allow_fail == 0)
32294418919fSjohnjiang rc |= rv;
32304418919fSjohnjiang }
32314418919fSjohnjiang
32324418919fSjohnjiang return rc;
32334418919fSjohnjiang }
32344418919fSjohnjiang
32354418919fSjohnjiang REGISTER_TEST_COMMAND(bpf_autotest, test_bpf);
3236