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