xref: /freebsd/contrib/netbsd-tests/lib/libbpfjit/t_extmem.c (revision 9268022b74279434ed6300244e3f977e56a8ceb5)
1*57718be8SEnji Cooper /*	$NetBSD: t_extmem.c,v 1.3 2014/07/14 19:11:15 alnsn Exp $ */
2*57718be8SEnji Cooper 
3*57718be8SEnji Cooper /*-
4*57718be8SEnji Cooper  * Copyright (c) 2014 Alexander Nasonov.
5*57718be8SEnji Cooper  * All rights reserved.
6*57718be8SEnji Cooper  *
7*57718be8SEnji Cooper  * Redistribution and use in source and binary forms, with or without
8*57718be8SEnji Cooper  * modification, are permitted provided that the following conditions
9*57718be8SEnji Cooper  * are met:
10*57718be8SEnji Cooper  *
11*57718be8SEnji Cooper  * 1. Redistributions of source code must retain the above copyright
12*57718be8SEnji Cooper  *    notice, this list of conditions and the following disclaimer.
13*57718be8SEnji Cooper  * 2. Redistributions in binary form must reproduce the above copyright
14*57718be8SEnji Cooper  *    notice, this list of conditions and the following disclaimer in
15*57718be8SEnji Cooper  *    the documentation and/or other materials provided with the
16*57718be8SEnji Cooper  *    distribution.
17*57718be8SEnji Cooper  *
18*57718be8SEnji Cooper  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19*57718be8SEnji Cooper  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20*57718be8SEnji Cooper  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21*57718be8SEnji Cooper  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
22*57718be8SEnji Cooper  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23*57718be8SEnji Cooper  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
24*57718be8SEnji Cooper  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25*57718be8SEnji Cooper  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26*57718be8SEnji Cooper  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27*57718be8SEnji Cooper  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28*57718be8SEnji Cooper  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*57718be8SEnji Cooper  * SUCH DAMAGE.
30*57718be8SEnji Cooper  */
31*57718be8SEnji Cooper 
32*57718be8SEnji Cooper #include <sys/cdefs.h>
33*57718be8SEnji Cooper __RCSID("$NetBSD: t_extmem.c,v 1.3 2014/07/14 19:11:15 alnsn Exp $");
34*57718be8SEnji Cooper 
35*57718be8SEnji Cooper #include <atf-c.h>
36*57718be8SEnji Cooper #include <stdint.h>
37*57718be8SEnji Cooper #include <string.h>
38*57718be8SEnji Cooper 
39*57718be8SEnji Cooper #define __BPF_PRIVATE
40*57718be8SEnji Cooper #include <net/bpf.h>
41*57718be8SEnji Cooper #include <net/bpfjit.h>
42*57718be8SEnji Cooper 
43*57718be8SEnji Cooper static uint32_t retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
44*57718be8SEnji Cooper 
45*57718be8SEnji Cooper static const bpf_copfunc_t copfuncs[] = {
46*57718be8SEnji Cooper 	&retM
47*57718be8SEnji Cooper };
48*57718be8SEnji Cooper 
49*57718be8SEnji Cooper static const bpf_ctx_t ctx = {
50*57718be8SEnji Cooper 	.copfuncs = copfuncs,
51*57718be8SEnji Cooper 	.nfuncs = sizeof(copfuncs) / sizeof(copfuncs[0]),
52*57718be8SEnji Cooper 	.extwords = 4,
53*57718be8SEnji Cooper 	.preinited = BPF_MEMWORD_INIT(0) | BPF_MEMWORD_INIT(3),
54*57718be8SEnji Cooper };
55*57718be8SEnji Cooper 
56*57718be8SEnji Cooper static uint32_t
retM(const bpf_ctx_t * bc,bpf_args_t * args,uint32_t A)57*57718be8SEnji Cooper retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
58*57718be8SEnji Cooper {
59*57718be8SEnji Cooper 
60*57718be8SEnji Cooper 	return args->mem[(uintptr_t)args->arg];
61*57718be8SEnji Cooper }
62*57718be8SEnji Cooper 
63*57718be8SEnji Cooper 
64*57718be8SEnji Cooper ATF_TC(libbpfjit_extmem_load_default);
ATF_TC_HEAD(libbpfjit_extmem_load_default,tc)65*57718be8SEnji Cooper ATF_TC_HEAD(libbpfjit_extmem_load_default, tc)
66*57718be8SEnji Cooper {
67*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test that external memory "
68*57718be8SEnji Cooper 	    "is zero initialized by default");
69*57718be8SEnji Cooper }
70*57718be8SEnji Cooper 
ATF_TC_BODY(libbpfjit_extmem_load_default,tc)71*57718be8SEnji Cooper ATF_TC_BODY(libbpfjit_extmem_load_default, tc)
72*57718be8SEnji Cooper {
73*57718be8SEnji Cooper 	static struct bpf_insn insns[] = {
74*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_MEM, 1),
75*57718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
76*57718be8SEnji Cooper 	};
77*57718be8SEnji Cooper 
78*57718be8SEnji Cooper 	bpfjit_func_t code;
79*57718be8SEnji Cooper 	uint8_t pkt[1] = { 0 };
80*57718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
81*57718be8SEnji Cooper 
82*57718be8SEnji Cooper 	/* Pre-inited words. */
83*57718be8SEnji Cooper 	mem[0] = 0;
84*57718be8SEnji Cooper 	mem[3] = 3;
85*57718be8SEnji Cooper 
86*57718be8SEnji Cooper 	bpf_args_t args = {
87*57718be8SEnji Cooper 		.pkt = pkt,
88*57718be8SEnji Cooper 		.buflen = sizeof(pkt),
89*57718be8SEnji Cooper 		.wirelen = sizeof(pkt),
90*57718be8SEnji Cooper 		.mem = mem,
91*57718be8SEnji Cooper 	};
92*57718be8SEnji Cooper 
93*57718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
94*57718be8SEnji Cooper 
95*57718be8SEnji Cooper 	code = bpfjit_generate_code(&ctx, insns, insn_count);
96*57718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
97*57718be8SEnji Cooper 
98*57718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 0);
99*57718be8SEnji Cooper 
100*57718be8SEnji Cooper 	bpfjit_free_code(code);
101*57718be8SEnji Cooper }
102*57718be8SEnji Cooper 
103*57718be8SEnji Cooper ATF_TC(libbpfjit_extmem_load_preinited);
ATF_TC_HEAD(libbpfjit_extmem_load_preinited,tc)104*57718be8SEnji Cooper ATF_TC_HEAD(libbpfjit_extmem_load_preinited, tc)
105*57718be8SEnji Cooper {
106*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test a load of external "
107*57718be8SEnji Cooper 	    "pre-initialized memory");
108*57718be8SEnji Cooper }
109*57718be8SEnji Cooper 
ATF_TC_BODY(libbpfjit_extmem_load_preinited,tc)110*57718be8SEnji Cooper ATF_TC_BODY(libbpfjit_extmem_load_preinited, tc)
111*57718be8SEnji Cooper {
112*57718be8SEnji Cooper 	static struct bpf_insn insns[] = {
113*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_MEM, 3),
114*57718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
115*57718be8SEnji Cooper 	};
116*57718be8SEnji Cooper 
117*57718be8SEnji Cooper 	bpfjit_func_t code;
118*57718be8SEnji Cooper 	uint8_t pkt[1] = { 0 };
119*57718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
120*57718be8SEnji Cooper 
121*57718be8SEnji Cooper 	/* Pre-inited words. */
122*57718be8SEnji Cooper 	mem[0] = 0;
123*57718be8SEnji Cooper 	mem[3] = 3;
124*57718be8SEnji Cooper 
125*57718be8SEnji Cooper 	bpf_args_t args = {
126*57718be8SEnji Cooper 		.pkt = pkt,
127*57718be8SEnji Cooper 		.buflen = sizeof(pkt),
128*57718be8SEnji Cooper 		.wirelen = sizeof(pkt),
129*57718be8SEnji Cooper 		.mem = mem,
130*57718be8SEnji Cooper 	};
131*57718be8SEnji Cooper 
132*57718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
133*57718be8SEnji Cooper 
134*57718be8SEnji Cooper 	code = bpfjit_generate_code(&ctx, insns, insn_count);
135*57718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
136*57718be8SEnji Cooper 
137*57718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 3);
138*57718be8SEnji Cooper 
139*57718be8SEnji Cooper 	bpfjit_free_code(code);
140*57718be8SEnji Cooper }
141*57718be8SEnji Cooper 
142*57718be8SEnji Cooper ATF_TC(libbpfjit_extmem_invalid_load);
ATF_TC_HEAD(libbpfjit_extmem_invalid_load,tc)143*57718be8SEnji Cooper ATF_TC_HEAD(libbpfjit_extmem_invalid_load, tc)
144*57718be8SEnji Cooper {
145*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test that out-of-range load "
146*57718be8SEnji Cooper 	    "fails validation");
147*57718be8SEnji Cooper }
148*57718be8SEnji Cooper 
ATF_TC_BODY(libbpfjit_extmem_invalid_load,tc)149*57718be8SEnji Cooper ATF_TC_BODY(libbpfjit_extmem_invalid_load, tc)
150*57718be8SEnji Cooper {
151*57718be8SEnji Cooper 	static struct bpf_insn insns[] = {
152*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_MEM, 4),
153*57718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
154*57718be8SEnji Cooper 	};
155*57718be8SEnji Cooper 
156*57718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
157*57718be8SEnji Cooper 
158*57718be8SEnji Cooper 	ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL);
159*57718be8SEnji Cooper }
160*57718be8SEnji Cooper 
161*57718be8SEnji Cooper ATF_TC(libbpfjit_extmem_store);
ATF_TC_HEAD(libbpfjit_extmem_store,tc)162*57718be8SEnji Cooper ATF_TC_HEAD(libbpfjit_extmem_store, tc)
163*57718be8SEnji Cooper {
164*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test stores to external memory");
165*57718be8SEnji Cooper }
166*57718be8SEnji Cooper 
ATF_TC_BODY(libbpfjit_extmem_store,tc)167*57718be8SEnji Cooper ATF_TC_BODY(libbpfjit_extmem_store, tc)
168*57718be8SEnji Cooper {
169*57718be8SEnji Cooper 	static struct bpf_insn insns[] = {
170*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 1),        /* A <- 1     */
171*57718be8SEnji Cooper 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2     */
172*57718be8SEnji Cooper 		BPF_STMT(BPF_ST, 1),                /* M[1] <- A  */
173*57718be8SEnji Cooper 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */
174*57718be8SEnji Cooper 		BPF_STMT(BPF_STX, 2),               /* M[2] <- X  */
175*57718be8SEnji Cooper 		BPF_STMT(BPF_ST, 3),                /* M[3] <- A  */
176*57718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)          /* ret A      */
177*57718be8SEnji Cooper 	};
178*57718be8SEnji Cooper 
179*57718be8SEnji Cooper 	bpfjit_func_t code;
180*57718be8SEnji Cooper 	uint8_t pkt[1] = { 0 };
181*57718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
182*57718be8SEnji Cooper 
183*57718be8SEnji Cooper 	/* Pre-inited words. */
184*57718be8SEnji Cooper 	mem[0] = 0;
185*57718be8SEnji Cooper 	mem[3] = 7;
186*57718be8SEnji Cooper 
187*57718be8SEnji Cooper 	mem[1] = mem[2] = 0xdeadbeef;
188*57718be8SEnji Cooper 
189*57718be8SEnji Cooper 	bpf_args_t args = {
190*57718be8SEnji Cooper 		.pkt = pkt,
191*57718be8SEnji Cooper 		.buflen = sizeof(pkt),
192*57718be8SEnji Cooper 		.wirelen = sizeof(pkt),
193*57718be8SEnji Cooper 		.mem = mem,
194*57718be8SEnji Cooper 	};
195*57718be8SEnji Cooper 
196*57718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
197*57718be8SEnji Cooper 
198*57718be8SEnji Cooper 	code = bpfjit_generate_code(&ctx, insns, insn_count);
199*57718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
200*57718be8SEnji Cooper 
201*57718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 3);
202*57718be8SEnji Cooper 
203*57718be8SEnji Cooper 	bpfjit_free_code(code);
204*57718be8SEnji Cooper 
205*57718be8SEnji Cooper 	ATF_CHECK(mem[0] == 0);
206*57718be8SEnji Cooper 	ATF_CHECK(mem[1] == 1);
207*57718be8SEnji Cooper 	ATF_CHECK(mem[2] == 2);
208*57718be8SEnji Cooper 	ATF_CHECK(mem[3] == 3);
209*57718be8SEnji Cooper }
210*57718be8SEnji Cooper 
211*57718be8SEnji Cooper ATF_TC(libbpfjit_extmem_side_effect);
ATF_TC_HEAD(libbpfjit_extmem_side_effect,tc)212*57718be8SEnji Cooper ATF_TC_HEAD(libbpfjit_extmem_side_effect, tc)
213*57718be8SEnji Cooper {
214*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test that ABC optimization doesn\'t "
215*57718be8SEnji Cooper 	    "skip stores to external memory");
216*57718be8SEnji Cooper }
217*57718be8SEnji Cooper 
ATF_TC_BODY(libbpfjit_extmem_side_effect,tc)218*57718be8SEnji Cooper ATF_TC_BODY(libbpfjit_extmem_side_effect, tc)
219*57718be8SEnji Cooper {
220*57718be8SEnji Cooper 	static struct bpf_insn insns[] = {
221*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0),  /* A <- P[0]  */
222*57718be8SEnji Cooper 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2     */
223*57718be8SEnji Cooper 		BPF_STMT(BPF_ST, 1),                /* M[1] <- A  */
224*57718be8SEnji Cooper 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */
225*57718be8SEnji Cooper 		BPF_STMT(BPF_STX, 2),               /* M[2] <- X  */
226*57718be8SEnji Cooper 		BPF_STMT(BPF_ST, 3),                /* M[3] <- A  */
227*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99), /* A <- P[99] */
228*57718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)          /* ret A      */
229*57718be8SEnji Cooper 	};
230*57718be8SEnji Cooper 
231*57718be8SEnji Cooper 	bpfjit_func_t code;
232*57718be8SEnji Cooper 	uint8_t pkt[1] = { 1 };
233*57718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
234*57718be8SEnji Cooper 
235*57718be8SEnji Cooper 	/* Pre-inited words. */
236*57718be8SEnji Cooper 	mem[0] = 0;
237*57718be8SEnji Cooper 	mem[3] = 7;
238*57718be8SEnji Cooper 
239*57718be8SEnji Cooper 	mem[1] = mem[2] = 0xdeadbeef;
240*57718be8SEnji Cooper 
241*57718be8SEnji Cooper 	bpf_args_t args = {
242*57718be8SEnji Cooper 		.pkt = pkt,
243*57718be8SEnji Cooper 		.buflen = sizeof(pkt),
244*57718be8SEnji Cooper 		.wirelen = sizeof(pkt),
245*57718be8SEnji Cooper 		.mem = mem,
246*57718be8SEnji Cooper 	};
247*57718be8SEnji Cooper 
248*57718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
249*57718be8SEnji Cooper 
250*57718be8SEnji Cooper 	code = bpfjit_generate_code(&ctx, insns, insn_count);
251*57718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
252*57718be8SEnji Cooper 
253*57718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 0);
254*57718be8SEnji Cooper 
255*57718be8SEnji Cooper 	bpfjit_free_code(code);
256*57718be8SEnji Cooper 
257*57718be8SEnji Cooper 	ATF_CHECK(mem[0] == 0);
258*57718be8SEnji Cooper 	ATF_CHECK(mem[1] == 1);
259*57718be8SEnji Cooper 	ATF_CHECK(mem[2] == 2);
260*57718be8SEnji Cooper 	ATF_CHECK(mem[3] == 3);
261*57718be8SEnji Cooper }
262*57718be8SEnji Cooper 
263*57718be8SEnji Cooper ATF_TC(libbpfjit_extmem_invalid_store);
ATF_TC_HEAD(libbpfjit_extmem_invalid_store,tc)264*57718be8SEnji Cooper ATF_TC_HEAD(libbpfjit_extmem_invalid_store, tc)
265*57718be8SEnji Cooper {
266*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test that out-of-range store "
267*57718be8SEnji Cooper 	    "fails validation");
268*57718be8SEnji Cooper }
269*57718be8SEnji Cooper 
ATF_TC_BODY(libbpfjit_extmem_invalid_store,tc)270*57718be8SEnji Cooper ATF_TC_BODY(libbpfjit_extmem_invalid_store, tc)
271*57718be8SEnji Cooper {
272*57718be8SEnji Cooper 	static struct bpf_insn insns[] = {
273*57718be8SEnji Cooper 		BPF_STMT(BPF_ST, 4),
274*57718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
275*57718be8SEnji Cooper 	};
276*57718be8SEnji Cooper 
277*57718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
278*57718be8SEnji Cooper 
279*57718be8SEnji Cooper 	ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL);
280*57718be8SEnji Cooper }
281*57718be8SEnji Cooper 
282*57718be8SEnji Cooper ATF_TC(libbpfjit_cop_ret_mem);
ATF_TC_HEAD(libbpfjit_cop_ret_mem,tc)283*57718be8SEnji Cooper ATF_TC_HEAD(libbpfjit_cop_ret_mem, tc)
284*57718be8SEnji Cooper {
285*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
286*57718be8SEnji Cooper 	    "that returns a content of external memory word");
287*57718be8SEnji Cooper }
288*57718be8SEnji Cooper 
ATF_TC_BODY(libbpfjit_cop_ret_mem,tc)289*57718be8SEnji Cooper ATF_TC_BODY(libbpfjit_cop_ret_mem, tc)
290*57718be8SEnji Cooper {
291*57718be8SEnji Cooper 	static struct bpf_insn insns[] = {
292*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 13),
293*57718be8SEnji Cooper 		BPF_STMT(BPF_ST, 2),
294*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 137),
295*57718be8SEnji Cooper 		BPF_STMT(BPF_ST, 1),
296*57718be8SEnji Cooper 		BPF_STMT(BPF_MISC+BPF_COP, 0), // retM
297*57718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
298*57718be8SEnji Cooper 	};
299*57718be8SEnji Cooper 
300*57718be8SEnji Cooper 	bpfjit_func_t code;
301*57718be8SEnji Cooper 	uint8_t pkt[1] = { 0 };
302*57718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
303*57718be8SEnji Cooper 	void *arg = (void*)(uintptr_t)2;
304*57718be8SEnji Cooper 
305*57718be8SEnji Cooper 	/* Pre-inited words. */
306*57718be8SEnji Cooper 	mem[0] = 0;
307*57718be8SEnji Cooper 	mem[3] = 3;
308*57718be8SEnji Cooper 
309*57718be8SEnji Cooper 	bpf_args_t args = {
310*57718be8SEnji Cooper 		.pkt = pkt,
311*57718be8SEnji Cooper 		.buflen = sizeof(pkt),
312*57718be8SEnji Cooper 		.wirelen = sizeof(pkt),
313*57718be8SEnji Cooper 		.arg = arg,
314*57718be8SEnji Cooper 		.mem = mem,
315*57718be8SEnji Cooper 	};
316*57718be8SEnji Cooper 
317*57718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
318*57718be8SEnji Cooper 
319*57718be8SEnji Cooper 	code = bpfjit_generate_code(&ctx, insns, insn_count);
320*57718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
321*57718be8SEnji Cooper 
322*57718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 13);
323*57718be8SEnji Cooper 
324*57718be8SEnji Cooper 	bpfjit_free_code(code);
325*57718be8SEnji Cooper }
326*57718be8SEnji Cooper 
327*57718be8SEnji Cooper ATF_TC(libbpfjit_cop_ret_preinited_mem);
ATF_TC_HEAD(libbpfjit_cop_ret_preinited_mem,tc)328*57718be8SEnji Cooper ATF_TC_HEAD(libbpfjit_cop_ret_preinited_mem, tc)
329*57718be8SEnji Cooper {
330*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function that "
331*57718be8SEnji Cooper 	    "returns a content of external pre-initialized memory word");
332*57718be8SEnji Cooper }
333*57718be8SEnji Cooper 
ATF_TC_BODY(libbpfjit_cop_ret_preinited_mem,tc)334*57718be8SEnji Cooper ATF_TC_BODY(libbpfjit_cop_ret_preinited_mem, tc)
335*57718be8SEnji Cooper {
336*57718be8SEnji Cooper 	static struct bpf_insn insns[] = {
337*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 13),
338*57718be8SEnji Cooper 		BPF_STMT(BPF_ST, 2),
339*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 137),
340*57718be8SEnji Cooper 		BPF_STMT(BPF_ST, 1),
341*57718be8SEnji Cooper 		BPF_STMT(BPF_MISC+BPF_COP, 0), // retM
342*57718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
343*57718be8SEnji Cooper 	};
344*57718be8SEnji Cooper 
345*57718be8SEnji Cooper 	bpfjit_func_t code;
346*57718be8SEnji Cooper 	uint8_t pkt[1] = { 0 };
347*57718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
348*57718be8SEnji Cooper 	void *arg = (void*)(uintptr_t)3;
349*57718be8SEnji Cooper 
350*57718be8SEnji Cooper 	/* Pre-inited words. */
351*57718be8SEnji Cooper 	mem[0] = 0;
352*57718be8SEnji Cooper 	mem[3] = 3;
353*57718be8SEnji Cooper 
354*57718be8SEnji Cooper 	bpf_args_t args = {
355*57718be8SEnji Cooper 		.pkt = pkt,
356*57718be8SEnji Cooper 		.buflen = sizeof(pkt),
357*57718be8SEnji Cooper 		.wirelen = sizeof(pkt),
358*57718be8SEnji Cooper 		.arg = arg,
359*57718be8SEnji Cooper 		.mem = mem,
360*57718be8SEnji Cooper 	};
361*57718be8SEnji Cooper 
362*57718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
363*57718be8SEnji Cooper 
364*57718be8SEnji Cooper 	code = bpfjit_generate_code(&ctx, insns, insn_count);
365*57718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
366*57718be8SEnji Cooper 
367*57718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 3);
368*57718be8SEnji Cooper 
369*57718be8SEnji Cooper 	bpfjit_free_code(code);
370*57718be8SEnji Cooper }
371*57718be8SEnji Cooper 
372*57718be8SEnji Cooper ATF_TC(libbpfjit_copx_ret_mem);
ATF_TC_HEAD(libbpfjit_copx_ret_mem,tc)373*57718be8SEnji Cooper ATF_TC_HEAD(libbpfjit_copx_ret_mem, tc)
374*57718be8SEnji Cooper {
375*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
376*57718be8SEnji Cooper 	    "that returns a content of external memory word");
377*57718be8SEnji Cooper }
378*57718be8SEnji Cooper 
ATF_TC_BODY(libbpfjit_copx_ret_mem,tc)379*57718be8SEnji Cooper ATF_TC_BODY(libbpfjit_copx_ret_mem, tc)
380*57718be8SEnji Cooper {
381*57718be8SEnji Cooper 	static struct bpf_insn insns[] = {
382*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 13),
383*57718be8SEnji Cooper 		BPF_STMT(BPF_ST, 2),
384*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 137),
385*57718be8SEnji Cooper 		BPF_STMT(BPF_ST, 1),
386*57718be8SEnji Cooper 		BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM
387*57718be8SEnji Cooper 		BPF_STMT(BPF_MISC+BPF_COPX, 0),
388*57718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
389*57718be8SEnji Cooper 	};
390*57718be8SEnji Cooper 
391*57718be8SEnji Cooper 	bpfjit_func_t code;
392*57718be8SEnji Cooper 	uint8_t pkt[1] = { 0 };
393*57718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
394*57718be8SEnji Cooper 	void *arg = (void*)(uintptr_t)2;
395*57718be8SEnji Cooper 
396*57718be8SEnji Cooper 	/* Pre-inited words. */
397*57718be8SEnji Cooper 	mem[0] = 0;
398*57718be8SEnji Cooper 	mem[3] = 3;
399*57718be8SEnji Cooper 
400*57718be8SEnji Cooper 	bpf_args_t args = {
401*57718be8SEnji Cooper 		.pkt = pkt,
402*57718be8SEnji Cooper 		.buflen = sizeof(pkt),
403*57718be8SEnji Cooper 		.wirelen = sizeof(pkt),
404*57718be8SEnji Cooper 		.arg = arg,
405*57718be8SEnji Cooper 		.mem = mem,
406*57718be8SEnji Cooper 	};
407*57718be8SEnji Cooper 
408*57718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
409*57718be8SEnji Cooper 
410*57718be8SEnji Cooper 	code = bpfjit_generate_code(&ctx, insns, insn_count);
411*57718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
412*57718be8SEnji Cooper 
413*57718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 13);
414*57718be8SEnji Cooper 
415*57718be8SEnji Cooper 	bpfjit_free_code(code);
416*57718be8SEnji Cooper }
417*57718be8SEnji Cooper 
418*57718be8SEnji Cooper ATF_TC(libbpfjit_copx_ret_preinited_mem);
ATF_TC_HEAD(libbpfjit_copx_ret_preinited_mem,tc)419*57718be8SEnji Cooper ATF_TC_HEAD(libbpfjit_copx_ret_preinited_mem, tc)
420*57718be8SEnji Cooper {
421*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function that "
422*57718be8SEnji Cooper 	    "returns a content of external pre-initialized memory word");
423*57718be8SEnji Cooper }
424*57718be8SEnji Cooper 
ATF_TC_BODY(libbpfjit_copx_ret_preinited_mem,tc)425*57718be8SEnji Cooper ATF_TC_BODY(libbpfjit_copx_ret_preinited_mem, tc)
426*57718be8SEnji Cooper {
427*57718be8SEnji Cooper 	static struct bpf_insn insns[] = {
428*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 13),
429*57718be8SEnji Cooper 		BPF_STMT(BPF_ST, 2),
430*57718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 137),
431*57718be8SEnji Cooper 		BPF_STMT(BPF_ST, 1),
432*57718be8SEnji Cooper 		BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM
433*57718be8SEnji Cooper 		BPF_STMT(BPF_MISC+BPF_COPX, 0),
434*57718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
435*57718be8SEnji Cooper 	};
436*57718be8SEnji Cooper 
437*57718be8SEnji Cooper 	bpfjit_func_t code;
438*57718be8SEnji Cooper 	uint8_t pkt[1] = { 0 };
439*57718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
440*57718be8SEnji Cooper 	void *arg = (void*)(uintptr_t)3;
441*57718be8SEnji Cooper 
442*57718be8SEnji Cooper 	/* Pre-inited words. */
443*57718be8SEnji Cooper 	mem[0] = 0;
444*57718be8SEnji Cooper 	mem[3] = 3;
445*57718be8SEnji Cooper 
446*57718be8SEnji Cooper 	bpf_args_t args = {
447*57718be8SEnji Cooper 		.pkt = pkt,
448*57718be8SEnji Cooper 		.buflen = sizeof(pkt),
449*57718be8SEnji Cooper 		.wirelen = sizeof(pkt),
450*57718be8SEnji Cooper 		.arg = arg,
451*57718be8SEnji Cooper 		.mem = mem,
452*57718be8SEnji Cooper 	};
453*57718be8SEnji Cooper 
454*57718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
455*57718be8SEnji Cooper 
456*57718be8SEnji Cooper 	code = bpfjit_generate_code(&ctx, insns, insn_count);
457*57718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
458*57718be8SEnji Cooper 
459*57718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 3);
460*57718be8SEnji Cooper 
461*57718be8SEnji Cooper 	bpfjit_free_code(code);
462*57718be8SEnji Cooper }
463*57718be8SEnji Cooper 
ATF_TP_ADD_TCS(tp)464*57718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
465*57718be8SEnji Cooper {
466*57718be8SEnji Cooper 
467*57718be8SEnji Cooper 	/*
468*57718be8SEnji Cooper 	 * For every new test please also add a similar test
469*57718be8SEnji Cooper 	 * to ../../net/bpfjit/t_extmem.c
470*57718be8SEnji Cooper 	 */
471*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, libbpfjit_extmem_load_default);
472*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, libbpfjit_extmem_load_preinited);
473*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, libbpfjit_extmem_invalid_load);
474*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, libbpfjit_extmem_store);
475*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, libbpfjit_extmem_side_effect);
476*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, libbpfjit_extmem_invalid_store);
477*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_mem);
478*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_preinited_mem);
479*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_mem);
480*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_preinited_mem);
481*57718be8SEnji Cooper 
482*57718be8SEnji Cooper 	return atf_no_error();
483*57718be8SEnji Cooper }
484