xref: /f-stack/dpdk/app/test/test_bpf.c (revision 2d9fd380)
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