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